раздел 05 · шаг 2/7
Шаг 2. FastAPI + SQLite
Поднимаем бэкенд. SQLAlchemy 2.0 в async-режиме, SQLite как лёгкая БД для локалки, базовый CRUD над задачами. На этом шаге работаем почти исключительно через Claude - он пишет код, мы запускаем.
Что делаем
- Один большой промпт Claude - получаем готовый бэкенд
- Запускаем
uvicorn, проверяем/docs - Через Swagger UI создаём первую задачу
- Коммитим
Промпт для Claude
Скопируйте этот текст в чат Claude Code (вы должны быть в корне проекта):
Создай FastAPI приложение в backend/ со следующим:
- SQLAlchemy 2.0 + SQLite, async-режим (aiosqlite)
- Модель Task: id (int, PK, autoincrement), title (str, до 200 символов),
category (str, default "other"), done (bool, default false),
created_at (datetime, server_default=now())
- Pydantic v2 схемы для запросов/ответов:
TaskCreate (title), TaskUpdate (title?, category?, done?), TaskRead (все поля)
- CRUD endpoints:
GET /api/tasks - список, сортировка по created_at desc
POST /api/tasks - создать (только title в теле)
PATCH /api/tasks/{id} - частичное обновление
DELETE /api/tasks/{id} - удалить
- CORS middleware: разрешить http://localhost:5173
- Структура: app/main.py, app/db.py, app/models.py, app/schemas.py, app/routers/tasks.py
- requirements.txt со всеми зависимостями
- Базовый pytest-сетап в tests/ с conftest.py (фикстура async client + тестовая БД in-memory)
- Один smoke-тест: POST /api/tasks с валидным title возвращает 201
- Запиши команды запуска в README.md в корне проекта
Используй современный async-стиль FastAPI: lifespan вместо on_event,
AsyncSession, async def роуты, async фикстуры в pytest.
Что Claude создаст
Структура после генерации:
backend/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI app + lifespan + CORS
│ ├── db.py # async engine, async session
│ ├── models.py # Task SQLAlchemy model
│ ├── schemas.py # TaskCreate, TaskUpdate, TaskRead
│ └── routers/
│ ├── __init__.py
│ └── tasks.py # CRUD endpoints
├── tests/
│ ├── __init__.py
│ ├── conftest.py # async client fixture, test DB
│ └── test_tasks.py # smoke-тест
├── requirements.txt
└── tasks.db # появится после первого запуска
requirements.txt будет примерно таким:
fastapi>=0.115
uvicorn[standard]>=0.32
sqlalchemy>=2.0
aiosqlite>=0.20
pydantic>=2.9
pytest>=8.0
pytest-asyncio>=0.24
httpx>=0.27
Устанавливаем зависимости
source venv/bin/activate
cd backend
pip install -r requirements.txt
Запуск
# из папки backend/, venv активен
uvicorn app.main:app --reload --port 8000
В логах должно быть что-то такое:
INFO: Uvicorn running on http://127.0.0.1:8000
INFO: Application startup complete.
Проверка
Откройте в браузере: http://localhost:8000/docs
Это автоматический Swagger UI. Через него можно вызвать любой endpoint без curl.
Проверьте создание задачи:
- Раскройте
POST /api/tasks - Нажмите "Try it out"
- В теле:
{ "title": "купить молоко" } - Execute
Должен вернуться 201 Created и JSON с id, title, category: "other", done: false, created_at.
Затем GET /api/tasks - в ответе массив с одной задачей.
Запуск тестов
cd backend
pytest -v
Должен пройти хотя бы один тест (POST /api/tasks возвращает 201). Если фейлится - копируйте лог в Claude, он поправит.
Возможные проблемы
- "no module named 'aiosqlite'" - не активировали venv или не сделали
pip install - "address already in use" - порт 8000 занят. Запустите на другом:
--port 8001(и поправьте фронт потом) - pytest падает с "event loop" - в
conftest.pyдолжно бытьasyncio_mode = "auto"(вpytest.iniилиpyproject.toml)
Точка сохранения
cd .. # вернуться в корень проекта
git add .
git commit -m "step 2: FastAPI backend with SQLite, CRUD for tasks"
Полезные ссылки
- FastAPI docs - официальная документация
- SQLAlchemy 2.0 async - async ORM
- Pydantic v2 migration - синтаксис v2