Структура и жизненный цикл приложения
Flask делает создание веб-приложений довольно простым. Однако существует немало различных частей приложения и каждого обрабатываемого запроса. Знание того, что происходит во время настройки приложения, обработки запросов и обслуживания поможет вам понять, что возможно в Flask, и как структурировать ваше приложение.
Настройка приложения
Первый шаг в создании приложения Flask — создание объекта приложения. Каждое приложение Flask — это экземпляр класса Flask, который собирает всю конфигурацию, расширения и представления.
from flask import Flask
app = Flask(__name__)
app.config.from_mapping(
SECRET_KEY="dev",
)
app.config.from_prefixed_env()
@app.route("/")
def index():
return "Hello, World!"
Это известно как «фаза настройки приложения»; это код, который вы пишете вне функций представлений или других обработчиков. Он может быть разделен между различными модулями и подпакетами, но весь код, который вы хотите включить в свое приложение, должен быть импортирован для регистрации.
Вся настройка приложения должна быть завершена перед запуском приложения и обработкой запросов. Это связано с тем, что серверы WSGI распределяют работу между несколькими рабочими процессами или могут быть распределены по нескольким машинам. Если конфигурация изменится в одном рабочем процессе, Flask не сможет гарантировать согласованность между другими рабочими процессами.
Flask пытается помочь разработчикам обнаруживать некоторые из этих проблем с порядком настройки, показывая ошибку, если методы, связанные с настройкой, вызываются после обработки запросов. В этом случае вы увидите следующую ошибку:
Метод настройки «route» больше не может быть вызван для приложения. Оно уже обработало свой первый запрос, любые изменения не будут применены согласованно. Убедитесь, что все импорты, декораторы, функции и т. д., необходимые для настройки приложения, выполнены до его запуска.
Однако Flask не может обнаружить все случаи несоответствующей настройки. В общем, не делайте ничего, чтобы изменить объект приложения Flask и объекты Blueprint из функций представлений, которые выполняются во время запросов. Это включает:
- Добавление маршрутов, функций представлений и других обработчиков запросов с помощью
@app.route,@app.errorhandler,@app.before_request, и т. д. - Регистрация планов.
- Загрузка конфигурации с помощью
app.config. - Настройка среды шаблонов Jinja с помощью
app.jinja_env. - Установка интерфейса сессий вместо стандартных cookie itsdangerous.
- Установка поставщика JSON с помощью
app.json, вместо стандартного поставщика. - Создание и инициализация расширений Flask.
Обслуживание приложения
Flask — это фреймворк приложений WSGI. Другая половина WSGI — это сервер WSGI. Во время разработки Flask через Werkzeug предоставляет сервер WSGI разработки с помощью команды flask run CLI. Когда вы закончите с разработкой, используйте сервер производства для обслуживания вашего приложения, см. Развертывание в производство.
Независимо от используемого сервера, он будет следовать спецификации WSGI PEP 3333. Сервер WSGI получит информацию о том, как получить доступ к вашему объекту приложения Flask, который является приложением WSGI. Затем он начнет прослушивать HTTP-запросы, преобразовывать данные запроса в WSGI environ и вызывать приложение WSGI с этими данными. Приложение WSGI вернет данные, которые будут преобразованы в HTTP-ответ.
- Браузер или другой клиент отправляет HTTP-запрос.
- Сервер WSGI получает запрос.
- Сервер WSGI преобразует данные HTTP в словарь WSGI
environ. - Сервер WSGI вызывает приложение WSGI с данным
environ. - Flask, приложение WSGI, выполняет всю свою внутреннюю обработку для маршрутизации запроса к функции представления, обработки ошибок и т. д.
- Flask преобразует возвращаемое значение функции представления в данные WSGI-ответа и передает их серверу WSGI.
- Сервер WSGI создает и отправляет HTTP-ответ.
- Клиент получает HTTP-ответ.
Средства промежуточного уровня
Приложение WSGI выше — это вызываемый объект, который ведет себя определенным образом. Средства промежуточного уровня — это приложение WSGI, которое оборачивает другое приложение WSGI. Это похожая концепция с Python-декораторами. Наружный уровень средств промежуточного уровня вызывается сервером. Он может изменять передаваемые ему данные, затем вызывать приложение WSGI (или другие средства промежуточного уровня), которое он оборачивает, и так далее. И он может принять возвращаемое значение этого вызова и дополнительно изменить его.
С точки зрения сервера WSGI существует одно приложение WSGI, которое он непосредственно вызывает. Как правило, Flask является «реальным» приложением в конце цепочки средств промежуточного уровня. Но даже Flask может вызывать другие приложения WSGI, хотя это продвинутый и нечастый случай использования.
Распространенным средством промежуточного уровня, используемым с Flask, является Werkzeug ProxyFix, который изменяет запрос, чтобы он выглядел так, как будто он пришел непосредственно от клиента, даже если он прошел через HTTP-прокси по пути. Есть и другие средства промежуточного уровня, которые могут обрабатывать предоставление статических файлов, аутентификацию и т. д.
Как обрабатывается запрос
Для нас интересной частью вышеперечисленных шагов является момент, когда сервер WSGI (или middleware) вызывает Flask. В этот момент он выполняет довольно много действий для обработки запроса и генерации ответа. В самом простом случае он сопоставит URL с функцией-представлением, вызовет эту функцию и передаст возвращаемое значение обратно серверу. Но есть множество других возможностей для настройки его поведения.
- Сервер WSGI вызывает объект Flask, который вызывает
Flask.wsgi_app(). - Создается объект
RequestContext. Он преобразует словарь WSGIenvironв объектRequest. Он также создает объектAppContext. - Контекст приложения контекст приложения подталкивается, что делает доступными
current_appиg. - Отправляется сигнал
appcontext_pushed. - Подталкивается контекст запроса контекст запроса, что делает доступными
requestиsession. - Сессия открывается, загружая любые существующие данные сессии с использованием интерфейса сессии приложения
session_interface, экземпляраSessionInterface. - URL сопоставляется с правилами URL, зарегистрированными с помощью декоратора
route()во время настройки приложения. Если соответствия нет, ошибка (обычно 404, 405 или перенаправление) сохраняется для обработки позже. - Отправляется сигнал
request_started. - Вызываются любые функции, декорированные
url_value_preprocessor(). - Вызываются любые функции, декорированные
before_request(). Если какая-либо из этих функций возвращает значение, оно сразу обрабатывается как ответ. - Если URL не сопоставился с маршрутом на предыдущих шагах, эта ошибка поднимается сейчас.
- Вызывается функция-представление, декорированная
route(), связанная с соответствующим URL, и возвращает значение, которое будет использоваться в качестве ответа. - Если на каком-либо шаге произошла ошибка, и есть функция, декорированная
errorhandler(), которая соответствует классу исключения или коду HTTP-ошибки, она вызывается для обработки ошибки и возвращает ответ. - Любое значение, возвращающее ответ — функция перед запросом, представление или обработчик ошибок — преобразуется в объект
Response. - Вызываются любые функции, декорированные
after_this_request(), затем они очищаются. - Вызываются любые функции, декорированные
after_request(), которые могут изменить объект ответа. - Сессия сохраняется, сохраняя любые измененные данные сессии с использованием интерфейса сессии приложения
session_interface. - Отправляется сигнал
request_finished. - Если на каком-либо шаге произошла ошибка, и она не была обработана функцией-обработчиком ошибок, она обрабатывается сейчас. HTTP-исключения обрабатываются как ответы с соответствующим кодом состояния, другие исключения преобразуются в универсальный ответ 500. Отправляется сигнал
got_request_exception. - Статус, заголовки и тело объекта ответа возвращаются серверу WSGI.
- Вызываются любые функции, декорированные
teardown_request(). - Отправляется сигнал
request_tearing_down. - Контекст запроса удаляется,
requestиsessionбольше недоступны. - Вызываются любые функции, декорированные
teardown_appcontext(). - Отправляется сигнал
appcontext_tearing_down. - Контекст приложения удаляется,
current_appиgбольше недоступны. - Отправляется сигнал
appcontext_popped.
Существует еще больше декораторов и точек настройки, которые не являются частью каждого жизненного цикла запроса. Они более специфичны для определенных вещей, которые вы можете использовать во время запроса, таких как шаблоны, создание URL-адресов или обработка данных JSON. Смотрите остальную часть этой документации, а также API для дальнейшего изучения.
© 2010 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/3.0.x/lifecycle/