Перейти к содержанию

HTTP API симулятора

Базовый URL: /api/v1. Ops-эндпоинты без префикса. Формат JSON, snake_case, ошибки {code, severity, path, message} (реестр simulate/contracts/error_codes.yaml).

Запуск

cd simulate
.venv/bin/pip install -e .
# Ключ: переменная SIMULATE_API_KEY, флаг --api-key или автогенерация при старте
export SIMULATE_API_KEY='dev-local-key'
.venv/bin/sim serve --host 127.0.0.1 --port 8080
# Локальная разработка без ключа (в лог — WARN):
# .venv/bin/sim serve --host 127.0.0.1 --port 8080 --no-auth

Статика фронта (simulate/web/dist) монтируется на /, если каталог существует. Для live SPA против защищённого API задайте при сборке VITE_SIM_API_KEY (см. simulate/web/src/config/runtime.ts).

Аутентификация

Защищены все пути /api/v1/*. Публичны без ключа: /healthz, /readyz, /metrics (Prometheus).

Передайте ключ одним из способов:

  • заголовок Authorization: Bearer <key>;
  • заголовок X-Api-Key: <key>.

Источник ключа на сервере: SIMULATE_API_KEY, опция sim serve --api-key, либо ключ, напечатанный при автогенерации на старте. Режим --no-auth отключает проверку (только dev).

Ситуация HTTP code
Сервер без ключа и без --no-auth (явный create_app в тестах) 503 API_KEY_REQUIRED
Запрос без ключа / неверный ключ 401 API_KEY_INVALID

Ops

Метод Путь Ответ
GET /healthz {"status":"ok","version":"<engine_version>"}
GET /readyz {"status":"ok"}
GET /metrics Prometheus text

Во всех ответах заголовок X-Request-Id.

Каталог

GET /api/v1/fleet

Каталог бортов и нагрузок из fleet.yaml / payloads.yaml.

curl -sS -H "Authorization: Bearer ${SIMULATE_API_KEY}" \
  http://127.0.0.1:8080/api/v1/fleet | jq '.fleet.uav | keys[:3]'

GET /api/v1/worlds

Список синтетических миров: world_id, kind, bbox, resolution_m, sha256.

GET /api/v1/worlds/{world_id}

world_manifest.json: слои, CRS, layer_completeness, layers.

Прогоны

POST /api/v1/runs → 202

Тело: {plan, scenario?, world_id, seed, options?, run_id?} или {plan_ref, world_id?, seed?, run_id?} (s01 / fixtures/plans/s01.json). Опциональный run_id (UUID) — идемпотентность каталога; повтор с тем же id → 409 RUN_ID_COLLISION.

curl -sS -D - -X POST http://127.0.0.1:8080/api/v1/runs \
  -H "Authorization: Bearer ${SIMULATE_API_KEY}" \
  -H 'Content-Type: application/json' \
  -d @- <<'EOF'
{"plan_ref":"s01","world_id":"plane_seed_42","seed":42}
EOF

Ответ: {"run_id":"…","status":"queued"}, заголовок Location: /api/v1/runs/{run_id}.

Коды: 400 — мир/вход; 422 — план; 429RUN_QUEUE_FULL; 409 — коллизия run_id (журнал).

GET /api/v1/runs

Список: run_id, status, created_at, world_id, plan_sha256.

GET /api/v1/runs/{run_id}

statusqueued|running|done|failed, manifest, fact_report, preflight_codes, exit_status.

GET /api/v1/runs/{run_id}/telemetry

Параметры: from, to, decimate, uav_id. По умолчанию ≤ 20 000 точек, равномерное прореживание.

GET /api/v1/runs/{run_id}/events

Параметр type — фильтр по полю type.

GET /api/v1/runs/{run_id}/frames

Паспорта кадров; decimate (по умолчанию ≤ 5000). Если кадры не материализованы — status: NOT_COMPUTED, пустой список.

GET /api/v1/runs/{run_id}/coverage

coverage_fraction_actual, сетка GSD, полигоны пропусков (из frames_summary.json, если есть).

GET /api/v1/runs/{run_id}/verdict

Трёхзначный вердикт. По чеклисту §7.2 сейчас всегда UNRESOLVED + blockers.

Валидация и эталоны

POST /api/v1/validate

{plan, scenario}reference (V-1…V-14) и mutants (матрица base).

GET /api/v1/reference

14 строк: id, metric, reference, actual, delta, tolerance, status, source.

OpenAPI

Схема: GET /api/v1/openapi.json. Снимок в репозитории: simulate/contracts/openapi.snapshot.json.

Коды ошибок (выборка)

HTTP code Смысл
404 RUN_NOT_FOUND Нет прогона
422 PLAN_SCHEMA_VERSION_UNSUPPORTED План не проходит импорт/контракт
429 RUN_QUEUE_FULL Очередь прогонов
401 API_KEY_INVALID Нет или неверный ключ
503 API_KEY_REQUIRED Сервер без настроенного ключа
500 INTERNAL_ERROR Внутренняя ошибка