Flask (по-русски часто пишут «фласк») — микрофреймворк для веб-приложений на Python. В ядре у него маршруты, обработка запросов и шаблоны, а базы данных, формы и вход по паролю подключаются расширениями. Чтобы начать, поставьте Python 3.9 или новее, выполните pip install Flask в виртуальном окружении, создайте файл с тремя строками кода и запустите его командой flask --app hello run. Через пару секунд по адресу http://127.0.0.1:5000/ откроется ваша первая страница.
Ниже весь путь от установки до маленького приложения со списком задач, формой и JSON-ответом. Примеры написаны под Flask 3.1.3 и Python 3.14, в блоках кода показано, что печатает терминал. Если Python ещё не стоит, начните с инструкции как скачать и установить Python, а про то, зачем вообще нужно отдельное окружение, есть разбор виртуального окружения venv.
Что такое Flask и почему его называют микрофреймворком

Фреймворк берёт на себя рутину веб-сервера: принимает HTTP-запрос, находит функцию под нужный адрес и превращает её результат в ответ браузеру. Вам остаётся написать сами функции. Если слова «запрос» и «ответ» пока звучат абстрактно, сначала загляните в материал про методы HTTP: Flask построен ровно на этой модели.
Слово «микро» в названии не про размер проектов. В разделе о философии дизайна разработчики пишут, что Flask старается оставить ядро простым и расширяемым и не решает за вас, например, какую базу данных использовать. Слоя для работы с базой и проверки форм в нём нет, это добавляют расширения.
При установке Flask сам подтягивает шесть пакетов. Список и назначение каждого взяты со страницы установки документации:
| Пакет | Что делает |
|---|---|
| Werkzeug | реализует WSGI, стандартный интерфейс между приложением на Python и сервером |
| Jinja | шаблонизатор, из которого собираются HTML-страницы |
| MarkupSafe | экранирует пользовательский ввод в шаблонах, чтобы закрыть инъекции |
| ItsDangerous | подписывает данные, на нём держится cookie сессии |
| Click | даёт команду flask в терминале |
| Blinker | поддержка сигналов |
Первая версия, 0.1, появилась на PyPI 16 апреля 2010 года. Версия 3.1.3 вышла 19 февраля 2026 года. Проект ведёт открытое сообщество Pallets, исходники лежат на GitHub.
Если хотите разбирать Flask с наставником и проверкой заданий, на Checkroi есть подборка курсов, где Flask входит в программу.
Flask, Django или FastAPI: что выбрать
У новичка в Python-вебе обычно три кандидата. Разница между ними в том, сколько решений фреймворк принимает за вас.
| Flask | Django | FastAPI | |
|---|---|---|---|
| Что в коробке | маршруты, шаблоны Jinja, сессии | ORM, админка, шаблоны, интернационализация | маршруты, проверка данных по аннотациям типов, документация API |
| База данных | подключаете сами, например через Flask-SQLAlchemy | встроенный ORM | подключаете сами |
| Под что берут | небольшие сайты, внутренние сервисы, прототипы, учебные проекты | крупные сайты с личными кабинетами и админкой | API для мобильных приложений и фронтенда |
| Порог входа | первый сайт за вечер | больше понятий до первой страницы | нужно понимать аннотации типов |
Состав коробки сверен по официальным страницам: у Django на главной перечислены ORM, автоматическая админка и шаблоны, у FastAPI названы стандартные аннотации типов и автоматическая интерактивная документация. Строки «Под что берут» и «Порог входа» мы написали сами, в документации таких оценок нет.
Flask удобнее всего для первого знакомства с веб-разработкой: в нём мало магии, и каждая строка кода видна. Если потом захочется перейти на фреймворк покрупнее, полезно прочитать, чем Django-разработчик отличается от Python-разработчика.
Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединитьсяКак установить Flask
Команды взяты из официальной инструкции. Flask поддерживает Python 3.9 и новее, документация советует брать последнюю версию языка.
- Создайте папку проекта и откройте в ней терминал.
- Создайте виртуальное окружение. На macOS и Linux:
python3 -m venv .venv, на Windows:py -3 -m venv .venv. - Активируйте его. На macOS и Linux:
. .venv/bin/activate, на Windows:.venv\Scripts\activate. Слева в строке терминала появится(.venv). - Установите фреймворк:
pip install Flask. - Проверьте, что всё встало:
flask --version.
$ flask --version
Python 3.14.7
Flask 3.1.3
Werkzeug 3.1.9
Если команда flask не находится, скорее всего, окружение не активировано или терминал открыт в другой папке. Для работы с кодом удобно сразу настроить VS Code для Python: редактор сам подхватит .venv и будет запускать файлы в нём.
Первое приложение на Flask: Hello World
Создайте в папке проекта файл hello.py:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "Привет, Flask!"
Что здесь происходит:
app = Flask(__name__)создаёт приложение. Через__name__Flask узнаёт, где лежит ваш модуль, и потом ищет рядом папки с шаблонами и статикой.- Декоратор
@app.route("/")привязывает функцию к адресу. Здесь это корень сайта. - Функция возвращает строку, и Flask отдаёт её браузеру как HTML.
Запустите сервер разработки:
$ flask --app hello run
* Serving Flask app 'hello'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
Откройте http://127.0.0.1:5000/ и увидите «Привет, Flask!». Остановить сервер можно сочетанием Ctrl+C в терминале.
Пока пишете код, включайте режим отладки флагом --debug. Тогда сервер сам перезапускается после каждой правки файла, а при ошибке показывает в браузере интерактивный отладчик:
$ flask --app hello run --debug
* Serving Flask app 'hello'
* Debug mode: on
* Running on http://127.0.0.1:5000
* Restarting with stat
* Debugger is active!
* Debugger PIN: 138-626-221
Через отладчик можно выполнить любой код Python прямо из браузера. В кратком руководстве Flask прямо предупреждает: не запускайте сервер разработки и отладчик в рабочем окружении. Поэтому режим отладки — только на своём компьютере.
Маршруты и переменные в адресе
У сайта много адресов, и каждый ведёт на свою функцию. Часть адреса можно сделать переменной: Flask вырежет её и передаст в функцию аргументом. Создадим файл app.py для маленького списка задач:
from flask import Flask
from markupsafe import escape
app = Flask(__name__)
tasks = ["Установить Flask", "Написать первый маршрут"]
@app.route("/hello/<name>")
def hello(name):
return f"Привет, {escape(name)}!"
@app.route("/task/<int:task_id>")
def task(task_id):
if task_id >= len(tasks):
return "Такой задачи нет", 404
return tasks[task_id]
Запуск теперь без --app: файл называется app.py, и команда flask run находит его сама. Вот что отвечает сервер на разные адреса:
| Адрес | Ответ |
|---|---|
/hello/Аня |
Привет, Аня! |
/task/1 |
Написать первый маршрут |
/task/7 |
код 404, «Такой задачи нет» |
/task/abc |
код 404: int пропускает только целые числа |
/hello/<b>Аня |
Привет, <b>Аня!: браузер покажет тег текстом и не выполнит его |
Последняя строка показывает, зачем нужна escape(). Без неё всё, что человек допишет в адрес, попадёт в страницу как HTML, вместе со скриптами. В шаблонах Jinja экранирование включено само, а вот в строках, которые вы собираете вручную через f-строки, о нём приходится помнить.
Ответ можно вернуть кортежем «текст, код»: так return "Такой задачи нет", 404 отдаёт страницу с кодом ошибки. Сами функции-обработчики остаются обычными функциями Python, ничего особенного в них нет.
Шаблоны Jinja2 и форма

