# retoor from __future__ import annotations import asyncio import time from fastapi import APIRouter from devplacepy_services.base.config import service_url from devplacepy_services.base.http import internal_request from devplacepy_services.base.schemas import HealthOut, HealthStatsOut from devplacepy_services.base.service import BaseMicroservice from devplacepy_services.base.stats import COUNTERS async def _dep_status(name: str) -> str: url = f"{service_url(name)}/health" try: response = await internal_request("GET", url, timeout=2.0) if response.status_code == 200: payload = response.json() if payload.get("status") == "ok": return "ok" return "degraded" return "down" except Exception: return "down" def health_router(service: BaseMicroservice) -> APIRouter: router = APIRouter() @router.get("/health", response_model=HealthOut) async def health() -> HealthOut: deps: dict[str, str] = {} if service.depends_on: results = await asyncio.gather( *[_dep_status(dep) for dep in service.depends_on] ) for dep_name, status in zip(service.depends_on, results, strict=True): deps[dep_name] = status overall = "ok" if deps and any(status != "ok" for status in deps.values()): overall = "degraded" uptime_s = int(time.monotonic() - service.started_at) stats = COUNTERS.snapshot() return HealthOut( service=service.name, status=overall, uptime_s=uptime_s, version=service.version, deps=deps, stats=HealthStatsOut(requests=stats["requests"], errors=stats["errors"]), ) return router