Перейти к основному содержимому

FastAPI

Разработчику Архитектору

FastAPI

FastAPI — фреймворк для построения HTTP API на Python 3.8+. Под "API" здесь имеется в виду сервис, который принимает запросы по сети (обычно JSON) и отдаёт JSON — без готовых HTML-страниц "из коробки", как у классического сайта.

Типичные сценарии:

  • REST/JSON-сервисы;
  • микросервисы;
  • бэкенд для SPA (React, Vue);
  • мобильных приложений.

Пошаговый старт с кодом: Первая программа на FastAPI (включая JWT). Сравнение Flask, Django и FastAPI: Создание собственного API на Python, Фреймворки и библиотеки Python.


Словарь перед чтением

ТерминПростыми словами
HTTPПротокол "браузер ↔ сервер": метод (GET, POST…), URL, заголовки, тело
RESTСтиль API: ресурсы по URL (/users/1), ответы в JSON, коды статуса 200, 404, 422
JSONТекстовый формат данных: {"title": "задача"} — удобен для фронтенда
ASGIСтандарт "как Python принимает HTTP" для async-серверов (Uvicorn, Hypercorn)
WSGIСтарый синхронный стандарт (Gunicorn + Flask/Django)
ЭндпоинтОдин URL + метод: например GET /health
OpenAPIМашиночитаемое описание всех эндпоинтов; из него рисуют Swagger
PydanticБиблиотека: класс с полями → автоматическая проверка входящего JSON
type hintsАннотации типов в Python: def f(x: int) -> str:

FastAPI опирается на Starlette (маршрутизация, ASGI) и Pydantic (валидация). Вам чаще пишут только FastAPI и модели Pydantic — остальное подключается прозрачно.


Чем FastAPI отличается от Flask и Django

КритерийFlaskDjangoFastAPI
ФокусВеб + API (собираете сами)Полноценные сайты, админкаAPI в первую очередь
ВалидацияВручную или расширенияForms / DRFАннотации + Pydantic
Документация APIВручную / плагиныDRF + drf-spectacularSwagger и ReDoc из коробки
AsyncQuart / отдельные решенияasync views с 4.1+Нативно (ASGI)
АдминкаНетВстроеннаяНет
ORMПодключаете самиВстроенныйSQLAlchemy и др. отдельно

Flask — минимальный каркас — маршрут, request, jsonify. Удобен, когда нужны и HTML-шаблоны, и API — см. Первая программа на Flask.

Django — CMS, auth, админка, ORM, миграции в одном репозитории — см. Django и DRF.

FastAPI выбирают, когда клиент уже отдельное приложение (React, мобильное) и контракт — чистый JSON с автопроверкой типов и живой документацией на /docs.


Как запрос проходит через приложение

  1. Клиент отправляет HTTP-запрос (например POST /notes с телом {"text": "привет"}).
  2. Uvicorn — процесс, который слушает порт 8000 и говорит с Python через ASGI.
  3. FastAPI находит функцию, привязанную к пути /notes и методу POST.
  4. Pydantic превращает JSON в объект Python и проверяет типы (строка не пустая, число ≥ 0 и т.д.).
  5. Ваша функция работает с уже проверенными данными и возвращает dict или модель — FastAPI сериализует в JSON.

Если JSON неверный, до вашей функции выполнение не доходит: клиент получает 422 Unprocessable Entity со списком полей и причин.


Минимальное приложение — разбор по строкам

from fastapi import FastAPI

app = FastAPI(title="Demo API")


@app.get("/health")
def health():
return {"status": "ok"}
СтрокаЧто происходит
FastAPI(...)Создаётся объект приложения; title попадёт в OpenAPI
@app.get("/health")Декоратор: "на GET /health вызывай функцию ниже"
def health():Обычная функция Python — это и есть обработчик (handler)
return {"status": "ok"}Словарь → FastAPI отдаст как JSON с кодом 200

Запуск: uvicorn main:app --reload — модуль main, переменная app. Флаг --reload перезапускает сервер при сохранении файла (только для разработки).


Модели Pydantic — зачем отдельный класс

Базовый обзор библиотеки (входящие данные, схема, EmailStr, pydantic-settings) — Pydantic — валидация входящих данных.

Без Pydantic вы вручную пишете проверки полей в каждом обработчике. С Pydantic описываете ожидаемую форму один раз:

from pydantic import BaseModel, Field


class ItemCreate(BaseModel):
title: str = Field(min_length=1, max_length=200)
done: bool = False

