Flask Blueprints

Deep dive · part of Python Flask

Blueprints split a Flask app into reusable modules - typically one per feature (auth, blog, api). Each blueprint has its own routes, templates and static folder, and is registered on the main app at startup.

Blueprints modularize Flask apps: group routes, templates, and static files per feature (blog, api, admin) then register_blueprint on the application factory. url_prefix mounts entire modules under a path without repeating /blog in every decorator.

Application factory pattern (create_app) enables testing with fresh app instances and configuration objects per environment.

Blueprints also carry their own static and template folders, so feature teams ship self-contained packages installable across multiple Flask apps.

Blueprints also carry their own static and template folders, so feature teams ship self-contained packages installable across multiple Flask apps.

Production code combines this topic with logging, tests, and clear module boundaries so refactors stay safe when requirements grow.

Blueprint('name', __name__, url_prefix='/blog') namespaced routes.

register_blueprint(bp) wires routes at startup.

Template folders relative to blueprint package for colocation.

before_request on blueprint scopes hooks to that subtree only.

errorhandler on blueprint handles domain-specific HTTP errors.

Same blueprint can register twice with different url_prefix in rare mounts.

Large apps split blueprints into packages with __init__ exporting bp. CLI commands register via app.cli or blueprint.cli in Flask 2+.

Testing: app.test_client().get('/blog/') hits blueprint routes without running server.

Integration tests should import create_app() once per session; register blueprints in factory order documented for middleware that depends on route precedence.

Document blueprint registration order when before_request hooks depend on overlapping url_prefix paths.

Read the parent tutorial on pythondeck.com for runnable snippets, then reproduce them locally in a virtual environment with pinned dependency versions matching your deployment target.

When pairing with teammates, agree on one idiomatic pattern per concern—mixed styles in one repo slow reviews and invite subtle integration bugs during merges.

Circular imports between blueprints and models—use late imports or extensions pattern.

Duplicate endpoint names across blueprints causing routing conflicts.

Forgetting url_prefix leading slash consistency.

Monolithic create_app registering dozens of blueprints without lazy loading docs.

One blueprint per bounded context (auth, catalog, webhooks).

Use application factory in tests with TESTING config.

Name blueprints after URL prefix for grep-friendly navigation.

Document registered blueprints in README for new contributors.

Re-read the examples below with these ideas in mind; change variable names and inputs to match your own project.

The program below demonstrates blueprint module. Read the comments on each line, run the code, then change names or values to see how the output shifts.

# blog.py
from flask import Blueprint, jsonify
blog = Blueprint("blog", __name__, url_prefix="/blog")

@blog.get("/")
def index():
    return jsonify(posts=["hello", "world"])

@blog.get("/<slug>")
def post(slug):
    return jsonify(slug=slug)

This sample walks through app factory in a small, runnable script. Paste it into the REPL or save it as a .py file before you continue to the next block.

# app.py
from flask import Flask
from blog import blog

def create_app():
    app = Flask(__name__)
    app.register_blueprint(blog)
    return app

if __name__ == "__main__":
    create_app().run(debug=True)

Here is a hands-on illustration of blueprint routes. Follow the inline comments first; only then execute the snippet and compare the result with what you expected.

# Blueprint groups related endpoints under a URL prefix
from flask import Blueprint, jsonify  # flask
api = Blueprint("api", __name__, url_prefix="/api")  # prefix /api

@api.get("/ping")  # route /api/ping
def ping():  # view
    return jsonify(pong=True)  # JSON

@api.get("/items/<int:item_id>")  # typed path param
def item(item_id):  # view
    return jsonify(id=item_id)  # echo id

print(api.name, api.url_prefix)  # api /api

The program below demonstrates register blueprint. Read the comments on each line, run the code, then change names or values to see how the output shifts.

# App factory registers blueprints on the Flask app
from flask import Flask  # Flask
from flask import Blueprint, jsonify  # reuse
pages = Blueprint("pages", __name__)  # pages blueprint

@pages.get("/")  # root
def home(): return jsonify(home=True)  # payload

def create_app():  # factory
    app = Flask(__name__)  # app
    app.register_blueprint(pages)  # attach
    return app  # return configured app

app = create_app()  # instance
print(app.url_map)  # registered rules

« back to Python Flask All tutorials