Flask API сигналов
Flask использует библиотеку Blinker для отправки сигналов при возникновении ключевых событий. Вы можете подключаться к этим сигналам, чтобы выполнять дополнительное логирование, мониторинг и другие операции.
Сигналы не являются основной функцией Flask — большинство потребностей можно удовлетворить с помощью хуков (таких как before_request).
Основные сигналы запроса
| signal | Момент срабатывания | Передаваемые параметры |
|---|---|---|
| request_started | После установления контекста запроса, перед предварительной обработкой | sender=app |
| request_finished | После полного формирования ответа, перед отправкой | sender=app, response |
| got_request_exception | Во время запроса возникает необработанное исключение | sender=app, exception |
| request_tearing_down | При уничтожении контекста запроса (выполняется всегда) | sender=app, exc (необязательно) |
Сигналы контекста приложения
| signal | Момент срабатывания | Передаваемые параметры |
|---|---|---|
| appcontext_pushed | Когда контекст приложения помещается в стек | sender=app |
| appcontext_popped | Когда контекст приложения извлекается из стека | sender=app |
| appcontext_tearing_down | Когда контекст приложения уничтожается (выполняется всегда) | sender=app, exc (необязательно) |
Сигналы шаблонов и сообщений
| signal | Момент срабатывания | Передаваемые параметры |
|---|---|---|
| template_rendered | Когда рендеринг шаблона завершается успешно | sender=app, template, context |
| before_render_template | Перед рендерингом шаблона | sender=app, template, context |
| message_flashed | При вызове flash() | sender=app, message, category |
Способы подключения сигналов
| Метод | Описание |
|---|---|
| signal.connect(func, app) | Подключайте сигналы напрямую. func получает sender и именованные аргументы. |
| signal.connect_via(app)(func) | Декораторная форма. Автоматически использует app в качестве sender. |
| with signal.connected_to(func, app): | Контекстный менеджер. Временное подключение сигнала |
Примеры кода
Пример
from flask import Flask, request_started, request_finished, template_rendered
app = Flask(__name__)
# Способ 1: Прямое подключение
def log_request_start(sender, **extra):
print(f"Запрос начат на {sender.name}")
request_started.connect(log_request_start, app)
# Способ 2: Декораторное подключение
@request_finished.connect_via(app)
def log_request_end(sender, response, **extra):
print(f"Запрос завершён со статусом {response.status_code}")
# Метод 3: Сигнал рендеринга шаблона
@template_rendered.connect_via(app)
def log_template(sender, template, context, **extra):
print(f"Шаблон отрендерен: {template.name}")
# Метод 4: Перехват исключений
from flask import got_request_exception
def log_error(sender, exception, **extra):
sender.logger.error(f"Исключение: {exception}")
got_request_exception.connect(log_error, app)
app = Flask(__name__)
# Способ 1: Прямое подключение
def log_request_start(sender, **extra):
print(f"Запрос начат на {sender.name}")
request_started.connect(log_request_start, app)
# Способ 2: Декораторное подключение
@request_finished.connect_via(app)
def log_request_end(sender, response, **extra):
print(f"Запрос завершён со статусом {response.status_code}")
# Метод 3: Сигнал рендеринга шаблона
@template_rendered.connect_via(app)
def log_template(sender, template, context, **extra):
print(f"Шаблон отрендерен: {template.name}")
# Метод 4: Перехват исключений
from flask import got_request_exception
def log_error(sender, exception, **extra):
sender.logger.error(f"Исключение: {exception}")
got_request_exception.connect(log_error, app)