Blueprint are a core Flask feature used to organize an application into distinct components. They allow developers to group related views, templates, and static files, facilitating cleaner code and better scalability. This modular approach supports two primary patterns: functional and divisional architectures.
Challenges of Monolithic Applicasions
In a small Flask application, it is common to define all routes in a single script. While simple, this approach becomes unmanageable as the project grows. Consider an application containing both user authentication and administrative functions:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Home Page'
# Authentication endpoints
@app.route('/account/signup')
def signup():
return 'Signup'
@app.route('/account/signin')
def signin():
return 'Signin'
# Management endpoints
@app.route('/dashboard/users')
def list_users():
return 'User List'
if __name__ == '__main__':
app.run(debug=True)
As more features are added, this file becomes bloated and difficult to maintain. Blueprints resolve this by decoupling the components.
Implementing Functional Architecture
A functional architecture groups modules by their purpose while sharing global static and template directories. A typical directory structure looks like this:
project_root/
├── app.py
├── auth/
│ ├── __init__.py
│ └── routes.py
├── admin/
│ ├── __init__.py
│ └── routes.py
├── static/
└── templates/
Creating the Blueprints
In auth/routes.py, we instantiate a Blueprint object and define routes relative to that component:
from flask import Blueprint
# Initialize the blueprint
auth_bp = Blueprint('auth', __name__, url_prefix='/auth')
@auth_bp.route('/register')
def register_user():
return 'User Registration'
@auth_bp.route('/login')
def login_user():
return 'User Login'
Similarly, in admin/routes.py:
from flask import Blueprint
admin_bp = Blueprint('admin', __name__, url_prefix='/admin')
@admin_bp.route('/reports')
def view_reports():
return 'Administrative Reports'
Registering Blueprints in the Application Factory
To make these routes accessible, they must be registered with the central Flask application instance in app.py:
from flask import Flask
from auth.routes import auth_bp
from admin.routes import admin_bp
app = Flask(__name__)
# Registering modular components
app.register_blueprint(auth_bp)
app.register_blueprint(admin_bp)
@app.route('/')
def home():
return 'Welcome to the Modular App'
if __name__ == '__main__':
app.run(port=8080)
With this configuration, the registration endpoint is accessed via /auth/register and the reporting tool via /admin/reports.
Implementing Divisional Architecture
In larger projects where modules are significantly distinct, you might prefer a divisional architecture. This allows each blueprint to maintain its own unique templates and static assets. When creating the Blueprint object, you explicitly define these paths:
# Inside a module's definition
store_bp = Blueprint(
'store',
__name__,
template_folder='templates',
static_folder='static',
url_prefix='/shop'
)
The project structure to divisional architecture follows this pattern:
project_root/
├── app.py
├── auth/
│ ├── routes.py
│ ├── static/
│ └── templates/
├── shop/
│ ├── routes.py
│ ├── static/
│ └── templates/
This structure ensures that the UI and assets for the shop do not conflict with the authentication module, providing maximum isolation between application domains.