
Flask – это микрофреймворк на Python, построенный на базе WSGI-интерфейса и библиотеки Werkzeug. Он не навязывает архитектуру проекта, не включает ORM по умолчанию и не содержит систем шаблонов, кроме встроенного Jinja2. Это позволяет использовать только необходимые компоненты, не перегружая приложение лишними зависимостями.
Маршрутизация в Flask реализована через декораторы. Каждый маршрут соответствует Python-функции, которая обрабатывает запрос и возвращает ответ. Поддерживается работа с методами GET, POST, PUT, DELETE и другими HTTP-методами без дополнительных настроек. Для доступа к параметрам запроса используется объект request из пакета flask.
Запуск приложения осуществляется через метод app.run(). В отладочном режиме (debug=True) Flask автоматически перезапускает сервер при изменении кода. Для использования в продакшене рекомендуется запуск через WSGI-сервер, например Gunicorn или uWSGI, с отключённым встроенным сервером Flask.
Система шаблонов Jinja2 позволяет использовать наследование, фильтры, условия и циклы прямо в HTML-файлах. Шаблоны размещаются в директории templates, статические файлы – в static. Flask автоматически подгружает их без дополнительной конфигурации.
Расширения, такие как Flask-SQLAlchemy, Flask-Migrate, Flask-Login, подключаются при необходимости и не загружаются по умолчанию. Это позволяет наращивать функциональность постепенно, без избыточной инфраструктуры.
Flask в Python: как работает микрофреймворк
Flask реализует минимальный каркас для построения веб-приложений, предоставляя только маршрутизацию, обработку запросов и шаблонизацию через Jinja2. Он не включает ORM, формы или администрирование, но позволяет подключать сторонние библиотеки по мере необходимости. За счёт этого достигается гибкость без скрытой логики и ненужных зависимостей.
Маршруты в Flask определяются через декораторы, что даёт чёткую привязку URL к функции:
@app.route('/users/<int:id>')
def get_user(id):
return f"Пользователь: {id}"
Контекст запроса (объекты request, session, g) создаётся на каждый входящий HTTP-запрос и уничтожается после отправки ответа. Это исключает проблемы с состоянием между пользователями и упрощает отладку.
Встроенный WSGI-сервер Werkzeug обеспечивает взаимодействие между приложением Flask и веб-сервером (например, Gunicorn или uWSGI). Это позволяет разворачивать приложение без внешних фреймворков, сохраняя контроль над поведением запроса.
Jinja2 позволяет использовать шаблоны с логикой рендеринга прямо в HTML. Шаблоны автоматически экранируют ввод, что снижает риск XSS-атак. Передача данных в шаблон реализуется через словари:
return render_template('profile.html', name='Иван')
Flask не имеет встроенной поддержки многопоточности, но корректно работает с WSGI-серверами, обрабатывающими запросы параллельно. Подключение SQLAlchemy или других ORM происходит вручную, без скрытых зависимостей и генерации кода.
Для настройки используются переменные окружения или объект конфигурации, подключаемый через app.config.from_pyfile(). Это упрощает изоляцию окружений (dev/test/prod) без изменения исходного кода.
Инициализация Flask-приложения: минимальная структура и запуск

