# Python Fastapi API Worker

> Используй при реализации или правке сборки HTTP API-процесса на FastAPI: фабрики приложения, типизированного runtime context, lifespan shared-ресурсов, middleware, logging context запроса, error boundary, health endpoints и запуска через Uvicorn. Не применять для определения HTTP-контрактов, реализации конкретных endpoint-ов и transport-моделей, application/domain-логики, persistence-адаптеров и фоновых worker-ов.

- Skill: `nemagu/python-fastapi-api-worker` (Agent Skill, multi-file: 9 files)
- Install (CLI): `npx skillmds@latest add nemagu/python-fastapi-api-worker`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nemagu/python-fastapi-api-worker/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: Nemagu (https://skillmd.com/u/nemagu)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/nemagu/python-fastapi-api-worker

---


# Сборка API-воркера на FastAPI

## Порядок работы

1. Извлечь заданные runtime-требования и изучить существующую точку сборки.
2. Отделить фабрику ASGI-приложения от запуска процесса.
3. Определить минимальные неизменяемые параметры и зависимости фабрики.
4. Собрать типизированный runtime context через lifespan.
5. Зарегистрировать заданные routers, handlers и middleware в явном порядке.
6. Добавить отдельный entrypoint и настроить режим Uvicorn и graceful shutdown.
7. Проверить startup, shutdown, entrypoint, ошибки, health endpoints и middleware.

Не спрашивать повторно о поведении, однозначно заданном требованиями или кодом.
Задать вопрос только при противоречии, небезопасном решении или выборе, меняющем
публичное поведение.

## Граница ответственности

Скил реализует сборку и жизненный цикл HTTP API-процесса. Он не определяет:

- пути, методы и внешние request/response/error-контракты;
- transport-модели и преобразования в application-контракты;
- бизнес-правила, транзакционные границы и Unit of Work;
- конкретные persistence, broker и другие исходящие адаптеры;
- структуру и источники конфигурации;
- фоновые циклы и message consumers.

Не импортировать domain-ошибки и конкретные infrastructure-реализации в
presentation. Получать application entry points, фабрики ресурсов и
валидированные параметры из composition root.

## Архитектура

Разделить три роли:

```text
configuration -> composition root -> application factory -> ASGI application
                         |
                         +-----------------------> Uvicorn runner
```

- Composition root преобразует внешнюю конфигурацию в минимальные параметры,
  выбирает реализации адаптеров и связывает зависимости.
- Application factory создаёт FastAPI/ASGI-приложение без I/O и открытия
  соединений.
- Lifespan создаёт process-scoped ресурсы и runtime context.
- Runner запускает приложение, но не определяет его маршруты и зависимости.

В новом сервисе использовать `APIWorker` как стандартное имя process-level
сборщика и runner-а. Имена фабрики приложения и runtime context адаптировать к
существующим терминам проекта. При правке существующего сервиса не выполнять
механическое переименование эквивалентных ролей без отдельной задачи.

Подробный вариант: [фабрика приложения](references/application_factory.md).

## Entrypoint API-процесса

В новом сервисе использовать структуру этого репозитория:

- `entrypoints/api.py` содержит import-safe `main()` и защиту
  `if __name__ == "__main__"`;
- `main()` загружает `APIWorkerSettings`, выполняет startup preflight и вызывает
  `APIWorker(settings).run()`;
- `presentation/api/server.py` содержит `APIWorker`, который собирает приложение
  и настраивает Uvicorn;
- фабрика приложения, lifespan, routers и middleware не размещаются в entrypoint;
- импорт entrypoint не читает конфигурацию, не открывает ресурсы, не применяет
  миграции и не запускает сервер.

В существующем проекте сохранять эквивалентную точку входа, если переименование
не входит в задачу.

## Конфигурируемые параметры

Все изменяемые между окружениями параметры получать снаружи:

- host, port, event loop и параметры graceful shutdown;
- количество workers или режим reload;
- root path, OpenAPI и адреса интерфейсов документации;
- CORS, trusted hosts и proxy trust;
- включение и параметры middleware;
- пути health endpoints.

Не передавать всему presentation общий settings-объект. Преобразовать его в
неизменяемые типизированные параметры API и runner-а. Не читать env/YAML и не
создавать module-level settings instance в presentation.

Не передавать `model_dump()` в FastAPI, Uvicorn или middleware. Сопоставлять
каждый параметр с актуальным аргументом клиента явно.

## Фабрика приложения

Фабрика:

- принимает параметры API, lifespan factory, routers, error handlers и
  middleware specifications;
- возвращает новое приложение при каждом вызове;
- не открывает соединения и не выполняет сетевые проверки;
- регистрирует компоненты детерминированно;
- не импортирует глобальный `main_router` и конкретные адаптеры;
- пригодна для тестов, import string и Uvicorn factory mode.

Проверять уникальность route names и operation IDs, а также порядок статических
и параметризованных путей, если это требуется существующей маршрутизацией.

## Жизненный цикл и контекст выполнения

Использовать один lifespan async context manager. Не смешивать его с
`startup`/`shutdown` handlers.

- Создавать обязательные ресурсы до начала приёма запросов.
- Регистрировать освобождение каждого ресурса в `AsyncExitStack` сразу после
  успешного создания.
- При частично неуспешном startup закрывать уже созданные ресурсы.
- На shutdown освобождать ресурсы в обратном порядке.
- Не подавлять startup-ошибку или отмену задачи.
- Не запускать бесконечные background loops внутри API lifespan.

Хранить в `app.state` один неизменяемый типизированный runtime context. Контекст
содержит application entry points, readiness state и только разрешённые
shared-ресурсы через абстрактные контракты. Не помещать туда Unit of Work,
request-scoped объекты или общий settings.

Подробности: [lifespan и контекст](references/lifespan_and_context.md).

## Промежуточное ПО

Состав middleware брать из требований. Для каждой middleware зафиксировать:

- какие scope types она обрабатывает;
- какие данные создаёт и кто их потребляет;
- видит ли она ответы и исключения downstream;
- её место во входящем и исходящем пути;
- безопасный набор логируемых полей.

Для собственных сквозных middleware предпочитать pure ASGI. Использовать
`BaseHTTPMiddleware` только если его ограничения, включая propagation
`contextvars`, приемлемы.

Middleware должна быть stateless: изменяемое состояние хранить локально на
вызов, а конфигурацию задавать в `__init__`.

CORS подключать только по требованиям. Если CORS должен присутствовать и на
ответах необработанных ошибок, обернуть им всё приложение. Не заменять отсутствие
решения разрешающей политикой `*`.

Подробности: [middleware](references/middlewares.md).

## Ошибки и логирование

Presentation обрабатывает:

- публичные application-ошибки;
- транспортные ошибки FastAPI/Pydantic;
- непредвиденные исключения на внешней error boundary.

Не обрабатывать domain-ошибки напрямую. Формат ответа и mapping статусов брать
из HTTP-требований, а не из полей внутреннего исключения.

- Не возвращать stack trace, внутреннее исключение и технические детали.
- Применять `python-service-logging-writing` и logging-профиль HTTP API.
- Создавать request context на внешней middleware до вызова downstream и очищать
  его в `finally`, включая disconnect, timeout, cancellation и исключение.
- Итоговую запись формировать после получения ответа либо безопасного error
  response; измерять полную длительность монотонными часами.
- Непредвиденное исключение логировать ровно один раз с `exc_info` на общей
  error boundary. Итоговая middleware не должна добавлять второй stack trace.
- Передавать из error handlers безопасную классификацию результата, не извлекая
  внутренние исключения повторно.
- Отключать или перенастраивать Uvicorn access/error logs, если они дублируют
  согласованную итоговую запись или stack trace.
- Ожидаемые ошибки логировать только на предусмотренном уровне.
- Передавать request ID через logging context.
- Не логировать authorization, cookies, секреты и произвольные тела.
- Не логировать успешные healthcheck, если профиль прямо этого не требует.

Подробности: [обработка ошибок](references/error_handling.md).

## Проверки состояния

Добавлять проверки только по требованиям:

- liveness подтверждает работу процесса без вызовов внешних систем;
- readiness показывает способность принимать трафик после успешного startup;
- readiness читает дешёвое состояние ресурсов, а не запускает тяжёлую диагностику;
- ответы не раскрывают адреса зависимостей, пути секретов и исключения.

Подробности: [health checks](references/health_checks.md).

## Запуск Uvicorn

Выбрать один режим:

- готовый объект приложения и программный `uvicorn.Server` — один процесс без
  reload;
- import string или application factory — reload либо несколько workers.

Не сочетать готовый объект приложения с параметрами, требующими повторного
импорта или создания приложения в дочернем процессе. Каждый worker создаёт
собственные ресурсы через lifespan.

Доверять forwarded headers только от согласованных proxy IPs. `root_path`,
OpenAPI/docs URLs и proxy trust передавать как явные параметры. Не выводить
scheme, host или client IP из недоверенных заголовков.

Подробности: [запуск Uvicorn](references/uvicorn_runner.md).

## Плавное завершение

- Прекратить приём новых запросов.
- Дать активным запросам конфигурируемое время на завершение.
- После drain закрыть lifespan-ресурсы.
- Продолжать попытку закрытия остальных ресурсов при ошибке отдельного cleanup.
- Сделать cleanup идемпотентным, где повторный вызов возможен.
- Не подавлять cancellation.

## Тестирование

Для wiring-кода не требовать изолированные unit-тесты, если это запрещено
правилами проекта. Интеграционно проверить:

- успешный и частично неуспешный startup;
- освобождение ресурсов и обратный порядок shutdown;
- runtime context;
- порядок и эффекты заданных middleware;
- безопасные application и unexpected error responses;
- отсутствие двойного логирования;
- очистку и изоляцию request context для параллельных запросов;
- обязательные поля, уровни и события logging-профиля;
- liveness/readiness;
- CORS только при его включении;
- сборку выбранного режима Uvicorn без открытия production-порта.
- вызов `main()` с подменёнными loader, preflight и `APIWorker` без открытия порта.

## Антипаттерны

- Создание адаптеров внутри presentation по конкретным классам.
- Передача Unit of Work в endpoint.
- I/O при импорте или создании FastAPI application.
- Module-level application с уже открытыми ресурсами.
- Общий settings в `app.state`.
- Набор неописанных динамических полей `app.state`.
- Одновременное использование lifespan и event handlers.
- Обязательный CORS или разрешающий wildcard без требований.
- Подавление исключений middleware.
- Двойное логирование одной ошибки.
- `BaseHTTPMiddleware` без оценки ограничений.
- Готовый `app` вместе с reload/multi-worker режимом.

## Критерии готовности

- Фабрика приложения отделена от runner-а и не выполняет I/O.
- Зависимости поступают из composition root и не нарушают инверсию.
- Runtime context типизирован и создаётся только в lifespan.
- Частичный startup и shutdown безопасно освобождают ресурсы.
- Middleware и их порядок соответствуют требованиям.
- Ошибки преобразуются безопасно и логируются один раз.
- Режим Uvicorn совместим со способом передачи приложения.
- Отдельный import-safe entrypoint доводит сборку до `APIWorker.run()`.
- Health, proxy, CORS и OpenAPI не включены неявно.
- Согласованные проверки проходят.

## Материалы

- [Фабрика приложения](references/application_factory.md)
- [Жизненный цикл и контекст выполнения](references/lifespan_and_context.md)
- [Промежуточное ПО](references/middlewares.md)
- [Обработка ошибок](references/error_handling.md)
- [Запуск Uvicorn](references/uvicorn_runner.md)
- [Проверки состояния](references/health_checks.md)
- [Чеклист](references/checklists.md)

