Шаблон проекта: даёте swagger и Postman-коллекцию своего API — получаете то же, что было сделано для Demo Shop:
- CLI
./api, который вызывает любую ручку по swagger от имени нужной роли, сам логинится, проверяет тело по схеме, хранит переменные как Postman и печатает correlationId каждого запроса; - агента в Claude Code (
CLAUDE.md+ навыки), который выполняет команды на естественном языке, готовит тестовые данные, анализирует цепочки запросов и оформляет баг-репорты; - автотесты на pytest: базовые проверки каждой ручки генерируются из swagger (401/403, обязательные поля, типы, границы, enum, query-параметры), сценарии Postman переносятся в тесты, в конце прогона — отчёт о покрытии ручек.
Нужен только Python 3.10+ (движок без зависимостей; для тестов — pytest, для YAML-спек — pyyaml).
- Создайте проект из шаблона:
~/Documents/api-agent-template/scripts/new-project.sh ~/Documents/my-api-agent
- Откройте
~/Documents/my-api-agentв Claude Code и напишите одно сообщение:Можно своими словами: «подключи мой API, вот swagger и коллекция». Всё, что агент не найдёт сам (адрес стенда, учётки ролей), он спросит одним списком./onboard-api swagger: http://localhost:8080/v3/api-docs postman: ~/Downloads/MyApi.postman_collection.json environment: ~/Downloads/local.postman_environment.json
Что сделает агент (навык /onboard-api):
| Шаг | Результат |
|---|---|
импорт ./api init |
spec/, черновики профиля config/api.json, окружения config/env.local.json, карточек ручек project/knowledge.py, сжатая коллекция knowledge/postman-digest.md |
| проверка догадок запросами | обёртка ответа, авторизация, коды 401/403/валидации, роли и уровни доступа — подтверждены живым API |
| знания | knowledge/api-notes.md: роли, сущности, статусы, бизнес-правила, цепочки «как получить состояние», расхождения со swagger |
| данные | генераторы ./api data <сущность> в project/factories.py по сценариям коллекции |
| тесты | сценарии Postman → tests/api/test_<группа>.py, базовые проверки всех ручек, прогон, баги — в knowledge/api-audit-*.md |
| отчёт | что подключено, что проверено, что упало, какие вопросы остались |
После этого пишите агенту задачи обычным текстом:
- «Подготовь пользователя с оплаченным заказом из трёх позиций»
- «Проверь, что менеджер не может удалить пользователя, и оформи баг, если может»
- «Какие запросы нужны, чтобы вернуть заказ? От какой роли каждый?»
- «Прогони тесты заказов и покажи, что упало»
- «Появилась ручка POST /reviews, вот swagger — добавь её» (навык
/add-endpoint)
python3 -m venv .venv && .venv/bin/pip install -r requirements-dev.txt
./api init --openapi spec.yaml --postman collection.json [--postman-env env.json] [--base-url http://localhost:8080]
cat knowledge/import-report.md # что угадано и что проверить
$EDITOR config/api.json config/env.local.json project/knowledge.py
./api status # API жив, роли авторизуются
./api data bootstrap # по актору на роль
./api run auto_base # базовые проверки всех ручек--openapi и --postman принимают файл или URL; swagger — JSON или YAML, OpenAPI 3.x или Swagger 2.0;
Postman — коллекция v2.1. Можно без коллекции (только swagger) — тогда меньше догадок о ролях и кодах ошибок.
Повторный ./api init обновляет spec и digest, но не трогает уже проверенные файлы (без маркера @stub);
--force перезаписывает всё.
| Команда | Что делает |
|---|---|
./api init --openapi … --postman … |
импорт swagger и коллекции, черновики профиля, окружения, знаний |
./api status |
API жив, операций и карточек, авторизуется ли каждый актор |
./api ops [--tag X] |
все операции swagger с доступом и ролями |
./api describe <op> |
параметры, схема тела, доступ, предусловия, коды ошибок, пример вызова |
./api errors |
коды ошибок и графы статусов (project/knowledge.py) |
./api op <op> k=v … [--as ROLE] |
вызвать операцию; k=v сам попадает в path, query, header или тело |
./api call METHOD /path … |
произвольный запрос |
./api data bootstrap | user | <сущность> |
тестовые данные (генераторы проекта — ./api data --help) |
./api run [наборы] [-k имя] [-m маркер] [--report junit.xml] |
автотесты pytest, см. tests/README.md |
./api actors [add|login|rm] |
учётки, от имени которых идут запросы |
./api vars [get|set|unset] |
переменные, аналог collection variables |
./api history [--errors] |
журнал запросов с correlationId |
./api spec diff|sync [файл|URL], ./api spec merge <фрагмент> |
сверить или обновить snapshot swagger |
./api money 649000 1990₽ |
минимальные единицы ↔ основные (если настроено money) |
Примеры:
./api op create-user email={{$uuid}}@x.test role=manager --as admin --save mgr=id
./api op get-order order_id={{order}} --as customer --data
./api op ship-order order_id={{order}} --as customer --expect 403
./api op create-item price=100 name=a --no-validate --expect 400 # негативный тест схемы
./api call GET /internal/metrics -H 'X-Debug: 1' --as adminКоды выхода: 0 — успех или --expect выполнен, 1 — ошибка API, 2 — ошибка ввода или валидации, 3 — API недоступен.
api запускалка (python3 -m apicli)
apicli/ ДВИЖОК — общий для любого API, при подключении не меняется
cli.py команды и разбор аргументов
client.py HTTP, авторизация по профилю, автологин, повтор при 401, разбор обёртки, история
spec.py операции из swagger (OpenAPI 3 / Swagger 2), валидатор тел по JSON Schema
importer.py ./api init: разбор swagger и Postman, эвристики профиля, черновики
factories.py база генераторов: пользователи ролей, вызов операций по id
knowledge.py, config.py доступ к карточкам ручек, профиль и окружение
config/
api.json ПРОФИЛЬ API (см. ниже)
env.example.json пример окружения; env.<имя>.json — адрес и учётки (в git не попадают)
project/ СЛОЙ API
knowledge.py карточки ручек: доступ, актор по умолчанию, предусловия, коды ошибок; ERROR_CODES, FLOWS
factories.py генераторы сущностей и подкоманды ./api data
knowledge/ знания для агента: api-notes.md, postman-digest.md, import-report.md, api-audit-*.md
spec/ snapshot swagger и исходная Postman-коллекция
tests/ автотесты: api/ (pytest), unit/ (офлайн), BASE_CHECKS.md (чек-лист)
.claude/skills/ навыки агента: onboard-api, api-call, test-data, api-analyze, api-test, add-endpoint
scripts/new-project.sh новый проект из шаблона
Состояние CLI — в .api/ (акторы с токенами, переменные, история; в git не попадает).
./api state reset очищает его, данные в API не меняются. Окружение: API_ENV=stage → config/env.stage.json;
отдельные поля переопределяются переменными API_BASE_URL, API_SLOW_RESPONSE_MS, API_<РОЛЬ>_PASSWORD,
API_<РОЛЬ>_TOKEN (удобно для CI).
Всё, чем API отличаются друг от друга, описано здесь; движок читает только профиль. ./api init заполняет черновик,
/onboard-api проверяет его запросами. Незаданные поля берут значения по умолчанию из apicli/config.py.
Типы авторизации:
login— логин запросом, токен в заголовке; автологин, продление за минуту до истечения, повтор приretryStatus; OAuth2 password flow —login.form: true,tokenPath: "access_token",expiresInPath: "expires_in";static— готовые токены ролей:accounts.<роль>.tokenв окружении;basic—accounts.<роль>.login/password,scheme: "Basic";apiKey—accounts.<роль>.apiKey,header: "X-API-Key",scheme: "";none— без авторизации.
Учётки ролей — в config/env.local.json → accounts: {"admin": {"login": "...", "password": "..."}}. Роли без
учёток создаются рецептом users.create или методом create_user в project/factories.py.
"create-order": {"access": "customer", "default": "customer", "pre": "в корзине есть товары",
"errors": ["cart.empty", "orders.out_of_stock"], "notes": "резервирует остаток",
"untestable": {"orders.expired": "нужен перезапуск API"}, "example": {"address": "..."},
"planned": False, "skipAuto": None},access — обязательно (по нему генерируются тесты 401/403), остальное — по необходимости.
./api describe <op> показывает карточку вместе со схемой из swagger.
- Новая или изменённая ручка: «появилась ручка …» → навык
/add-endpoint(spec diff/sync или merge фрагмента, карточка, знания, тесты по tests/BASE_CHECKS.md). - Большое обновление swagger:
./api spec diff <URL|файл>покажет добавленные и удалённые операции и операции без карточек. - Чек-лист базовых проверок редактируйте в tests/BASE_CHECKS.md — агент следует текущей версии.
- Тесты создают данные в API. Подключайте тестовый стенд, не прод.
- Эвристики импорта опираются на Postman: проверки статусов (
pm.response.to.have.status), коды ошибок вpm.expect(...).to.eql('...'), переменные<роль>Token/Email/Password,noauthу публичных запросов. Чем подробнее коллекция, тем точнее черновик. Всё угаданное агент перепроверяет запросами. - Не поддерживаются из коробки: GraphQL, multipart-загрузка файлов (используйте
./api callс--body), подпись запросов (HMAC) — для неё добавьте тип авторизации вapicli/client.py. - Офлайн-тесты движка:
python3 -m unittest discover -s tests/unit -t .
{ "name": "My API", "basePath": null, // префикс от хоста; null — из swagger (servers[0] / basePath) "apiPrefix": "/api/v1", // в тестах можно писать api.get("/users") "healthPath": "/health", // для ./api status и test_contract "openapiPath": "/openapi.json", // откуда ./api spec diff|sync берёт свежий swagger "operationIds": "auto", // auto | summary | operationId — из чего строить id операций "response": { // обёртка ответа; null — нет такого поля "successField": "success", // null → успех = HTTP 2xx "dataPath": "data", // null → данные = всё тело "errorCodePath": "error.code", "errorMessagePath": "error.message", "correlationIdPath": "meta.correlationId", "correlationIdHeader": "x-request-id" }, "auth": { "type": "login", // none | login | static | basic | apiKey "header": "Authorization", "scheme": "Bearer", "login": { // для type=login "method": "POST", "path": "/api/v1/auth/login", "form": false, "body": {"email": "{{login}}", "password": "{{password}}"}, "tokenPath": "data.token", "expiresAtPath": "data.expiresAt", "expiresInPath": null, "fields": {"uuid": "data.user.id", "role": "data.user.role"} }, "tokenTtlSeconds": 3600, "retryStatus": 401, "retryCodes": [] }, "roles": ["admin", "manager", "customer"], "users": { // как создать пользователя роли (./api data user, фикстуры тестов) "loginTemplate": "qa.{name}.{stamp}@example.test", "idPath": "id", "create": { "customer": {"op": "register", "as": "guest", "body": {"email": "{{login}}", "password": "{{password}}"}}, "manager": {"op": "create-user", "as": "admin", "body": {"email": "{{login}}", "password": "{{password}}", "role": "{{role}}"}} } }, "access": { // уровни доступа для карточек ручек и автотестов 401/403 "levels": {"public": [], "auth": ["*"], "admin": ["admin"], "staff": ["manager", "admin"], "customer": ["customer"]}, "missingToken": {"status": 401, "code": "auth.missing_token"}, "invalidToken": {"status": 401, "code": "auth.invalid_token"}, "denied": {"status": 403, "code": null, "codes": {"admin": "auth.admin_required", "staff": "auth.staff_required"}} }, "validation": {"status": 400, "code": "validation.failed", "fieldInMessage": "{location}.{field}"}, "money": {"scale": 100, "symbol": "₽", "aliases": ["р", "руб"]} // или null }