feat(api): роутеры API v1 и WebSocket-поток метрик (Refs #19)
contract-openapi / openapi-contract (push) Has been cancelled
contract-openapi / ts-client-is-current (push) Has been cancelled

- ops: health/ready/metrics без аутентификации (503 = схема Error).
- auth: login/logout/session, cookie-сессия + CSRF-токен.
- status/config/routing/devices+logs: все эндпоинты контракта.
- ws/metrics: /api/v1/metrics/stream, токен в заголовке или query.
This commit is contained in:
2026-10-22 00:21:56 +03:00
parent 839f773010
commit 7d9cf8ca5e
9 changed files with 258 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
"""Служебные эндпоинты: /api/v1/health, /api/v1/ready, /metrics (без аутентификации)."""
from __future__ import annotations
from typing import Any
from fastapi import APIRouter
from fastapi.responses import JSONResponse, PlainTextResponse
from awg_api.deps import StateDep
from awg_api.errors import error_payload
router = APIRouter(tags=["ops"])
@router.get("/api/v1/health")
async def get_health(state: StateDep) -> dict[str, Any]:
return state.get_health()
@router.get("/api/v1/ready")
async def get_ready(state: StateDep) -> JSONResponse:
if state.ready:
return JSONResponse(status_code=200, content=state.get_ready())
checks = state.get_ready()["checks"]
return JSONResponse(
status_code=503,
content=error_payload(
"agent_unavailable", "Шлюз не готов обслуживать запросы", {"checks": checks}
),
)
@router.get("/metrics", response_class=PlainTextResponse)
async def get_prometheus_metrics(state: StateDep) -> PlainTextResponse:
return PlainTextResponse(state.prometheus_text())