Для запуска минимального Flask-приложения достаточно одного Python-файла. Название файла не имеет значения, но по соглашению часто используется app.py.
Содержимое минимального приложения:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "Приложение работает"
if __name__ == "__main__":
app.run()
Объект Flask создаётся с передачей имени текущего модуля. Это требуется для корректной настройки путей, например, к шаблонам и статике. Аргументом передаётся __name__, что позволяет Flask определить, откуда загружать ресурсы.
Маршрут / регистрируется через декоратор @app.route(). Функция, связанная с маршрутом, должна возвращать строку, объект ответа или результат функции render_template().
Метод app.run() запускает встроенный сервер разработки. По умолчанию он слушает 127.0.0.1:5000. Для запуска на другом адресе и порту используется:
app.run(host="0.0.0.0", port=8000, debug=True)
Минимальная структура проекта может состоять из одного файла. Однако при усложнении логики имеет смысл выносить маршруты, конфигурации и шаблоны в отдельные директории. Для запуска достаточно команды:
python app.py
Маршруты и обработка запросов: как связать URL и функции
@app.route("/profile")
def profile():
return "Профиль пользователя"
Поддерживаются переменные сегменты URL. Для передачи параметров используется синтаксис <имя> или <имя:тип>:
@app.route("/user/<username>")
def show_user(username):
return f"Пользователь: {username}"
Типы: string (по умолчанию), int, float, path, uuid. Пример с типом:
@app.route("/post/<int:post_id>")
def show_post(post_id):
return f"Пост №{post_id}"
Для обработки разных HTTP-методов используется параметр methods:
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
return "Обработка входа"
return "Форма входа"
Если путь не указан явно, корневой маршрут "/" связывается с основной страницей:
@app.route("/")
def index():
return "Главная страница"
Для доступа к данным запроса используется объект request из flask. Пример извлечения параметров из строки запроса:
from flask import request
@app.route("/search")
def search():
query = request.args.get("q")
return f"Результаты для: {query}"
Формы передают данные через request.form, а JSON – через request.json. Пример с JSON:
@app.route("/api/data", methods=["POST"])
def api_data():
data = request.json
return {"status": "ok", "received": data}
Маршруты с перекрывающимися путями обрабатываются в порядке регистрации. Flask не допускает два одинаковых маршрута с одними и теми же методами – это вызовет ошибку.
Для генерации URL на основе имени функции используется url_for():
url_for("show_user", username="alice")
Это гарантирует корректную генерацию путей при изменении структуры маршрутов.
Шаблоны Jinja2: передача данных и рендеринг HTML

