Flask: основы
Flask любят за минимализм, и собес проверяет ровно те места, где минимализм превращается в грабли: два контекста (application и request), время жизни flask.g и то, что встроенный сервер - не для прода. Эти три вопроса отсеивают тех, кто писал только hello-world.
Типовые формулировки: «сколько живёт flask.g?», «зачем blueprints?», «почему app.run() нельзя в прод».
Два контекста и время жизни g
Flask держит два контекста. Application-контекст (current_app, g) - про приложение, request-контекст (request, session) - про текущий запрос. Путаница между ними - источник «утёкших» данных, когда состояние одного запроса случайно видит другой.
Главный подвох - flask.g: это хранилище на ОДИН запрос, не глобальное состояние. К следующему запросу g обнуляется. Хочешь сохранить между запросами это session (куки), кэш или БД, но не g.
// @app.route(path) связывает URL с view-функцией, методы задаёшь methods=['POST']; возвращённое из view становится телом ответа.
- g
- контейнер данных на время одного запроса
- @app.route
- декоратор маршрутизации: путь → view-функция
Blueprints и почему не app.run() в прод
Blueprint - модульная группировка роутов, шаблонов и статики с общим префиксом. Большое приложение бьётся на blueprints вместо одного разбухшего файла: каждый модуль (auth, api, admin) - свой blueprint, регистрируется в приложении.
Встроенный app.run() это dev-сервер Werkzeug: отладка, авто-reload, удобно локально, но он не держит конкурентную нагрузку. В прод ставят gunicorn или uWSGI за nginx - они дают воркеры и реальную конкурентность. app.run() в проде - классическая ошибка новичка.
- Blueprint
- модуль приложения: группа роутов с общим префиксом
- dev-сервер
- app.run() для отладки, не для продакшена
Как отвечать: «Сколько живёт flask.g и что в ней хранить?»
flask.g живёт ровно один запрос - она создаётся в начале обработки и обнуляется к следующему запросу. Это не глобальное состояние, несмотря на имя, а удобный контейнер, чтобы протащить данные между слоями одного запроса: например, соединение с БД или текущего пользователя, вычисленного в before_request. Если мне надо сохранить что-то между запросами одного пользователя это уже session поверх куки, а общие данные - кэш или БД. Класть в g в расчёте на следующий запрос - типичная ошибка, данные просто пропадут.
Точно назван скоуп (один запрос), развеяно заблуждение из имени «global», приведены правильные примеры содержимого и альтернативы для межзапросного состояния.
На чём валят
- −Класть данные в flask.g в расчёте на следующий запрос: g живёт один запрос и обнуляется.
- −app.run() в проде - dev-сервер Werkzeug не держит конкурентную нагрузку; нужен gunicorn/uWSGI.
- −Путать app-контекст (на приложение) и request-контекст (на запрос) - источник «утёкших» данных.
- −Складывать всё приложение в один файл вместо blueprints - растёт до неподдерживаемого.
Проверьте себя
Пять вопросов из банка по этой подтеме. Всего их 14, остальные разбираются в тренажёре.
- Что делает
@app.route("/users")во Flask?A)Связывает URL с view-функцией под декораторомB)Кэширует ответ этого пути на стороне сервераC)Регистрирует новую таблицу users в базе данных приложенияD)Создаёт HTML-шаблон страницы users автоматическипоказать ответ и разбор
+A)Связывает URL с view-функцией под декоратором// разбор: Декоратор @app.route привязывает путь (и методы) к функции-обработчику: запрос на /users вызовет её, а возвращённое станет телом ответа. Методы задаются через methods=["POST"]. Это базовая маршрутизация Flask, аналог @app.get у FastAPI.
- Чем request-контекст Flask отличается от app-контекста?A)request-контекст общий сразу для всех активных запросовB)Это синонимы, Flask никак их между собой не различаетC)request живёт на один запрос, app — на приложениеD)app-контекст создаётся заново на каждый входящий запрос
показать ответ и разбор
+C)request живёт на один запрос, app — на приложение// разбор: Flask держит два контекста: application (current_app, g) и request (request, session). Оба заводятся на время обработки запроса, но g — хранилище на один запрос, не глобальное состояние между запросами. Путаница этих контекстов — источник багов с «утёкшими» данными.
- Зачем во Flask нужны blueprints?A)Заменить WSGI-сервер приложения на собственный движокB)Разбить приложение на модули со своими роутамиC)Автоматически сгенерировать схему базы данных проектаD)Ускорить рендеринг шаблонов за счёт предварительной компиляции
показать ответ и разбор
+B)Разбить приложение на модули со своими роутами// разбор: Blueprint — способ модульно организовать приложение: группа роутов, шаблонов и статики регистрируется на app с префиксом. Большое приложение бьётся на blueprints (auth, api, admin) вместо одного гигантского файла и подключается через app.register_blueprint.
- Почему встроенный
app.run()Flask не годится для продакшена?A)Он слушает только localhost и недоступен извнеB)Это dev-сервер: не держит нагрузку и один воркерC)Он требует обязательный HTTPS-сертификат для стартаD)Он запускается только на Windows-хостах разработчикапоказать ответ и разбор
+B)Это dev-сервер: не держит нагрузку и один воркер// разбор: Dev-сервер Flask (Werkzeug) рассчитан на отладку: удобные трейсбеки, авто-reload, но не на конкурентную нагрузку и устойчивость. В прод ставят WSGI-сервер (gunicorn/uWSGI) с несколькими воркерами за nginx. app.run в проде — классическая ошибка джуна.
- Разработчик кладёт данные в
flask.gи ждёт их в следующем запросе. Что не так?A)g хранит данные вечно, их нужно вручную чистить после запросаB)g работает только внутри шаблонов, но не во вьюхахC)g общий на всех пользователей, будет утечка данных между нимиD)g живёт один запрос — между запросами не сохраняетсяпоказать ответ и разбор
+D)g живёт один запрос — между запросами не сохраняется// разбор: g — контейнер на время одного запроса (в рамках его app-контекста), он обнуляется к следующему. Хранить в нём состояние между запросами нельзя — для этого session (куки), кэш или БД. Ожидание, что g переживёт запрос, — частое заблуждение о его природе.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.