Files
ENI-projet-piscine/apps/backend/app/api/v1/endpoints/health.py
T
Johan LEROY 12c5cf87ad Merge branch 'dev' into feat/openapi-contrat
Complète le contrat OpenAPI de GET /sites et GET /sites/{site_id} (merges depuis dev via #78) :
tag sites décrit, REPONSES_LECTEUR (401 + 403 mot de passe provisoire) posée au niveau du
routeur, 404 et 422 documentés sur la route detail. openapi.json régénéré.
2026-09-16 12:04:32 +02:00

48 lines
1.8 KiB
Python

from fastapi import APIRouter, HTTPException, status
from sqlalchemy import text
from sqlalchemy.exc import SQLAlchemyError
from app.api.deps import SessionDep, SettingsDep
from app.api.openapi import REPONSE_INDISPONIBLE
from app.core.logging import get_logger
from app.schemas.health import LivenessStatus, ReadinessStatus
logger = get_logger(__name__)
router = APIRouter()
TIMESCALEDB_VERSION = text("SELECT extversion FROM pg_extension WHERE extname = 'timescaledb'")
@router.get("/live", summary="Sonde de vivacité")
async def liveness(settings: SettingsDep) -> LivenessStatus:
return LivenessStatus(
status="ok",
service=settings.name,
version=settings.version,
environment=settings.env,
)
@router.get("/ready", summary="Sonde de disponibilité", responses=REPONSE_INDISPONIBLE)
async def readiness(session: SessionDep) -> ReadinessStatus:
try:
version: str | None = await session.scalar(TIMESCALEDB_VERSION)
# `# fmt: skip` contourne un bug de ruff format 0.16.7 : il retire les parenthèses de ce
# `except` à deux types, ce qui produit une syntaxe invalide (`except A, B:`).
except (SQLAlchemyError, OSError): # fmt: skip
logger.exception("Base de données injoignable")
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Base de données injoignable",
) from None
if version is None:
logger.error("Extension TimescaleDB absente de la base")
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Extension TimescaleDB absente",
)
logger.debug("Extension TimescaleDB en version %s", version)
return ReadinessStatus(status="ready", database="reachable", timescaledb="loaded")