Собирать HTML строками неудобно уже на второй странице. Для этого есть шаблоны: Flask ищет их в папке templates рядом с приложением. Структура проекта станет такой:
todo/
├── app.py
└── templates/
├── index.html
└── add.html
Шаблон templates/index.html выводит список задач циклом Jinja:
<!doctype html>
<title>Мои задачи</title>
<h1>Задачи: {{ tasks|length }}</h1>
<ul>
{% for t in tasks %}
<li>{{ t }}</li>
{% endfor %}
</ul>
<a href="{{ url_for('add') }}">Добавить задачу</a>
В templates/add.html лежит форма из одного поля:
<!doctype html>
<title>Новая задача</title>
<form method="post">
<input name="title" placeholder="Что сделать">
<button>Сохранить</button>
</form>
В app.py добавьте два маршрута и расширьте импорт:
from flask import Flask, redirect, render_template, request, url_for
@app.route("/")
def index():
return render_template("index.html", tasks=tasks)
@app.route("/add", methods=["GET", "POST"])
def add():
if request.method == "POST":
title = request.form.get("title", "").strip()
if title:
tasks.append(title)
return redirect(url_for("index"))
return render_template("add.html")
Как это работает:
- По умолчанию маршрут принимает только GET. Параметр
methods=["GET", "POST"]разрешает ещё и отправку формы. - При GET функция показывает пустую форму, при POST читает поле
titleизrequest.form. - После сохранения
redirect(url_for("index"))отправляет браузер обратно на главную. Сервер отвечает кодом 302, и обновление страницы не отправит форму второй раз. url_for("index")строит адрес по имени функции. Если переименовать адрес в декораторе, ссылки в шаблонах поменяются сами.
После того как через форму добавили «Выложить на сервер», главная страница показывает «Задачи: 3» и три пункта списка. Учтите, что список в переменной живёт, пока работает сервер: после перезапуска задачи пропадут. Для постоянного хранения нужна база данных, во Flask её обычно подключают расширением Flask-SQLAlchemy.
Стили, скрипты и картинки: папка static
CSS, JavaScript и изображения Flask отдаёт из папки static рядом с приложением. По краткому руководству, она сама становится доступна по адресу /static. Положите туда файл style.css:
todo/
├── app.py
├── static/
│ └── style.css
└── templates/
├── index.html
└── add.html
В шаблоне ссылку на файл стройте через ту же url_for, только с именем static:
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
В готовой странице на этом месте окажется /static/style.css, а сервер отдаст файл с типом text/css. На рабочем сервере статику лучше отдать веб-серверу, например nginx. По документации, в идеале эти файлы раздаёт веб-сервер, а Flask может делать это во время разработки.
Как отдать JSON и сделать простое API
Тот же Flask годится и для API, которое читает фронтенд или мобильное приложение. Что это такое и зачем нужно, подробно описано в статье что такое API простыми словами. Добавьте в app.py:
from flask import jsonify
app.json.ensure_ascii = False
@app.route("/api/tasks")
def api_tasks():
return jsonify(count=len(tasks), tasks=tasks)
Ответ на запрос /api/tasks:
{"count":2,"tasks":["Установить Flask","Написать первый маршрут"]}
Строка app.json.ensure_ascii = False нужна ради кириллицы. Без неё Flask отдаёт русские буквы escape-последовательностями вида \u0423\u0441.... Браузер и программы их поймут, но читать такой ответ глазами неудобно. Если функция возвращает словарь или список, jsonify() можно не писать: по документации, Flask вызовет его сам.
Частые ошибки и что с ними делать
Тексты ошибок приведены дословно, как их печатают Flask 3.1.3 и Python.
| Что видите | Почему | Что сделать |
|---|---|---|
ModuleNotFoundError: No module named 'flask' |
скрипт запущен не тем Python, в котором стоит Flask | активируйте .venv и запустите снова |
Error: Could not locate a Flask application. |
в папке нет app.py или wsgi.py, а --app не указан |
перейдите в папку проекта или запустите с --app имя_файла |
Error: Could not import 'nosuch'. |
в --app опечатка в имени модуля |
укажите имя файла без .py |
на macOS адрес localhost:5000 отвечает пустой страницей с кодом 403 |
порт 5000 занимает системная служба AirPlay, а Flask слушает только 127.0.0.1 |
откройте http://127.0.0.1:5000/ или запустите на другом порту: flask run --port 5001 |
AssertionError: View function mapping is overwriting an existing endpoint function: page |
у двух маршрутов функции с одинаковым именем | дайте каждой функции своё имя |
jinja2.exceptions.TemplateNotFound: main.html |
шаблон лежит не в templates или имя написано иначе |
проверьте имя файла и папку |
405 Method Not Allowed при отправке формы |
маршрут принимает только GET | добавьте methods=["GET", "POST"] |
С портом на Mac легко потерять полчаса: сервер запускается без единого предупреждения, и кажется, что сломан код. Пока Flask работает, запрос на localhost:5000 возвращает 403 с заголовком Server: AirTunes, а запрос на 127.0.0.1:5000 открывает страницу приложения. О том, что macOS Monterey и новее занимает этот порт системной службой, пишет и документация сервера разработки.
Если Python-окружения путаются в целом, а не только с Flask, пригодится разбор как запустить скрипт Python через командную строку.
Как выложить Flask-приложение на сервер

