Introduction
This tutorial covers advanced Flask concepts including blueprints for modular applications, the application factory pattern for flexible configuration, and popular Flask extensions that enhance functionality.
Application Factory Pattern
The application factory pattern allows you to create multiple instances of your application with different configurations. This is essential for testing and scaling.
# app/__init__.py
from flask import Flask
def create_app(config_name='default'):
app = Flask(__name__)
if config_name == 'testing':
app.config['TESTING'] = True
app.config['DEBUG'] = False
elif config_name == 'production':
app.config['DEBUG'] = False
app.config['TESTING'] = False
# Initialize extensions
from app.extensions import db, login_manager
db.init_app(app)
login_manager.init_app(app)
# Register blueprints
from app.blueprints.main import main_bp
from app.blueprints.auth import auth_bp
app.register_blueprint(main_bp)
app.register_blueprint(auth_bp, url_prefix='/auth')
return app
Blueprints
Blueprints allow you to organize your application into modular components. Each blueprint can have its own templates, static files, and routes.
# app/blueprints/main.py
from flask import Blueprint, render_template
main_bp = Blueprint('main', __name__)
@main_bp.route('/')
def index():
return render_template('index.html')
@main_bp.route('/about')
def about():
return render_template('about.html')
# app/blueprints/auth.py
from flask import Blueprint, request, redirect, url_for
auth_bp = Blueprint('auth', __name__)
@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# Handle login
return redirect(url_for('main.index'))
return render_template('login.html')
@auth_bp.route('/logout')
def logout():
# Handle logout
return redirect(url_for('main.index'))
Flask Extensions
Flask extensions provide additional functionality. Popular extensions include Flask-SQLAlchemy, Flask-Login, Flask-Migrate, and Flask-WTF.
# app/extensions.py
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_migrate import Migrate
from flask_wtf import CSRFProtect
db = SQLAlchemy()
login_manager = LoginManager()
migrate = Migrate()
csrf = CSRFProtect()
# app/models.py
from app.extensions import db
from flask_login import UserMixin
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(150), unique=True, nullable=False)
email = db.Column(db.String(150), unique=True, nullable=False)
password_hash = db.Column(db.String(256))
def set_password(self, password):
import hashlib
self.password_hash = hashlib.sha256(password.encode()).hexdigest()
def check_password(self, password):
import hashlib
return self.password_hash == hashlib.sha256(password.encode()).hexdigest()
Practice Problems
- Create an application factory that accepts a database URI configuration parameter
- Implement a blueprint for a blog with routes for listing posts, viewing a single post, and creating a new post
- Add Flask-Login to your application with user authentication routes
- Create a custom Flask extension that logs all requests to a file
- Refactor a monolithic Flask application into multiple blueprints