В этой короткой статье мы рассмотрим способы запуска функций до и после запроса во Flask, используя декораторы before_request
и after_request
и не только.
Мы начнем с очень простого приложения Flask:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
print("index is running!")
return "Hello world"
if __name__ == "__main__":
app.run()
before_request
Декоратор before_request
позволит нам создать функцию, которая будет выполняться перед каждым запросом.
@app.before_request
def before_request_func():
print("before_request is running!")
Добавив эту функцию в наше приложение и сделав запрос к главной странице сайта/
, мы получим в терминале следующий вывод:
before_request is running!
index is running!
before_request
идеально подходят для таких задач, как:
- Открытие соединений с базой данных
- Загрузка пользователя из сессии
- Работа с глобальным
flask.g
объектом
Функция обернутая с помощью @app.before_request
, не обязана что-либо возвращать. Если она не возвращает None
значение, она будет обработана как функция представления, и любая дальнейшая обработка запросов будет остановлена.
Например:
@app.before_request
def before_request_func():
print("before_request is running!")
return "Hello Ramziv.com"
Если вы сделаете какой либо запрос по любому маршруту в своем приложении, вы увидите Hello Ramziv.com
, а не Hello world
как в нашем примере.
before_first_request
Функции обернутая с помощью @app.before_first_request
будут запускаться один раз перед первым запросом к этому экземпляру приложения.
@app.before_first_request
def before_first_request_func():
print("This function will run once")
Запустив приложение и сделав пару запросов, мы видим следующий вывод:
This function will run once
index is running!
127.0.0.1 - - [06/Jan/2023 18:24:36] "GET / HTTP/1.1" 200 -
index is running!
127.0.0.1 - - [06/Jan/2023 18:24:39] "GET / HTTP/1.1" 200 -
Как вы заметили, функция before_first_request_func
запускалась только один раз перед самым первым запросом к приложению и игнорируется при последующих запросах.
after_request
Функция обернутая с помощью декоратора after_request
работают так же, как и before_request
, за исключением того, что она запустится после каждого запроса.
Важно отметить, что любые функции after_request
должны принимать и возвращать объект ответа.
Вот простой пример:
@app.after_request
def after_request_func(response):
print("after_request is running!")
return response
Запустив наше приложение и сделав запрос к нашему маршруту /
, мы увидим:
before_request is running!
index is running!
after_request is running!
Можете подумать, это отличное место, чтобы сделать что-то вроде закрытие соединение с базой данных. Однако следует отметить, что любые функции обернутые с помощью after_request
, НЕ будут работать если ваше приложение вызовет исключение. К счастью, мы можем обойти это с помощью teardown_request
.
teardown_request
Функции обернутая с помощью teardown_request
ведет себя аналогично after_request
функции, однако у нее есть дополнительное преимущество заключающееся в том, что они запускаются независимо от каких-либо исключений.
Это делает функцию с teardown_request
отличным местом для выполнения любых операций по очистке после запросов, поскольку мы знаем, что эти функции отработают всегда.
@app.teardown_request
def teardown_request_func(error=None):
print("teardown_request is running!")
if error:
print(error)
Все вместе
Собрав все вместе, наше приложение выглядит так:
from flask import Flask
app = Flask(__name__)
@app.before_first_request
def before_first_request_func():
print("This function will run once")
@app.before_request
def before_request_func():
print("before_request is running!")
@app.route("/")
def index():
print("index is running!")
return "Hello world"
@app.after_request
def after_request_func(response):
print("after_request is running!")
return response
@app.teardown_request
def teardown_request_func(error=None):
print("teardown_request is running!")
if error:
print(error)
if __name__ == "__main__":
app.run()
Результат
This function will run once
before_request is running!
index is running!
after_request is running!
teardown_request is running!
Заключение
Я привел здесь только несколько примеров, другие полезные функции для работы с запросами как before_request
и after_request
вы можете найдете в документации Flask.