Registering Blueprints and URL Prefixes
To organize your application into modules, you can use the Blueprint class to define routes and then register them on a Flask application. This allows you to group related views and apply common URL prefixes or subdomains.
Basic Blueprint Registration
To register a blueprint, create an instance of Blueprint and use the register_blueprint method of your Flask application.
from flask import Flask, Blueprint
app = Flask(__name__)
auth_bp = Blueprint("auth", __name__)
@auth_bp.route("/login")
def login():
return "Login Page"
# Register the blueprint on the app
app.register_blueprint(auth_bp)
Configuring URL Prefixes
You can define a url_prefix when creating the blueprint or when registering it. Registration-time options will override or extend the blueprint's defaults.
# Defined at creation
api_bp = Blueprint("api", __name__, url_prefix="/api/v1")
@api_bp.route("/users")
def get_users():
return "User List"
# Registering with the default prefix: /api/v1/users
app.register_blueprint(api_bp)
# Overriding the prefix at registration: /v2/users
app.register_blueprint(api_bp, url_prefix="/v2", name="api_v2")
Using Subdomains
To use subdomains with blueprints, you must first enable subdomain_matching on the application and set a SERVER_NAME.
app = Flask(__name__)
app.config["SERVER_NAME"] = "example.test"
app.subdomain_matching = True
# Define a blueprint for a specific subdomain
admin_bp = Blueprint("admin", __name__, subdomain="admin")
@admin_bp.route("/")
def admin_index():
return "Admin Panel"
app.register_blueprint(admin_bp)
# This route matches: http://admin.example.test/
Nesting Blueprints
Blueprints can be registered on other blueprints using the register_blueprint method. This creates a hierarchy where URL prefixes and subdomains are concatenated.
parent = Blueprint("parent", __name__, url_prefix="/parent")
child = Blueprint("child", __name__, url_prefix="/child")
@child.route("/")
def index():
return "Nested Index"
# Nest the child blueprint inside the parent
parent.register_blueprint(child)
# Register the parent on the app
app.register_blueprint(parent)
# The resulting URL is: /parent/child/
When nesting subdomains, the child subdomain is prepended to the parent subdomain (e.g., child.parent.example.test).
Registering the Same Blueprint Multiple Times
You can register the same Blueprint object multiple times with different configurations by providing a unique name during registration. This is useful for versioning or reusing logic under different paths.
bp = Blueprint("bp", __name__)
@bp.route("/")
def index():
return "Index"
# Register twice with different names and prefixes
app.register_blueprint(bp, url_prefix="/a", name="instance_a")
app.register_blueprint(bp, url_prefix="/b", name="instance_b")
# Endpoints will be 'instance_a.index' and 'instance_b.index'
Troubleshooting and Constraints
- No Dots in Names: Blueprint names (the
nameparameter in the constructor) cannot contain a dot (.) character. - No Self-Registration: A blueprint cannot be registered on itself. This will raise a
ValueError. - Duplicate Names: Registering two different blueprints with the same name, or the same blueprint twice without providing a unique
nameoverride, will raise aValueError. - Post-Registration Setup: You cannot call setup methods (like
@route,@errorhandler, orrecord) on a blueprint after it has been registered on an application. Doing so will raise anAssertionError. Ensure all routes and handlers are defined before callingapp.register_blueprint(). - Static Files: If a blueprint does not have a
url_prefix, the application's static route will take precedence, potentially making the blueprint's static files inaccessible. Provide aurl_prefixor a uniquestatic_url_pathto avoid this.