Skip to content

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

api-agent-template — CLI и ИИ-агент для любого REST API

Шаблон проекта: даёте 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).

Быстрый старт: один запрос

  1. Создайте проект из шаблона:
    ~/Documents/api-agent-template/scripts/new-project.sh ~/Documents/my-api-agent
  2. Откройте ~/Documents/my-api-agent в Claude Code и напишите одно сообщение:
    /onboard-api swagger: http://localhost:8080/v3/api-docs
    postman: ~/Downloads/MyApi.postman_collection.json
    environment: ~/Downloads/local.postman_environment.json
    
    Можно своими словами: «подключи мой API, вот swagger и коллекция». Всё, что агент не найдёт сам (адрес стенда, учётки ролей), он спросит одним списком.

Что сделает агент (навык /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 — config/api.json

Всё, чем API отличаются друг от друга, описано здесь; движок читает только профиль. ./api init заполняет черновик, /onboard-api проверяет его запросами. Незаданные поля берут значения по умолчанию из apicli/config.py.

{
  "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
}

Типы авторизации:

  • 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.

Карточка ручки — project/knowledge.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.

Когда API меняется

  • Новая или изменённая ручка: «появилась ручка …» → навык /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 .

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages