From d2bcb4f1f832c9c5f437d210a2f0d8f789ba243a Mon Sep 17 00:00:00 2001 From: Leopoldadmin Date: Wed, 3 Jun 2026 23:52:13 +0000 Subject: [PATCH] Upload app/api/v1/health.py --- app/api/v1/health.py | 69 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 app/api/v1/health.py diff --git a/app/api/v1/health.py b/app/api/v1/health.py new file mode 100644 index 0000000..53d615a --- /dev/null +++ b/app/api/v1/health.py @@ -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__, + }