Flask Blueprints let you break down your application into smaller, self-contained modules.

Let’s see this in action. Imagine a simple Flask app with two distinct features: user authentication and a dashboard.

# app.py
from flask import Flask
from auth import auth_bp
from dashboard import dashboard_bp

app = Flask(__name__)

app.register_blueprint(auth_bp, url_prefix='/auth')
app.register_blueprint(dashboard_bp, url_prefix='/dashboard')

if __name__ == '__main__':
    app.run(debug=True)

Now, let’s define those blueprints in separate files.

# auth.py
from flask import Blueprint, render_template_string

auth_bp = Blueprint('auth', __name__)

@auth_bp.route('/login')
def login():
    return render_template_string("<h1>Login Page</h1>")

@auth_bp.route('/register')
def register():
    return render_template_string("<h1>Register Page</h1>")
# dashboard.py
from flask import Blueprint, render_template_string

dashboard_bp = Blueprint('dashboard', __name__)

@dashboard_bp.route('/')
def index():
    return render_template_string("<h1>Dashboard Home</h1>")

@dashboard_bp.route('/settings')
def settings():
    return render_template_string("<h1>Dashboard Settings</h1>")

When you run app.py and navigate to http://127.0.0.1:5000/auth/login, you see "Login Page". Visiting http://127.0.0.1:5000/dashboard/ shows "Dashboard Home". Each blueprint handles its own routes and logic, keeping app.py clean.

Blueprints are essentially mini-Flask applications that can be registered with your main application. They allow you to group related routes, templates, static files, and other components under a common prefix. This modularity is crucial for managing complexity as your application grows. Instead of a single, monolithic app.py file with hundreds of routes, you can have distinct blueprints for different functional areas, like users, products, orders, or admin.

The __name__ argument passed to Blueprint() is important. It tells Flask where to look for resources like templates and static files relative to the blueprint’s module. This allows each blueprint to have its own isolated directory structure if needed, promoting better organization.

The url_prefix argument during register_blueprint is what namespaces your routes. Without it, the /login route from auth.py would conflict with a potential /login route in another blueprint. By specifying /auth and /dashboard, you ensure that all routes within the auth blueprint are accessible under /auth/* and similarly for the dashboard blueprint.

You can also pass options to register_blueprint. For instance, static_folder and static_url_path can define where a blueprint’s static files live and how they are accessed. template_folder lets you specify a custom directory for templates used only by that blueprint.

Consider a blueprint that needs to access the main application’s configuration or extensions. You can access the application object from within a blueprint’s views using current_app. For example, to get a configuration value:

# some_blueprint.py
from flask import Blueprint, current_app

my_bp = Blueprint('my_bp', __name__)

@my_bp.route('/config_check')
def config_check():
    api_key = current_app.config.get('API_KEY')
    return f"API Key: {api_key}"

In app.py, you’d set this config:

# app.py
from flask import Flask
from auth import auth_bp
from dashboard import dashboard_bp
from some_blueprint import my_bp # assuming you added this

app = Flask(__name__)
app.config['API_KEY'] = 'supersecret123' # Set the config

app.register_blueprint(auth_bp, url_prefix='/auth')
app.register_blueprint(dashboard_bp, url_prefix='/dashboard')
app.register_blueprint(my_bp, url_prefix='/my') # Register the new blueprint

if __name__ == '__main__':
    app.run(debug=True)

Navigating to /my/config_check would then display "API Key: supersecret123". This shows how blueprints can interact with the main application’s context.

A powerful, yet often overlooked, aspect of blueprints is their ability to be unregistered. While not common for core features, this can be useful for dynamic loading or conditional functionality. You can remove a blueprint from an application instance using app.blueprints.pop('blueprint_name').

The next step in organizing large Flask apps involves understanding how to manage shared resources and dependencies between blueprints effectively.

Want structured learning?

Take the full Flask course →