Documentation Index Fetch the complete documentation index at: https://mintlify.com/pallets/flask/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Blueprints are Flask’s way of organizing applications into modular components. They allow you to structure large applications into smaller, reusable pieces.
What are Blueprints?
A blueprint is a template for generating a “section” of a web application. You can think of it as a mini-application that can be registered on the main Flask app.
Why Use Blueprints?
Modularity : Organize code by feature or functionality
Reusability : Share blueprints across projects
Scalability : Large apps become manageable
Team Development : Different teams work on different blueprints
Namespace : Avoid naming conflicts with prefixes
Creating a Blueprint
From blueprints.py:18-54:
from flask import Blueprint
# Create a blueprint
admin = Blueprint(
'admin' , # Blueprint name
__name__ , # Import name
url_prefix = '/admin' ,
template_folder = 'templates' ,
static_folder = 'static'
)
@admin.route ( '/' )
def index ():
return 'Admin Dashboard'
@admin.route ( '/users' )
def users ():
return 'User Management'
Registering Blueprints
Register blueprints with the Flask application:
from flask import Flask
from myapp.admin import admin
from myapp.api import api
app = Flask( __name__ )
# Register blueprints
app.register_blueprint(admin)
app.register_blueprint(api, url_prefix = '/api' )
if __name__ == '__main__' :
app.run()
Blueprint Parameters
Basic Parameters
blueprint = Blueprint(
name = 'admin' , # Blueprint name (required)
import_name = __name__ , # Module import name (required)
static_folder = 'static' , # Static files folder
static_url_path = '/static' , # URL path for static files
template_folder = 'templates' , # Templates folder
url_prefix = '/admin' , # URL prefix for all routes
subdomain = 'admin' , # Subdomain for blueprint
url_defaults = { 'lang' : 'en' }, # Default URL values
root_path = None , # Root path override
)
URL Prefix
Add a prefix to all blueprint routes:
api = Blueprint( 'api' , __name__ , url_prefix = '/api/v1' )
@api.route ( '/users' ) # Accessible at /api/v1/users
def list_users ():
return jsonify(users)
# Override at registration
app.register_blueprint(api, url_prefix = '/api/v2' )
Subdomain
Mount blueprint on a subdomain:
app.config[ 'SERVER_NAME' ] = 'example.com'
admin = Blueprint( 'admin' , __name__ , subdomain = 'admin' )
@admin.route ( '/' ) # Accessible at admin.example.com/
def admin_home ():
return 'Admin Home'
app.register_blueprint(admin)
Blueprint Structure
Recommended Directory Layout
myapp/
├── __init__.py # Application factory
├── models.py # Database models
├── admin/
│ ├── __init__.py # Blueprint creation
│ ├── views.py # Route handlers
│ ├── forms.py # WTForms
│ ├── templates/
│ │ └── admin/
│ │ ├── index.html
│ │ └── users.html
│ └── static/
│ └── admin.css
├── api/
│ ├── __init__.py
│ ├── users.py
│ └── products.py
└── main/
├── __init__.py
├── views.py
└── templates/
└── main/
└── index.html
Example Blueprint Module
myapp/admin/__init__.py:
from flask import Blueprint
admin = Blueprint(
'admin' ,
__name__ ,
template_folder = 'templates' ,
static_folder = 'static' ,
url_prefix = '/admin'
)
from . import views
myapp/admin/views.py:
from flask import render_template, redirect, url_for
from . import admin
@admin.route ( '/' )
def index ():
return render_template( 'admin/index.html' )
@admin.route ( '/users' )
def users ():
users = get_all_users()
return render_template( 'admin/users.html' , users = users)
Blueprint Routes
Defining Routes
Blueprints use the same routing decorators as the main app:
from flask import Blueprint, request, jsonify
api = Blueprint( 'api' , __name__ )
@api.route ( '/users' , methods = [ 'GET' , 'POST' ])
def users ():
if request.method == 'POST' :
return create_user()
return list_users()
@api.get ( '/users/<int:id>' )
def get_user ( id ):
return jsonify(user)
@api.post ( '/users' )
def create_user ():
return jsonify(user), 201
@api.delete ( '/users/<int:id>' )
def delete_user ( id ):
return '' , 204
Endpoint Names
Blueprint routes get prefixed endpoint names:
admin = Blueprint( 'admin' , __name__ )
@admin.route ( '/' )
def index (): # Endpoint: 'admin.index'
return 'Admin Home'
# Use in url_for()
url_for( 'admin.index' ) # /admin/
url_for( 'admin.users' ) # /admin/users
Blueprint Resources
Templates
From templating.py:98-107, blueprints can have their own templates:
admin = Blueprint( 'admin' , __name__ , template_folder = 'templates' )
@admin.route ( '/' )
def index ():
# Looks in blueprint's templates folder first, then app's
return render_template( 'admin/index.html' )
Template search order:
Blueprint’s templates folder
Application’s templates folder
Static Files
From blueprints.py:82-102, serve static files from blueprints:
admin = Blueprint(
'admin' ,
__name__ ,
static_folder = 'static' ,
static_url_path = '/admin/static'
)
# In templates
{{ url_for( 'admin.static' , filename = 'admin.css' ) }}
# Generates: /admin/static/admin.css
Resource Files
From blueprints.py:104-129, open blueprint resources:
@admin.route ( '/init' )
def init_database ():
with admin.open_resource( 'schema.sql' ) as f:
db.executescript(f.read())
return 'Database initialized'
Blueprint Hooks
Before Request
@admin.before_request
def check_admin ():
if not current_user.is_admin:
abort( 403 )
@admin.before_app_request # Runs for ALL requests
def log_request ():
app.logger.info( f ' { request.method } { request.path } ' )
After Request
@admin.after_request
def add_header ( response ):
response.headers[ 'X-Admin' ] = 'true'
return response
@admin.after_app_request # Runs for ALL requests
def add_security_headers ( response ):
response.headers[ 'X-Content-Type-Options' ] = 'nosniff'
return response
Teardown
@admin.teardown_request
def cleanup ( exception = None ):
# Clean up blueprint resources
pass
@admin.teardown_app_request # Runs for ALL requests
def global_cleanup ( exception = None ):
db.session.remove()
Error Handlers
@admin.errorhandler ( 404 )
def admin_not_found ( error ):
return render_template( 'admin/404.html' ), 404
@admin.app_errorhandler ( 500 ) # Handles ALL 500 errors
def server_error ( error ):
return render_template( 'errors/500.html' ), 500
Context Processors
Add variables to blueprint templates:
@admin.context_processor
def inject_admin_context ():
return dict ( admin_version = '1.0' )
@admin.app_context_processor # For ALL templates
def inject_global ():
return dict ( site_name = 'My Site' )
Nested Blueprints
Blueprints can be nested (Flask 2.0+):
parent = Blueprint( 'parent' , __name__ , url_prefix = '/parent' )
child = Blueprint( 'child' , __name__ , url_prefix = '/child' )
@child.route ( '/' )
def index ():
return 'Child Index'
# Register child on parent
parent.register_blueprint(child)
# Register parent on app
app.register_blueprint(parent)
# Routes to: /parent/child/
Blueprint Factories
Create configurable blueprints:
def create_api_blueprint ( version = 'v1' ):
api = Blueprint(
f 'api_ { version } ' ,
__name__ ,
url_prefix = f '/api/ { version } '
)
@api.route ( '/users' )
def users ():
return jsonify(users)
return api
# Register multiple versions
app.register_blueprint(create_api_blueprint( 'v1' ))
app.register_blueprint(create_api_blueprint( 'v2' ))
URL Generation
Within Blueprint
@admin.route ( '/' )
def index ():
# Relative to current blueprint
url_for( '.users' ) # Same as url_for('admin.users')
# Absolute
url_for( 'admin.users' )
# Other blueprint
url_for( 'api.users' )
# Main app
url_for( 'index' )
From Templates
{# Current blueprint #}
<a href=" {{ url_for ( '.users' ) }} ">Users</a>
{# Specific blueprint #}
<a href=" {{ url_for ( 'admin.users' ) }} ">Admin Users</a>
{# Static files #}
<link rel="stylesheet" href=" {{ url_for ( '.static' , filename = 'style.css' ) }} ">
CLI Commands
Add CLI commands to blueprints:
import click
from flask import Blueprint
admin = Blueprint( 'admin' , __name__ )
@admin.cli.command ( 'init-db' )
def init_db ():
"""Initialize the admin database."""
click.echo( 'Initializing admin database...' )
# Initialization code
# Usage: flask admin init-db
Application Factory Pattern
Combine blueprints with application factories:
def create_app ( config_name = 'default' ):
app = Flask( __name__ )
app.config.from_object(config[config_name])
# Initialize extensions
db.init_app(app)
login_manager.init_app(app)
# Register blueprints
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
from .admin import admin as admin_blueprint
app.register_blueprint(admin_blueprint, url_prefix = '/admin' )
from .api import api as api_blueprint
app.register_blueprint(api_blueprint, url_prefix = '/api/v1' )
return app
Best Practices
Organize by Feature Group related functionality together, not by type
Clear Naming Use descriptive blueprint names that reflect their purpose
Avoid Circular Imports Import views at the end of init .py
Use Factories Combine with application factory pattern for flexibility
Common Patterns
API Blueprint
api = Blueprint( 'api' , __name__ , url_prefix = '/api/v1' )
@api.before_request
def verify_token ():
token = request.headers.get( 'Authorization' )
if not verify_api_token(token):
abort( 401 )
@api.after_request
def add_cors_headers ( response ):
response.headers[ 'Access-Control-Allow-Origin' ] = '*'
return response
Auth Blueprint
auth = Blueprint( 'auth' , __name__ )
@auth.route ( '/login' , methods = [ 'GET' , 'POST' ])
def login ():
if request.method == 'POST' :
# Process login
return redirect(url_for( 'main.index' ))
return render_template( 'auth/login.html' )
@auth.route ( '/logout' )
def logout ():
# Clear session
return redirect(url_for( 'main.index' ))