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

Первая программа на FastAPI

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

Play ITЗагрузка интерактивного демо…


Первая программа на FastAPI

Где применяют FastAPI

FastAPI строит REST API на Python 3.10+: аннотации типов и Pydantic проверяют запрос до вашего кода, OpenAPI (/docs) генерируется автоматически.

Flask удобен, когда нужны и шаблоны, и API. FastAPI — когда клиент уже SPA, мобильное приложение или другой сервис и нужен чистый JSON + валидация + async.

МатериалЗачем
FastAPIОбзор и сравнение с Django/Flask
FastAPI и база данныхSQLAlchemy и БД
Асинхронность и многопоточность в Pythonasync/await, выбор модели
Основы asyncio в Pythongather, Task, таймауты

Словарь

ТерминПростыми словами
UvicornПрограмма, слушающая порт 8000 и вызывающая ваш app
Pydantic-модельКласс с полями = ожидаемая форма JSON
422"Данные не прошли проверку" — список полей в detail
JWTПодписанный токен "кто вы" без cookie-сессии
BearerЗаголовок: Authorization: Bearer <токен>
OAuth2PasswordBearer"Логин → токен → доступ к API"

Что получится

ЭтапРезультат
1CRUD заметок в памяти + /docs
2Логин → JWT → защищённые маршруты

Тот же сценарий "Заметки", что в Node 262 и Flask 3411.


Часть 1. API без авторизации

Установка

python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install "fastapi[standard]" uvicorn
mkdir fastapi-notes && cd fastapi-notes

Разбор:

  • venv создаёт изолированное окружение для зависимостей проекта.
  • Активация подключает это окружение в текущей сессии терминала.
  • pip install "fastapi[standard]" uvicorn ставит FastAPI и сервер Uvicorn.
  • Последняя команда формирует отдельную папку для учебного API.
  • Такой старт даёт воспроизводимую среду и убирает влияние глобальных пакетов.

main.py

Код ITЗагрузка примера кода…


Разбор main.py

ЭлементСмысл
_notesХранилище в RAM — пропадёт после перезапуска
NoteCreateТело POST; пустой text → 422
response_model=NoteOutВ JSON только поля модели
status_code=201Ресурс создан
Path(ge=1)id в URL — целое ≥ 1
HTTPException(404)Стандартная ошибка с detail

Запуск

uvicorn main:app --reload

Разбор:

  • main:app указывает путь к объекту приложения (app) в файле main.py.
  • --reload автоматически перезапускает сервер при изменении кода.
  • Этот режим подходит для разработки и не используется в production.
URLНазначение
http://127.0.0.1:8000/docsSwagger — "Try it out"
http://127.0.0.1:8000/redocДокументация
http://127.0.0.1:8000/healthHealthcheck

curl

curl http://127.0.0.1:8000/notes
curl -X POST http://127.0.0.1:8000/notes \
-H "Content-Type: application/json" \
-d '{"text": "Изучить FastAPI"}'
curl -X DELETE http://127.0.0.1:8000/notes/1

Разбор:

  • Первый вызов читает список заметок (GET /notes).
  • Второй создаёт заметку, отправляя JSON в POST /notes.
  • Третий удаляет заметку по id через DELETE /notes/1.
  • Этот набор покрывает базовый CRUD-поток в минимальном API.
  • На этой тройке запросов удобно быстро проверять регрессии в контракте API.

Пустой text422 с полем detail — разбор для фронтенда:

{
"detail": [
{
"loc": ["body", "text"],
"msg": "String should have at least 1 character",
"type": "string_too_short"
}
]
}

Часть 2. JWT-авторизация

Клиент сначала получает токен, затем шлёт Authorization: Bearer ....

JWT — подписанная строка с sub (username) и exp (срок). Сервер проверяет подпись секретом JWT_SECRET.

pip install "python-jose[cryptography]" "passlib[bcrypt]" python-multipart

Разбор:

  • python-jose добавляет работу с JWT (подпись и проверка токенов).
  • passlib[bcrypt] нужен для безопасной проверки и хранения хешей паролей.
  • python-multipart позволяет принимать form-data на эндпоинте /token.
  • Вместе эти пакеты закрывают минимальный auth-сценарий по схеме OAuth2 Password Flow.

auth.py:

Код ITЗагрузка примера кода…

В main.py:

Код ITЗагрузка примера кода…

Добавьте Depends(get_current_user) к POST и DELETE.


Получить токен

curl -X POST http://127.0.0.1:8000/token \
-d "username=demo&password=demo123"

Разбор:

  • Запрос отправляет форму логина в OAuth2-совместимом формате.
  • В ответе приходит access_token, который используют в следующих запросах.
  • Поле token_type обычно равно bearer и подсказывает формат заголовка авторизации.
curl http://127.0.0.1:8000/notes \
-H "Authorization: Bearer ВАШ_ТОКЕН"

Разбор:

  • Заголовок Authorization передаёт bearer-токен в защищённый эндпоинт.
  • Сервер проверяет подпись и срок токена до выполнения бизнес-логики.
  • При невалидном или просроченном токене API возвращает 401.

В Swagger: Authorize → Bearer token.

Безопасность

JWT_SECRET из переменных окружения. Пароли в БД — только хеш. HTTPS в production.


Async


import httpx

@app.get("/time")
async def external_time():
async with httpx.AsyncClient() as client:
r = await client.get("https://worldtimeapi.org/api/timezone/Etc/UTC")
r.raise_for_status()
return r.json()

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


Тест с TestClient

from fastapi.testclient import TestClient
from main import app

client = TestClient(app)


def test_health():
assert client.get("/health").json() == {"status": "ok"}


def test_create_note():
r = client.post("/notes", json={"text": "test"})
assert r.status_code == 201

С JWT — сначала POST /token, затем заголовок. Подробнее: Тестирование на pytest.

pip install pytest
pytest -q

Разбор:

  • pip install pytest подключает тестовый фреймворк.
  • pytest -q запускает автотесты в кратком режиме вывода.
  • Этот запуск удобно включать в pre-commit и CI-пайплайн.
  • Такой baseline снижает риск незаметно сломать базовые маршруты и авторизацию.

Частые ошибки

СимптомПричина
422Тело не прошло Pydantic
401 на /notesНет Authorization: Bearer …
401 на /tokenНеверный логин или не form-urlencoded

Дальше

ТемаМатериал
БДFastAPI и база данных
ОбзорFastAPI
Сравнение APIСоздание собственного API на Python

Как читать путь обучения по FastAPI

Эта статья даёт рабочий старт и первый API-контракт. Для устойчивого уровня добавьте следующие шаги:

  1. Перенесите хранение заметок из памяти в БД — FastAPI и база данных.
  2. Покройте эндпоинты автотестами — Тестирование на pytest.
  3. Разведите код по модулям — routers, schemas, services, repositories.
  4. Добавьте конфигурацию через переменные окружения и .env.

Такой маршрут переводит учебный пример в основу для реального сервиса.


Мини-практикум для закрепления

Сделайте три доработки и проверьте API через /docs:

  • добавьте PUT /notes/{id} для обновления текста;
  • добавьте фильтр GET /notes?limit=10;
  • возвращайте единый формат ошибки для 404 и 422.

После этого сравните результат с реализацией на Flask в Первая программа на Flask: станет видна разница между подходами к валидации и структуре кода.


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

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


В подборках

Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:

Первые шаги (маршрут подборки) — Первая программа на Flask, Первая программа на JavaServer Faces, Первая программа на PyQt6, Первая программа на JavaBean, Первая программа на Tkinter, Первая программа на Spring Framework.