Flask Blueprints

A Blueprint is a way to organize a Flask application into smaller, self-contained modules. Instead of putting all routes in one app.py file, you split them into separate files — one per feature — and register them with the main app. Blueprints make large applications maintainable and testable.

The Department Analogy

Think of a large company. Every department (HR, Engineering, Sales) has its own team, resources, and processes. The company coordinates them but each department operates independently. Flask Blueprints work the same way — each blueprint is a department with its own routes, templates, and static files, all registered under the main application.

Main App (company HQ)
├── auth blueprint    (login, register, logout)
├── blog blueprint    (posts, comments, categories)
├── admin blueprint   (user management, dashboard)
└── api blueprint     (REST API endpoints)

Creating a Blueprint

Create a file auth/routes.py:

from flask import Blueprint, render_template, redirect, url_for, request

auth = Blueprint('auth', __name__, template_folder='templates')

@auth.route('/login', methods=['GET', 'POST'])
def login():
    return render_template('auth/login.html')

@auth.route('/register', methods=['GET', 'POST'])
def register():
    return render_template('auth/register.html')

@auth.route('/logout')
def logout():
    return redirect(url_for('auth.login'))

Blueprint('auth', __name__) creates a blueprint named 'auth'. The name becomes the prefix for endpoint lookups: url_for('auth.login') instead of url_for('login').

Registering the Blueprint

In your main app.py:

from flask import Flask
from auth.routes import auth

app = Flask(__name__)
app.register_blueprint(auth, url_prefix='/auth')

Now all routes in the auth blueprint are accessible at:

/auth/login
/auth/register
/auth/logout

Blueprint Folder Structure

myapp/
├── app.py
├── auth/
│   ├── __init__.py      (empty or imports)
│   ├── routes.py
│   └── templates/
│       └── auth/
│           ├── login.html
│           └── register.html
├── blog/
│   ├── __init__.py
│   ├── routes.py
│   └── templates/
│       └── blog/
│           ├── index.html
│           └── post.html
└── templates/
    └── base.html         (shared base template)

Put blueprint-specific templates inside a subfolder named after the blueprint inside that blueprint's templates/ folder. This prevents name collisions when two blueprints have a template named index.html.

Using url_for with Blueprints

Reference blueprint routes using the format 'blueprint_name.function_name':

{# In any template #}
<a href="{{ url_for('auth.login') }}">Log In</a>
<a href="{{ url_for('blog.index') }}">Blog</a>
<a href="{{ url_for('auth.register') }}">Register</a>

Blueprint-Specific Static Files

auth = Blueprint('auth', __name__,
                 template_folder='templates',
                 static_folder='static')

Files in auth/static/ are served at /auth/static/ and referenced with:

{{ url_for('auth.static', filename='css/auth.css') }}

Multiple Blueprints Registered at Once

from auth.routes   import auth
from blog.routes   import blog
from api.routes    import api_bp
from admin.routes  import admin

def create_app():
    app = Flask(__name__)

    app.register_blueprint(auth,   url_prefix='/auth')
    app.register_blueprint(blog,   url_prefix='/blog')
    app.register_blueprint(api_bp, url_prefix='/api/v1')
    app.register_blueprint(admin,  url_prefix='/admin')

    return app

Before-Request Hooks on a Blueprint

A blueprint can define its own before-request hook that runs only for its own routes:

@admin.before_request
def check_admin():
    if not current_user.is_admin:
        abort(403)

This check runs before every admin blueprint route without adding it to each function individually.

Summary

Blueprints split a large Flask app into feature modules. Create a Blueprint object in each feature's module, define routes on it, and register it with the main app. Use url_prefix to group all blueprint URLs under a common path. Reference blueprint endpoints using 'blueprint_name.function_name' in url_for(). Blueprints make code reusable, independently testable, and easy to understand as a project grows.

Leave a Comment

Your email address will not be published. Required fields are marked *