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é.
This commit is contained in:
Johan LEROY
2026-09-16 12:04:32 +02:00
18 changed files with 664 additions and 78 deletions
+3 -1
View File
@@ -27,7 +27,9 @@ async def liveness(settings: SettingsDep) -> LivenessStatus:
async def readiness(session: SessionDep) -> ReadinessStatus:
try:
version: str | None = await session.scalar(TIMESCALEDB_VERSION)
except SQLAlchemyError, OSError:
# `# 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,
@@ -0,0 +1,36 @@
from fastapi import APIRouter, HTTPException, status
from app.api.deps import LecteurDep, SiteServiceDep
from app.api.openapi import REPONSE_VALIDATION, Reponses
from app.schemas.errors import ErrorResponse
from app.schemas.site import SiteResponse
from app.services.site import SiteNotFoundError
router = APIRouter()
REPONSES_INTROUVABLE: Reponses = {
**REPONSE_VALIDATION,
404: {"model": ErrorResponse, "description": "Aucun site ne porte cet identifiant."},
}
@router.get("", response_model=list[SiteResponse], summary="Liste les sites")
async def list_sites(_: LecteurDep, service: SiteServiceDep) -> list[SiteResponse]:
sites = await service.list_all()
return [SiteResponse.model_validate(site) for site in sites]
@router.get(
"/{site_id}",
response_model=SiteResponse,
summary="Décrit un site",
responses=REPONSES_INTROUVABLE,
)
async def get_site(site_id: str, _: LecteurDep, service: SiteServiceDep) -> SiteResponse:
try:
site = await service.get_by_id(site_id)
except SiteNotFoundError as erreur:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Site introuvable"
) from erreur
return SiteResponse.model_validate(site)
+3 -2
View File
@@ -1,9 +1,10 @@
from fastapi import APIRouter
from app.api.openapi import REPONSE_SERVEUR, REPONSES_ADMIN
from app.api.v1.endpoints import auth, health, users
from app.api.openapi import REPONSE_SERVEUR, REPONSES_ADMIN, REPONSES_LECTEUR
from app.api.v1.endpoints import auth, health, sites, users
api_router = APIRouter(responses=REPONSE_SERVEUR)
api_router.include_router(health.router, prefix="/health", tags=["health"])
api_router.include_router(auth.router, prefix="/auth", tags=["auth"])
api_router.include_router(users.router, prefix="/users", tags=["users"], responses=REPONSES_ADMIN)
api_router.include_router(sites.router, prefix="/sites", tags=["sites"], responses=REPONSES_LECTEUR)