Короткий ответ
Общую проверку выносят в переиспользуемую функцию/декоратор и подключают её через before_request конкретного Blueprint (bp.before_request) или через общий механизм на уровне приложения с проверкой request.blueprint, избегая копирования одинаковой проверки в каждый модуль.
Как это работает подробнее
У каждого Blueprint есть собственные хуки before_request/after_request, которые срабатывают только для маршрутов этого Blueprint, в отличие от app.before_request, который срабатывает для всех запросов. Это позволяет применить, например, проверку авторизации только к admin-Blueprint, не трогая публичные маршруты.
Пример кода
example.py
from flask import Blueprint, g, abort
admin_bp = Blueprint("admin", __name__, url_prefix="/admin")
@admin_bp.before_request
def check_admin_rights():
if not getattr(g, "current_user", None) or not g.current_user.get("is_admin"):
abort(403)
@admin_bp.route("/stats")
def stats():
return {"visits": 1000}
# Запрос к /admin/stats без g.current_user.is_admin -> 403,
# запрос к публичному Blueprint эта проверка не затрагивает.Что использовать на практике
- Практика. Для действительно общей логики (например, добавление request_id для логирования) используют
app.before_request; для логики, специфичной для группы маршрутов (авторизация только для/admin/*), —bp.before_requestконкретного Blueprint. Декораторы на отдельные view оставляют для точечных исключений внутри Blueprint.
Подводные камни
- Риск. Копируют одинаковый код проверки прав в каждую view-функцию вместо использования
before_requestBlueprint; путаютapp.before_request(для всех маршрутов) иbp.before_request(только для маршрутов конкретного Blueprint), получая неожиданно широкое или узкое применение проверки.