5.02. Справочник по Flask
Справочник по Flask
1. Основные компоненты приложения
Flask
Основной класс приложения во Flask. Создание экземпляра этого класса инициализирует веб-приложение.
from flask import Flask
app = Flask(__name__)
Параметры конструктора:
import_name— имя модуля или пакета приложения. Обычно передаётся__name__.static_url_path— URL-префикс для статических файлов. По умолчанию/static.static_folder— путь к папке со статическими файлами. По умолчанию'static'.static_host— хост для обслуживания статики (требуется при использовании поддоменов).host_matching— включает сопоставление хостов для всех правил маршрутизации.subdomain_matching— включает сопоставление поддоменов.template_folder— путь к папке с шаблонами. По умолчанию'templates'.instance_path— абсолютный путь к папке экземпляра приложения.instance_relative_config— загружать ли конфигурацию относительно папки экземпляра.root_path— корневой путь приложения. По умолчанию определяется автоматически.
Свойства экземпляра Flask
name— имя приложения, совпадает сimport_name.config— объект конфигурации (Config), содержит все настройки приложения.jinja_env— экземпляр среды Jinja2, используемый для рендеринга шаблонов.url_map— карта URL-адресов (Mapиз Werkzeug), содержит все зарегистрированные маршруты.before_request_funcs,after_request_funcs,teardown_request_funcs— списки обработчиков соответствующих событий.blueprints— словарь зарегистрированных Blueprint’ов.extensions— словарь расширений, привязанных к приложению.
2. Конфигурация приложения
Объект app.config представляет собой подкласс словаря и поддерживает все стандартные операции.
Встроенные конфигурационные ключи
| Ключ | Значение по умолчанию | Назначение |
|---|---|---|
DEBUG | False | Включает режим отладки. |
TESTING | False | Включает тестовый режим. |
PROPAGATE_EXCEPTIONS | None | Передаёт исключения в тестовом режиме. |
PRESERVE_CONTEXT_ON_EXCEPTION | None | Сохраняет контекст запроса при исключении. |
TRAP_HTTP_EXCEPTIONS | False | Преобразует HTTP-исключения в обычные. |
TRAP_BAD_REQUEST_ERRORS | None | Ловит ошибки типа BadRequest. |
SECRET_KEY | None | Секретный ключ для подписи сессий и токенов. |
SESSION_COOKIE_NAME | 'session' | Имя cookie для сессии. |
SESSION_COOKIE_DOMAIN | None | Домен cookie сессии. |
SESSION_COOKIE_PATH | None | Путь cookie сессии. |
SESSION_COOKIE_HTTPONLY | True | Устанавливает флаг HttpOnly. |
SESSION_COOKIE_SECURE | False | Требует HTTPS для отправки cookie. |
SESSION_COOKIE_SAMESITE | 'Lax' | Политика SameSite для cookie. |
PERMANENT_SESSION_LIFETIME | timedelta(days=31) | Время жизни постоянной сессии. |
USE_X_SENDFILE | False | Использовать X-Sendfile для отдачи файлов. |
SERVER_NAME | None | Имя сервера (для генерации абсолютных URL). |
APPLICATION_ROOT | '/' | Корень приложения (для сессий и URL). |
PREFERRED_URL_SCHEME | 'http' | Предпочтительная схема URL. |
MAX_CONTENT_LENGTH | None | Максимальный размер тела запроса. |
SEND_FILE_MAX_AGE_DEFAULT | timedelta(hours=12) | Время кэширования статики. |
TEMPLATES_AUTO_RELOAD | None | Автоматическая перезагрузка шаблонов. |
EXPLAIN_TEMPLATE_LOADING | False | Вывод информации о загрузке шаблонов. |
Методы управления конфигурацией
app.config.from_pyfile(filename, silent=False)— загружает конфиг из Python-файла.app.config.from_object(obj)— загружает конфиг из объекта (например, класса).app.config.from_envvar(variable_name, silent=False)— загружает путь к файлу из переменной окружения.app.config.from_file(filename, load_function, silent=False)— загружает конфиг из JSON/YAML через пользовательскую функцию.app.config.from_prefixed_env(prefix='FLASK')— загружает переменные окружения с префиксом (начиная с Flask 2.0).
3. Маршрутизация и представления
Декоратор @app.route
Регистрирует функцию как обработчик запроса по указанному пути.
Параметры:
rule— строка маршрута (например,'/user/<username>').endpoint— имя маршрута. По умолчанию — имя функции.methods— список HTTP-методов (например,['GET', 'POST']).defaults— словарь значений по умолчанию для переменных маршрута.subdomain— поддомен, к которому применяется маршрут.strict_slashes— управляет обработкой завершающего слеша.redirect_to— URL или функция для перенаправления.provide_automatic_options— автоматически обрабатывать OPTIONS-запросы.
Пример:
@app.route('/user/<username>', methods=['GET'], strict_slashes=False)
def profile(username):
return f"Profile of {username}"
Конвертеры переменных в маршрутах
Flask поддерживает следующие встроенные конвертеры:
<string:name>— любая строка без слеша (по умолчанию).<int:id>— целое число.<float:value>— число с плавающей точкой.<path:path>— строка, включающая слеши.<uuid:token>— UUID (требует Python 3.7+).
Можно регистрировать собственные конвертеры через app.url_map.converters.
4. Объекты запроса и ответа
request
Глобальный объект, представляющий текущий входящий запрос.
Свойства:
method— HTTP-метод (GET,POSTи т.д.).url— полный URL запроса.base_url— URL без строки запроса.host— хост запроса.remote_addr— IP-адрес клиента.headers— заголовки запроса (словарь).args— параметры строки запроса (?key=value).form— данные формы (POST).json— тело запроса в формате JSON.files— загруженные файлы.cookies— cookie, отправленные клиентом.is_json— указывает, является ли тело запроса JSON.get_json(force=False, silent=False, cache=True)— безопасное получение JSON.
Response
Объект ответа. Flask автоматически преобразует возвращаемое значение представления в Response.
Явное создание:
from flask import Response
return Response("Hello", status=200, mimetype='text/plain')
Параметры конструктора:
response— тело ответа (строка, байты, итератор).status— код состояния HTTP.headers— заголовки ответа.mimetype— MIME-тип (например,'application/json').content_type— полный Content-Type с кодировкой.
5. Сессии
Flask предоставляет защищённые подписанные cookie-сессии через глобальный объект session.
Использование:
from flask import session
session['user_id'] = 123
user_id = session.get('user_id')
session.pop('user_id', None)
Требования:
- Обязательно задан
SECRET_KEY. - Сессия сериализуется в JSON (поддерживаются только простые типы: строки, числа, списки, словари).
Настройки сессии — см. раздел «Конфигурация» выше (SESSION_COOKIE_*).
6. Blueprints
Blueprints — механизм модульной организации приложения. Позволяют группировать маршруты, обработчики ошибок, шаблоны и статические файлы в логически связанные компоненты.
Создание Blueprint
from flask import Blueprint
auth_bp = Blueprint('auth', __name__, url_prefix='/auth')
Параметры конструктора:
name— уникальное имя Blueprint’а.import_name— обычно__name__.static_folder,static_url_path,template_folder— аналогичны параметрамFlask.url_prefix— префикс для всех маршрутов внутри Blueprint’а.subdomain— поддомен, к которому применяется Blueprint.url_defaults— значения по умолчанию для переменных URL.
Регистрация Blueprint
app.register_blueprint(auth_bp)
Дополнительные параметры регистрации:
url_prefix— может быть переопределён при регистрации.options— словарь дополнительных настроек (например,subdomain).
Blueprints поддерживают собственные before_request, after_request, errorhandler и другие декораторы.
7. Обработка ошибок
Глобальные обработчики ошибок
@app.errorhandler(404)
def not_found(error):
return "Страница не найдена", 404
Поддерживаются как HTTP-коды, так и классы исключений:
from werkzeug.exceptions import BadRequest
@app.errorhandler(BadRequest)
def handle_bad_request(e):
return "Неверный запрос", 400
Возврат JSON при ошибках
В API-приложениях часто требуется возвращать ошибки в формате JSON:
@app.errorhandler(404)
def not_found_json(error):
return jsonify({"error": "Not found"}), 404
Ошибки в Blueprint
Blueprint может иметь собственные обработчики ошибок, которые перекрывают глобальные только для своих маршрутов.
8. Шаблоны и Jinja2
Flask использует шаблонизатор Jinja2 по умолчанию.
Рендеринг шаблона
from flask import render_template
@app.route('/')
def index():
return render_template('index.html', title="Главная")
Настройка Jinja2
Через app.jinja_env можно настраивать:
trim_blocks,lstrip_blocks— управление пробелами.autoescape— автоматическое экранирование (включено по умолчанию для.html).filters— регистрация пользовательских фильтров.globals— глобальные переменные в шаблонах.
Пользовательские фильтры
@app.template_filter('reverse')
def reverse_filter(s):
return s[::-1]
Использование в шаблоне: {{ name|reverse }}.
Макросы и наследование
Jinja2 поддерживает макросы ({% macro %}) и наследование шаблонов ({% extends %}, {% block %}).
9. Сигналы (Signals)
Flask использует систему сигналов через библиотеку blinker. Сигналы позволяют подписываться на события без прямого вызова функций.
Основные сигналы
request_started— начало обработки запроса.request_finished— завершение запроса.got_request_exception— возникновение исключения.template_rendered— рендеринг шаблона.signals_available— проверка доступности сигналов.
Пример подписки
from flask import got_request_exception
def log_exception(sender, exception, **extra):
print(f"Exception: {exception}")
got_request_exception.connect(log_exception, app)
Сигналы полезны для логирования, аудита, интеграции с внешними системами.
10. Командная строка (CLI)
Flask предоставляет встроенную поддержку CLI через Click.
Регистрация команды
@app.cli.command()
def init_db():
"""Инициализация базы данных."""
print("Database initialized")
Запуск: flask init_db.
Команды с параметрами
import click
@app.cli.command()
@click.option('--count', default=1, help='Number of greetings.')
def greet(count):
for _ in range(count):
print("Hello!")
Автоматическое обнаружение
Если переменная окружения FLASK_APP указывает на модуль, Flask автоматически загружает все зарегистрированные команды.
11. Тестирование
Flask предоставляет инструменты для интеграционного тестирования.
Клиент для тестов
with app.test_client() as client:
response = client.get('/')
assert response.status_code == 200
Контекст приложения в тестах
with app.app_context():
# Выполнение кода в контексте приложения
pass
Фикстуры и временные данные
Рекомендуется использовать pytest или unittest в сочетании с test_client() и app_context().
12. Работа с файлами и медиа
Отправка файлов
from flask import send_file
@app.route('/download')
def download():
return send_file('path/to/file.pdf', as_attachment=True)
Загрузка файлов
@app.route('/upload', methods=['POST'])
def upload():
file = request.files['file']
file.save('/uploads/' + file.filename)
return "Файл сохранён"
Ограничения:
- Установите
MAX_CONTENT_LENGTHв конфигурации. - Проверяйте расширения и MIME-типы вручную — Flask не делает этого автоматически.
13. Расширения
Flask имеет богатую экосистему расширений. Расширения обычно инициализируются так:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
db.init_app(app)
Популярные расширения
Flask-SQLAlchemy— ORM поверх SQLAlchemy.Flask-WTF— работа с формами и CSRF-защитой.Flask-Login— управление сессиями пользователей.Flask-Mail— отправка email.Flask-CORS— поддержка CORS.Flask-Migrate— миграции базы данных через Alembic.Flask-RESTful— создание REST API.Flask-JWT-Extended— аутентификация через JWT.
Расширения следуют соглашению: init_app(app) для отложенной инициализации.
14. Производительность и масштабируемость
Режим разработки vs продакшен
- В режиме
DEBUG=Trueвключены перезагрузка кода и отладчик. - Для продакшена используйте WSGI-сервер (Gunicorn, uWSGI) за обратным прокси (Nginx).
Асинхронность
Начиная с Flask 2.0, поддерживаются асинхронные представления:
@app.route('/async')
async def async_view():
await some_async_operation()
return "Done"
Требуется ASGI-сервер (например, Hypercorn или Daphne).
Кэширование
Flask не включает кэширование по умолчанию. Используйте Flask-Caching с бэкендами: Redis, Memcached, простой словарь.
15. Безопасность
Защита от основных угроз
- CSRF: используйте
Flask-WTFилиFlask-SeaSurf. - XSS: Jinja2 автоматически экранирует переменные в шаблонах.
- SQL-инъекции: используйте ORM или параметризованные запросы.
- Clickjacking: добавьте заголовок
X-Frame-Options: DENY. - Session fixation: регенерируйте сессию после входа.
Заголовки безопасности
Рекомендуется использовать Flask-Talisman для автоматической настройки безопасных заголовков (HSTS, CSP, XSS-Protection и др.).
16. Middleware и WSGI-уровень
Flask основан на спецификации WSGI (Web Server Gateway Interface). Приложение Flask само является WSGI-приложением и может быть обёрнуто в middleware.
Пример простого middleware
class PrefixMiddleware:
def __init__(self, app, prefix):
self.app = app
self.prefix = prefix
def __call__(self, environ, start_response):
if environ['PATH_INFO'].startswith(self.prefix):
environ['PATH_INFO'] = environ['PATH_INFO'][len(self.prefix):]
environ['SCRIPT_NAME'] = self.prefix
return self.app(environ, start_response)
else:
start_response('404 Not Found', [('Content-Type', 'text/plain')])
return [b'Not Found']
Подключение:
app.wsgi_app = PrefixMiddleware(app.wsgi_app, '/api')
Распространённые WSGI-мидлвары
ProxyFix(из Werkzeug) — корректирует заголовки при работе за обратным прокси.DispatcherMiddleware— объединяет несколько приложений под разными путями.SharedDataMiddleware— отдаёт статику (полезно в разработке без Nginx).
17. Контексты приложения и запроса
Flask использует два типа контекстов:
- Контекст приложения (
app_context) — содержит данные, общие для всего приложения (например, подключение к БД). - Контекст запроса (
request_context) — содержит данные, относящиеся к текущему HTTP-запросу.
Когда нужны контексты?
- В фоновых задачах (Celery, потоки).
- При запуске кода вне обработчика запроса (например, в CLI или тестах).
Пример использования
with app.app_context():
# Доступ к current_app, g, db и другим глобальным объектам
user = User.query.get(1)
Глобальные объекты
current_app— текущее приложение.g— временный объект для хранения данных в течение одного запроса.request,session,url_for— работают только внутри контекста запроса.
18. Логирование
Flask использует стандартный модуль logging Python.
Настройка логгера
import logging
app.logger.setLevel(logging.INFO)
handler = logging.FileHandler('app.log')
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
app.logger.addHandler(handler)
Использование
@app.route('/')
def index():
app.logger.info("Главная страница загружена")
return "OK"
В режиме DEBUG=True логи автоматически выводятся в консоль.
19. Интернационализация (i18n)
Flask не включает i18n по умолчанию, но легко интегрируется с Babel.
Установка и настройка
pip install Flask-Babel
from flask_babel import Babel, gettext
babel = Babel(app)
@babel.localeselector
def get_locale():
return request.accept_languages.best_match(['en', 'ru'])
Использование в шаблонах:
{{ _('Hello') }}
Компиляция переводов осуществляется через команды pybabel.
20. Работа с WebSocket и реального времени
Flask сам по себе не поддерживает WebSocket. Для этого используются расширения:
- Flask-SocketIO — реализует протокол Socket.IO поверх WebSocket и long polling.
- Quart — асинхронный клон Flask с нативной поддержкой WebSocket (альтернатива, а не расширение).
Пример с Flask-SocketIO
from flask_socketio import SocketIO, emit
socketio = SocketIO(app)
@socketio.on('connect')
def handle_connect():
emit('response', {'data': 'Connected'})
if __name__ == '__main__':
socketio.run(app)
21. Деплой и производственная эксплуатация
Требования к продакшену
- Отключите
DEBUG. - Установите надёжный
SECRET_KEY. - Используйте WSGI-сервер (Gunicorn, uWSGI).
- Разместите приложение за обратным прокси (Nginx, Apache).
- Настройте HTTPS.
Пример запуска через Gunicorn
gunicorn -w 4 -b 0.0.0.0:8000 myapp:app
Docker-образ
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "myapp:app"]
22. Мониторинг и метрики
- Логирование ошибок: Sentry, Loggly, ELK.
- Метрики: Prometheus + Flask-Exporter.
- Профилирование:
flask-profiler,py-spy.
Пример подключения Prometheus:
from prometheus_flask_exporter import PrometheusMetrics
metrics = PrometheusMetrics(app)
Автоматически экспортирует метрики по /metrics.
23. Типовая структура проекта
Хотя Flask не навязывает структуру, рекомендуется следующая организация:
myproject/
├── app/
│ ├── __init__.py # Создание экземпляра Flask
│ ├── models.py # Модели данных (если нет ORM-слоя)
│ ├── routes/
│ │ ├── __init__.py
│ │ ├── main.py
│ │ └── auth.py
│ ├── templates/
│ ├── static/
│ └── utils.py
├── migrations/ # Alembic миграции
├── tests/
├── config.py # Конфигурационные классы
├── requirements.txt
├── run.py # Точка входа
└── instance/ # Файлы экземпляра (если используется)
Для крупных проектов — переход на архитектуру по Blueprint’ам или даже на пакетную структуру с app/main/, app/auth/ и т.д.
24. Полезные функции и утилиты из flask и werkzeug
| Функция | Назначение |
|---|---|
url_for(endpoint, **values) | Генерация URL по имени маршрута. |
redirect(location, code=302) | Перенаправление клиента. |
abort(code) | Выбрасывает HTTP-исключение (например, abort(404)). |
make_response(rv) | Преобразует возвращаемое значение в объект Response. |
safe_join(directory, *pathnames) | Безопасное объединение путей (защита от directory traversal). |
secure_filename(filename) | Очистка имени файла от опасных символов. |
escape(s) | Экранирование HTML (устаревшее, лучше использовать Jinja2). |
25. Совместимость и версионность
- Flask 2.0+ требует Python 3.7+.
- Flask 3.0 (ожидается) будет требовать Python 3.9+.
- Werkzeug и Jinja2 обновляются вместе с Flask.
- Расширения могут отставать — проверяйте совместимость в
requirements.txt.