Getting Started with Blueprints
Blueprints allow you to organize your application into distinct components. Instead of defining all routes and logic on a single application object, you can group related functionality into a Blueprint and register it with the application later.
In this tutorial, you will build a modular authentication system by creating an "auth" blueprint and integrating it into a Flask application.
Prerequisites
To follow this guide, you should have a basic Flask application structure. This tutorial assumes you are using an application factory pattern, as seen in the examples/tutorial/flaskr/ directory.
Step 1: Create the Blueprint
First, create a new module for your authentication logic. In this file, you will instantiate the Blueprint class.
In flaskr/auth.py:
from flask import Blueprint
bp = Blueprint("auth", __name__, url_prefix="/auth")
@bp.route("/login", methods=("GET", "POST"))
def login():
# This view will be accessible at /auth/login
return "Login Page"
@bp.route("/logout")
def logout():
# This view will be accessible at /auth/logout
return "Logout Page"
When you create a Blueprint, you provide:
- name: The first argument (
"auth") is the name of the blueprint. This is prepended to all endpoint names (e.g.,auth.login). - import_name: Usually
__name__, which helps the blueprint locate resources like templates. - url_prefix: An optional path (like
"/auth") that will be prepended to all routes defined in this blueprint.
Step 2: Register the Blueprint
A blueprint does nothing until it is registered on a Flask application instance. You do this using the register_blueprint method.
In flaskr/__init__.py:
from flask import Flask
def create_app():
app = Flask(__name__)
# Import the blueprint object
from . import auth
# Register it with the app
app.register_blueprint(auth.bp)
return app
Once registered, the routes defined in auth.py become part of the application. Because we set url_prefix="/auth", the login function is now mapped to the URL /auth/login.
Step 3: Link to Blueprint Routes
When using url_for to generate URLs for blueprint routes, you must use the blueprint's name as a prefix.
from flask import url_for
# Generates "/auth/login"
login_url = url_for("auth.login")
If you are inside a view function of the same blueprint, you can use a shortcut by prefixing the endpoint with a dot:
# Inside a view in auth.py, this also generates "/auth/login"
login_url = url_for(".login")
Step 4: Use Application-Wide Hooks
Blueprints can also define functions that run globally for every request, not just those handled by the blueprint itself. The @bp.before_app_request decorator is commonly used for tasks like loading the current user.
In flaskr/auth.py:
@bp.before_app_request
def load_logged_in_user():
# This runs before EVERY request to the application,
# regardless of which blueprint handles the route.
print("Checking user session...")
In contrast, using @bp.before_request would only execute the function for routes defined within the auth blueprint.
Important Considerations
- Naming Restrictions: The blueprint
namecannot contain a dot (.). Dots are reserved as separators for nested blueprints and endpoints. - Registration Order: You must define all routes and handlers on the blueprint before calling
app.register_blueprint(). TheBlueprintclass tracks these operations and "plays them back" during registration; changes made after registration will not be applied. - No Self-Registration: A blueprint cannot be registered on itself. However, you can nest blueprints by calling
bp.register_blueprint(other_bp)to create hierarchical URL structures.
Complete Result
You now have a modular structure where authentication logic is isolated in auth.py. Your application factory in __init__.py remains clean, simply registering the blueprint to activate its routes and hooks.
Next, you might consider creating a blog blueprint to handle your application's main content, following the same pattern of definition and registration.