Команда flask run поднимает сервер для разработки, и он сам об этом предупреждает при каждом запуске. На рабочем сервере приложение запускают через WSGI-сервер, а перед ним обычно ставят nginx. В разделе о развёртывании документация разбирает Gunicorn, Waitress, mod_wsgi, uWSGI и другие варианты. Для начала хватит одного из двух:
| Сервер | Где работает | Команда для нашего app.py |
|---|---|---|
| Gunicorn | Linux и macOS, на Windows только через WSL | gunicorn -w 4 'app:app' |
| Waitress | в том числе Windows без WSL | waitress-serve --host 127.0.0.1 app:app |
Запись app:app читается как «из модуля app взять переменную app». Под Gunicorn наш список задач по умолчанию слушает http://127.0.0.1:8000 и отвечает так же, как под сервером разработки.
Перед выкладкой проверьте три вещи:
- режим отладки выключен, флага
--debugв команде запуска нет; - задачи хранятся в базе, а не в переменной;
- зависимости записаны в файл командой
pip freeze > requirements.txt, чтобы на сервере поставить те же версии.
Где освоить Flask и Python системно
Маршруты, шаблоны и форма займут первый вечер с Flask. Дальше начинается работа бэкенд-разработчика: базы данных и миграции, авторизация, тесты, очереди, Docker и деплой без ручных шагов. Чем такой специалист занят каждый день, разобрано в материале кто такой бэкенд-разработчик, а пошаговый план есть в статье как стать Python-разработчиком.
Учиться с проверкой заданий удобнее на курсе. Подборки собраны в каталоге: курсы с Flask в программе и все курсы по Python. Несколько программ из каталога:
| Курс | Школа | Стоимость со скидкой | В рассрочку | Длительность | Обзор курса от Checkroi |
|---|---|---|---|---|---|
| Профессия «Python-разработчик» Перейти на сайт курса | 157 335 ₽ | 5987 ₽/мес. | 10 месяцев | Обзор курса | |
| Fullstack-разработчик на Python Перейти на сайт курса | 137 000 ₽ | 7125 ₽/мес. | 21 месяц | Обзор курса | |
| ДО Профессия Python-разработчик Перейти на сайт курса | 149 001 ₽ | 3167 ₽/мес. | 10 месяцев | Обзор курса | |
| Автоматизированное тестирование на Python Перейти на сайт курса | 122 226 ₽ | 4108 ₽/мес. | 9 месяцев | Обзор курса | |
| Профессия Python-разработчик Перейти на сайт курса | 154 044 ₽ | 4279 ₽/мес. | 10 месяцев | Обзор курса |
Больше программ — в полном каталоге курсов по Python