Flask использует движок Jinja2 для генерации HTML на основе переданных данных. Шаблоны хранятся в директории templates, которая создаётся в корне проекта. Для рендеринга используется функция render_template, импортируемая из модуля flask.
Данные передаются в шаблон через именованные аргументы функции render_template. Ключи становятся переменными, доступными внутри HTML-файла. Например, render_template("index.html", username="Иван") делает переменную {{ username }} доступной в шаблоне.
Поддерживаются конструкции управления логикой: % if %}, {% for %}, фильтры ({{ name}), макросы и наследование шаблонов. Шаблон может расширять другой через {% extends "base.html" %} и вставлять содержимое в блоки {% block content %}.
Избегайте передачи в шаблон сложных объектов, не предназначенных для сериализации, таких как открытые файловые дескрипторы или соединения с базой данных. Поддерживаются списки, словари, строки, числа и стандартные объекты Python.
Для отображения HTML без экранирования используется фильтр |safe. Его применение требует осторожности: нельзя передавать пользовательский ввод напрямую, если он не прошёл очистку. Это касается вставок через { variable}.
Для отладки полезно использовать встроенный режим отладки Flask. При ошибках рендеринга Jinja2 выдаёт точное сообщение с указанием строки в шаблоне, что ускоряет поиск причины.
Разделяйте логику и представление. Не вставляйте SQL-запросы или бизнес-логику в шаблон. Все вычисления должны выполняться в представлении (view-функции), а шаблон – только отображать результат.
Работа с формами: получение данных из POST-запросов
Во Flask данные из форм извлекаются через объект request, доступный из модуля flask. Метод запроса проверяется с помощью request.method, а сами данные – через request.form.
from flask import Flask, request
app = Flask(__name__)
@app.route('/submit', methods=['POST'])
def handle_form():
username = request.form.get('username')
email = request.form.get('email')
return f"Получено: {username}, {email}"
request.form– словарь с данными из тела POST-запроса, еслиContent-Typeустановлен какapplication/x-www-form-urlencodedилиmultipart/form-data.get()безопасен – вернётNone, если ключ отсутствует, вместо выбрасывания исключения.- Чтобы обрабатывать только POST, указывай параметр
methods=['POST']в декораторе@app.route.
Если форма содержит файл, используют request.files:
file = request.files.get('document')
if file:
file.save('/путь/к/файлу')
Для проверки источника данных:
request.args– параметры из URL-строки.request.form– данные из формы.request.json– тело запроса в формате JSON (если указан соответствующийContent-Type).
Пример шаблона HTML-формы, отправляющей POST-запрос:
<form action="/submit" method="post">
<input type="text" name="username">
<input type="email" name="email">
<button type="submit">Отправить</button>
</form>
Для защиты от CSRF-атак в продакшене используйте Flask-WTF с токеном csrf_token.
Подключение и использование SQLite в Flask
Для подключения к SQLite необходимо указать путь к базе данных в конфигурации Flask-приложения. Можно задать строку подключения как абсолютный путь, либо использовать относительный путь к файлу базы данных в проекте. Для этого можно использовать параметр SQLALCHEMY_DATABASE_URI, если применяется библиотека SQLAlchemy, или напрямую подключиться через sqlite3 для выполнения запросов.
Пример настройки SQLite в Flask-приложении:
from flask import Flask
import sqlite3
app = Flask(__name__)
def get_db():
db = sqlite3.connect('example.db')
db.row_factory = sqlite3.Row
return db
@app.route('/')
def index():
db = get_db()
cursor = db.cursor()
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
db.close()
return str(rows)
В этом примере создается соединение с базой данных example.db и выполняется запрос на получение данных из таблицы users. Метод row_factory используется для преобразования строк в объекты с доступом к столбцам по имени.
SQLite в Flask можно использовать с SQLAlchemy, если требуется более удобная абстракция для работы с данными. Для этого необходимо установить и настроить Flask-SQLAlchemy. Этот подход позволит эффективно управлять моделями данных и выполнять запросы с использованием ORM.
Для обеспечения целостности данных стоит использовать контекст приложений Flask. Например, создание базы данных и таблиц может быть выполнено в контексте при запуске приложения.
from flask_sqlalchemy import SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
with app.app_context():
db.create_all() # Создает таблицы в базе данных
Здесь база данных и таблица для модели User создаются при вызове метода create_all() в контексте приложения. Это позволяет гарантировать правильную настройку и структуру базы данных.
Важной особенностью SQLite является отсутствие полноценной поддержки многопользовательской работы в реальном времени. Это ограничение можно обойти с помощью механизмов блокировок или при переходе на более мощные решения для продакшн-окружения.
Использование SQLite в Flask помогает ускорить разработку и тестирование без необходимости в сложной настройке сторонних сервисов баз данных.
Сессии и cookies: хранение пользовательских данных между запросами
Для хранения информации о пользователе между запросами Flask использует два основных механизма: сессии и cookies. Эти технологии позволяют веб-приложению «помнить» данные о пользователе без необходимости каждый раз запрашивать информацию из базы данных.
Cookies представляют собой небольшие текстовые файлы, которые браузер сохраняет на стороне клиента. Flask позволяет работать с cookies через объект request. Cookies обычно используются для хранения данных, которые должны быть доступны в каждом запросе, например, идентификатор сессии или настройки пользователя.
- Запись cookies: Flask записывает cookies с помощью функции
make_response(). Это позволяет прикрепить cookies к ответу, который отправляется клиенту. Пример:
from flask import make_response
@app.route('/set_cookie')
def set_cookie():
resp = make_response("Cookie set!")
resp.set_cookie('user_id', '12345')
return resp
request.cookies. Пример:
from flask import request
@app.route('/get_cookie')
def get_cookie():
user_id = request.cookies.get('user_id')
return f'User ID from cookie: {user_id}'
Сессии в Flask используют cookies для хранения данных, но они шифруются и защищены с помощью секретного ключа. Сессии позволяют хранить более сложные данные, такие как пользовательские предпочтения или состояние пользователя между запросами, не опасаясь, что эти данные могут быть подделаны.
- Запись данных в сессию: Сессия в Flask используется через объект
session. В отличие от cookies, данные сессии не могут быть легко изменены пользователем. Пример:
from flask import session
@app.route('/set_session')
def set_session():
session['user_id'] = '12345'
return 'Session set!'
session:
@app.route('/get_session')
def get_session():
user_id = session.get('user_id')
return f'User ID from session: {user_id}'
Чтобы сессии работали, необходимо настроить секретный ключ для Flask-приложения. Это можно сделать, установив значение app.secret_key. Например:
app.secret_key = 'your_secret_key'
Использование сессий и cookies в Flask важно для безопасности. Все данные, которые хранятся в cookies, могут быть подделаны пользователем. Поэтому для более конфиденциальных данных следует использовать сессии, которые шифруются и не могут быть изменены напрямую. Также следует использовать безопасные флаги при работе с cookies, чтобы предотвратить возможные атаки.
- Безопасность cookies: Для повышения безопасности можно использовать флаг
secureдля cookies, чтобы они отправлялись только через HTTPS-соединение, и флагhttponly, чтобы предотвратить доступ к cookies через JavaScript:
resp.set_cookie('user_id', '12345', secure=True, httponly=True)
Важное замечание: cookies могут быть отключены в браузере пользователя, что приведет к невозможности использования этого механизма. В таких случаях можно использовать сессии, которые будут храниться на сервере.
Регистрация собственных фильтров и обработчиков ошибок

В Flask можно добавлять собственные фильтры и обработчики ошибок для расширения стандартных возможностей. Это позволяет кастомизировать обработку исключений и представление данных, предоставляемое в шаблонах.
Регистрация фильтров

from flask import Flask
import datetime
app = Flask(__name__)
def format_date(value):
if isinstance(value, datetime.date):
return value.strftime('%d-%m-%Y')
return value
app.jinja_env.filters['format_date'] = format_date
Теперь в шаблоне можно использовать фильтр format_date:
format_date }
Этот фильтр преобразует объект datetime.date в строку в формате «день-месяц-год». Если значение не является датой, фильтр просто возвращает его без изменений.
Регистрация обработчиков ошибок
Flask предоставляет возможность регистрировать обработчики для различных типов ошибок. Для этого используется декоратор @app.errorhandler, который привязывает функцию обработки ошибки к коду состояния HTTP.
from flask import Flask, render_template
app = Flask(__name__)
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
В данном примере обработчик для ошибки 404 отображает шаблон 404.html. Код ошибки передается в обработчик как параметр e, но в данном случае он не используется напрямую.
Можно создавать обработчики для любых ошибок, включая 500 (внутренняя ошибка сервера), 403 (Forbidden) и другие. Важно, чтобы обработчики ошибок всегда возвращали корректный HTTP-ответ, который будет отправлен клиенту.
Советы по использованию
- При регистрации фильтров учитывайте, что они должны быть максимально универсальными, чтобы избежать избыточной логики в шаблонах.
- Обработчики ошибок не должны быть слишком сложными, их задача – предоставить пользователю информативное сообщение или перенаправить на другую страницу.
- Создание фильтров и обработчиков ошибок позволяет избежать повторного кода и улучшить поддержку различных случаев в приложении.
Вопрос-ответ:
Что такое Flask и как он работает?
Flask — это микрофреймворк для разработки веб-приложений на Python. Он предоставляет минимальный набор инструментов для создания веб-серверов и API, позволяя разработчику самому решать, какие компоненты и библиотеки подключать. Flask не имеет жесткой структуры, что дает большую гибкость при создании приложения. В его основе лежит простой сервер, а для работы с запросами используются маршруты, которые указываются в коде. Каждый маршрут обрабатывает определенный тип запросов, например, GET или POST, и может возвращать HTML-страницу или другие типы данных.
Какие преимущества использования Flask по сравнению с другими фреймворками?
Flask выделяется среди других фреймворков своей простотой и минимализмом. Он не навязывает структуру проекта, и вы сами решаете, как строить приложение. Это особенно удобно для небольших проектов, стартапов или для тех, кто хочет быстро разрабатывать прототипы. В Flask нет встроеннойORM или аутентификации, что позволяет легко использовать сторонние библиотеки, если это необходимо. Этот фреймворк подходит для опытных разработчиков, которые хотят полный контроль над процессом создания приложения.
Как работает маршрутизация в Flask?
Маршрутизация в Flask основывается на декораторах. Для каждого маршрута (пути, по которому приходит запрос) создается функция, которая обрабатывает этот запрос. Например, для создания маршрута, который будет отвечать на GET-запросы по адресу «/hello», нужно использовать декоратор @app.route(‘/hello’) и создать соответствующую функцию, которая вернет ответ. Flask автоматически связывает запросы с нужной функцией, исходя из URL и метода HTTP. Можно также добавлять параметры в маршруты, чтобы получать данные, передаваемые в запросе.
Можно ли использовать Flask для больших проектов?
Flask отлично подходит для небольших и средних проектов, а также для прототипов и API. Однако, при переходе к большим проектам, его гибкость может стать как преимуществом, так и проблемой. В больших приложениях разработчику предстоит самостоятельно организовать структуру проекта, что может быть сложнее, чем в фреймворках с более строгими ограничениями, например, Django. Для крупных проектов в Flask часто используется модульная архитектура, позволяющая разбить приложение на несколько частей и лучше организовать код. При этом Flask легко интегрируется с другими библиотеками и инструментами, что дает возможность масштабировать проект по мере роста.