Разбор фрагмента:

  • ItemCreate описывает ожидаемое тело запроса для создания сущности.
  • Field(min_length=1, max_length=200) задаёт валидацию длины заголовка.
  • done: bool = False делает поле необязательным с безопасным значением по умолчанию.

В обработчике:

@app.post("/items")
def create_item(body: ItemCreate):
# body.title уже str, body.done уже bool
...

Разбор фрагмента:

  • body: ItemCreate заставляет FastAPI валидировать и парсить JSON до входа в функцию.
  • Внутри обработчика body уже типизированный объект, а не "сырой" словарь.

BaseModel — базовый класс Pydantic: поля класса = поля JSON.

Field(min_length=1) — ограничение: пустая строка → 422 с понятным сообщением.

done: bool = False — поле необязательное в JSON; если его нет, подставится False.


Зависимости (Depends) — общая логика без копипаста

Повторяющиеся действия выносят в функции и подключают через Depends:

  • открыть сессию БД на один запрос и закрыть в конце;
  • прочитать JWT из заголовка и вернуть имя пользователя;
  • общая пагинация ?skip=0&limit=10.
from fastapi import Depends

def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()


@app.get("/users/{user_id}")
def get_user(user_id: int, db: Session = Depends(get_db)):
return db.get(UserRow, user_id)

Разбор фрагмента:

  • Depends(get_db) подключает зависимость и передаёт сессию БД в обработчик.
  • yield в get_db обеспечивает корректное закрытие сессии после запроса.
  • db.get(...) читает запись по первичному ключу.

yield в зависимости означает — код до yield — подготовка (открыли БД), код после — очистка (закрыли), даже если обработчик упал с ошибкой. Подробнее в FastAPI и база данных.


Документация без отдельного Word-файла

URLНазначение
/docsSwagger UI — список эндпоинтов, кнопка "Try it out"
/redocReDoc — та же схема, другой интерфейс
/openapi.jsonСхема для генераторов клиентов и CI

Схема строится из type hints и моделей Pydantic. Изменили поле в ItemCreate — документация обновилась автоматически.


Экосистема вокруг FastAPI

КомпонентНазначение
uvicornASGI-сервер: слушает порт, вызывает app
SQLAlchemy 2ORM — FastAPI и база данных, Работа с базами данных в Python
AlembicВерсии схемы БД
HTTPXHTTP-клиент для тестов
pytest + TestClientТесты API — Тестирование на pytest

Подробнее: Экосистема Python-приложений.


Синхронные и async обработчики

@app.get("/sync")
def read_sync():
return {"mode": "sync"}


@app.get("/async")
async def read_async():
return {"mode": "async"}

Разбор фрагмента:

  • def создаёт синхронный обработчик для CPU-bound или простых операций.
  • async def подходит для задач с await к сети или async-драйверам.
  • Оба варианта возвращают JSON-ответ, но по-разному работают с event loop.

async def уместен при await к сети или async-БД. Синхронный SQLAlchemy внутри async def без async-драйвера блокирует event loop — см. Асинхронность и многопоточность в Python, FastAPI и база данных.


Когда выбирать FastAPI

Подходит, если нужен чистый JSON API с автодокументацией, type hints, WebSocket/async I/O, связка с React/Vue/мобильным клиентом.

Для учебного сайта с HTML и админкой чаще стартуют с Django или Flask.


Типичные ошибки новичка

СимптомЧто проверить
422 на каждый POSTТело не JSON или поле называется иначе, чем в модели
Пустой /docsUvicorn не запущен или другой модуль app
401 после JWTЗаголовок Authorization: Bearer <token>

Связанные материалы


Границы применимости FastAPI

FastAPI особенно хорошо работает, когда команда поддерживает API-контракт как центральный артефакт продукта — внешние интеграции, мобильные клиенты, микросервисы.

Для контентного сайта с административной панелью чаще быстрее стартовать с Django. Для учебных и гибридных задач (HTML + небольшой API) удобен Flask. Выбор зависит от формы продукта и компетенций команды.


Чек-лист выбора фреймворка

Если на большинство вопросов ответ "да", FastAPI обычно подходит:

  • нужен JSON API с формальной схемой;
  • важна автодокументация /docs;
  • команда работает с type hints;
  • планируются интеграционные тесты и CI;
  • в roadmap есть async-операции и внешние HTTP-вызовы.

Основа по протоколу

Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.