Coverage for server / routes / common / health.py: 100%
9 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-10-04 09:33 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-10-04 09:33 +0000
1"""
2Readiness probe — GET /v1/health/ready.
4Companion to the two LIVENESS endpoints (`/health`, `/v1/health`), which answer
5a static literal and are deliberately left alone: the deploy workflow points
6HEALTH_ENDPOINT at /v1/health and rolls back when it fails, so coupling that to
7MongoDB would let a transient database blip roll back a good deploy.
9This endpoint answers the other question — can the process actually serve? — and
10says so with the status code, so anything that polls it needs no body parsing:
12 200 {"status": "ready", "dependencies": {"mongodb": "up"}}
13 503 {"status": "not ready", "dependencies": {"mongodb": "down"}}
15Unauthenticated, like the liveness probes, because a probe that needs a token is
16no use to a load balancer. That is also why the body names dependencies and
17their state and nothing else — no connection strings, hostnames, driver
18messages or stack traces.
20JIRA / Zephyr: EI-T419 / EI-T421 (Edge_System_Health — the probe reflects a
21downstream dependency outage)
22Developer: Allan Ninal
23Date: 2026-09-21
24"""
26from fastapi import APIRouter, Response, status
28from server.connection.database import client as mongo_client
29from server.utilities.readiness import check_dependencies
31router = APIRouter()
34@router.get(
35 "/ready",
36 tags=["Server Health Check"],
37 summary="Check whether the server can serve requests",
38 description=(
39 "Readiness probe. Answers 200 when every dependency is reachable and "
40 "503 when one is not, so a caller can rely on the status code alone. "
41 "Unauthenticated, and deliberately discloses nothing beyond each "
42 "dependency name and whether it is up."
43 ),
44 responses={
45 200: {"description": "Every dependency is reachable"},
46 503: {"description": "At least one dependency is unreachable"},
47 },
48)
49async def readiness(response: Response) -> dict:
50 ready, dependencies = await check_dependencies(mongo_client)
51 response.status_code = (
52 status.HTTP_200_OK if ready else status.HTTP_503_SERVICE_UNAVAILABLE
53 )
54 return {"status": "ready" if ready else "not ready", "dependencies": dependencies}