Upload app/api/v1/health.py
This commit is contained in:
@@ -0,0 +1,69 @@
|
|||||||
|
"""Health check endpoints: /health (root) and /api/v1/health."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
from sqlalchemy import text
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from app import __version__
|
||||||
|
from app.core.db import get_db
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
router = APIRouter(tags=["health"])
|
||||||
|
|
||||||
|
|
||||||
|
async def _check_db(db: AsyncSession) -> bool:
|
||||||
|
"""Run SELECT 1 to verify the database connection is alive."""
|
||||||
|
try:
|
||||||
|
result = await db.execute(text("SELECT 1"))
|
||||||
|
result.scalar_one()
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Database health check failed: %s", e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"/health",
|
||||||
|
summary="Healthcheck (used by Coolify + Kubernetes)",
|
||||||
|
)
|
||||||
|
async def health(
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
) -> dict:
|
||||||
|
"""Returns 200 if the API and DB are healthy, 503 if the DB is down."""
|
||||||
|
db_ok = await _check_db(db)
|
||||||
|
if not db_ok:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||||
|
detail={"status": "error", "db": "down"},
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"status": "ok",
|
||||||
|
"db": "ok",
|
||||||
|
"version": __version__,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"/api/v1/health",
|
||||||
|
summary="Versioned healthcheck (for clients that hit /api/v1/*)",
|
||||||
|
)
|
||||||
|
async def api_v1_health(
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
) -> dict:
|
||||||
|
"""Same as /health but under the /api/v1 prefix for versioned routing."""
|
||||||
|
db_ok = await _check_db(db)
|
||||||
|
if not db_ok:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||||
|
detail={"status": "error", "db": "down"},
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"status": "ok",
|
||||||
|
"db": "ok",
|
||||||
|
"version": __version__,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user