Зачем нужен FastAPI, сравнение с Flask и Django REST Framework, установка и первые шаги
FastAPI — современный веб-фреймворк для Python, использующий аннотации типов для валидации, документации и внедрения зависимостей. В этой теме вы поймёте, чем FastAPI отличается от альтернатив и когда его стоит выбирать.
Представьте, что вы создаёте API. Вам нужно:
Раньше это означало много шаблонного кода. FastAPI меняет подход.
1. Автоматическая валидация данных
Вместо ручных проверок if 'email' not in data вы объявляете типы, а FastAPI и Pydantic проверяют входные данные во время выполнения:
from pydantic import BaseModel
class UserCreate(BaseModel):
email: str # Обязательно строка
age: int # Обязательно целое число
@app.post('/users')
def create_user(user: UserCreate):
# user.email и user.age уже гарантированно правильных типов
return {'id': 1, **user.model_dump()}Если клиент отправит {"email": 123}, FastAPI автоматически вернёт ошибку 422 с подробным описанием проблемы.
2. Автоматическая документация
FastAPI генерирует интерактивную OpenAPI-документацию из ваших аннотаций типов:
@app.get('/users/{user_id}', response_model=UserResponse)
def get_user(user_id: int):
"""Получить пользователя по ID"""
...Откройте /docs в браузере — и у вас готовый Swagger UI с возможностью тестирования API.
3. Асинхронность на основе ASGI
FastAPI построен на Starlette (асинхронный веб-фреймворк) и Pydantic (валидация данных). Благодаря поддержке async/await и ASGI, FastAPI подходит для большого количества I/O-операций, WebSocket, SSE и долгоживущих соединений.
4. Интуитивный синтаксис
from fastapi import FastAPI
app = FastAPI()
@app.get('/')
def read_root():
return {'Hello': 'World'}Это весь код для создания работающего API.
Python остаётся динамически типизированным языком — сам интерпретатор не обеспечивает соблюдение аннотаций. FastAPI активно использует аннотации типов Python: на их основе FastAPI и Pydantic выполняют обработку и валидацию данных во время выполнения, а внешние анализаторы (Pyright, mypy, IDE) могут проверять код статически.
| Flask | FastAPI |
|---|---|
| Аннотации типов необязательны и обычно не определяют поведение фреймворка | Аннотации являются важной частью объявления API, валидации и документации |
| Критерий | Flask | FastAPI |
|---|---|---|
| Валидация | Ручная или через расширения (marshmallow, Pydantic) | Встроенная через Pydantic |
| Документация | Требует расширений (flask-openapi, connexion) | Автоматическая OpenAPI |
| Асинхронность | Ограниченная (Flask 2.0+) | Полноценная async/await через ASGI |
| Типизация | Аннотации необязательны | Аннотации — основа API, валидации и документации |
Когда Flask:
Когда FastAPI:
| Критерий | DRF | FastAPI |
|---|---|---|
| Экосистема | Полная (ORM, админка, аутентификация) | Минимальная (только API) |
| Сложность | Высокая, много абстракций | Низкая, явный код |
| Асинхронность | Ограниченная | Полноценная async/await |
Когда DRF:
Когда FastAPI:
| Ситуация | Обычно рациональный выбор |
|---|---|
| Уже есть Django, ORM, admin и модель пользователей | Django REST Framework |
| Небольшое приложение со зрелой Flask-экосистемой | Flask |
| Новый типизированный API, OpenAPI, async-интеграции | FastAPI |
| Основная сложность — бизнес-модель и admin-интерфейс | Django/DRF |
| Нужны WebSocket, SSE, большое число I/O-операций | ASGI-фреймворк (FastAPI и др.) |
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# или
.venv\Scripts\activate # WindowsАктуальный способ из официальной документации:
python -m pip install "fastapi[standard]"fastapi[standard] включает Uvicorn с дополнительными зависимостями (uvloop, httptools, watchfiles, websockets).
fastapi dev main.pyFastAPI CLI запускает приложение через ASGI-сервер (Uvicorn) с автоперезагрузкой.
Для production:
fastapi run main.pyuvicorn main:app --reloadmain — имя файла (main.py)app — переменная с приложением--reload — автоперезагрузка при измененияхОба способа запускают одно и то же ASGI-приложение. FastAPI CLI — рекомендуемый путь в актуальной документации.
python -c "import fastapi; print(fastapi.__version__)"Откройте http://localhost:8000/docs — и вы увидите готовую документацию!
ASGI (Asynchronous Server Gateway Interface) — спецификация, которая поддерживает асинхронный обмен сообщениями между сервером и приложением.
До ASGI был WSGI (Web Server Gateway Interface) — синхронный интерфейс приложения. WSGI не означает, что запросы всегда выполняются строго один за другим: сервер может обрабатывать их конкурентно через несколько процессов, потоков или специальные worker-модели. Но WSGI задаёт синхронный интерфейс самого приложения, что ограничивает работу с долгоживущими соединениями и WebSocket.
ASGI подходит для:
async даёт конкурентность во время ожидания сети или базы данных, но не превращает CPU-bound Python-код в параллельный. Для использования нескольких ядер процессора нужны несколько workers.
def, а когда async def| Ситуация | Рекомендация |
|---|---|
| Используемые библиотеки предоставляют асинхронный API | async def |
| Вызывается синхронный код | обычный def (FastAPI выполнит в пуле потоков) |
Нужно вызвать блокирующий клиент (например requests) внутри async def | Вынести работу в отдельный поток или использовать асинхронный клиент (httpx) |
| Нужно использовать несколько ядер процессора | Запустить несколько workers |
Нельзя вызывать блокирующий код вроде requests.get(...) внутри async def без вынесения работы — это заблокирует event loop для всех остальных запросов.
FastAPI состоит из трёх ключевых компонентов:
┌─────────────────────────────────────────┐
│ FastAPI App │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ Starlette │ │ Pydantic │ │
│ │ (роутинг, │ │ (валидация, │ │
│ │ middleware, │ │ сериализация) │ │
│ │ WebSocket) │ │ │ │
│ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────┘
↓
┌───────────┐
│ Uvicorn │
│ (ASGI │
│ сервер) │
└───────────┘
Вместо готовых цифр производительности проведите собственный эксперимент. Создайте четыре эндпоинта:
return {"ok": True})asyncio.sleep)Запустите бенчмарк (например, wrk или hey) с одним и несколькими workers.
Вопросы для анализа:
async def для CPU-bound задачи?Этот эксперимент одновременно обучает FastAPI, асинхронности и корректному чтению бенчмарков.
Вот полный пример минимального API:
from fastapi import FastAPI
app = FastAPI(
title="My API",
description="Моё первое API",
version="1.0.0"
)
@app.get('/')
def read_root():
return {'message': 'Hello, World!'}
@app.get('/items/{item_id}')
def read_item(item_id: int, q: str | None = None):
return {'item_id': item_id, 'q': q}Запуск:
fastapi dev main.pyДалее: Первые шаги