""" Health Controller Provides service health and information endpoints """ from fastapi import APIRouter, Response from fastapi.responses import JSONResponse from src.shared.base import BaseController from src.shared.config import get_settings from src.shared.logging import get_logger from src.shared.database import get_database logger = get_logger(__name__) class HealthController(BaseController): """ Controller for service health and information Provides endpoints for: - Service information and status - Health checks """ def __init__(self): super().__init__(prefix="", tags=["Health"]) def create_router(self) -> APIRouter: """Create and configure the router""" router = APIRouter(tags=self.tags) settings = get_settings() @router.get( "/", summary="Service information", response_class=JSONResponse ) async def root(): """ Get service information and health status Returns basic information about the API service and available endpoints. """ logger.debug("Root endpoint accessed") return { "service": settings.app_name, "version": settings.app_version, "status": "healthy", "docs": "/docs" } @router.get( "/health", summary="Health check", response_class=JSONResponse ) async def health_check(): """ Fast health check endpoint for container orchestration Returns a 200 OK immediately if the service is running. Does NOT check backend connectivity (use /health/full for that). Used by Docker, Kubernetes, and load balancers for liveness probes. """ return { "status": "healthy", "version": settings.app_version } @router.get( "/health/full", summary="Full health check with database", ) async def full_health_check(response: Response): """ Health check including database connectivity. Returns 200 OK if database is available, otherwise 503. """ import time start_time = time.time() # Check database connection database = get_database() db_healthy = False db_error = None try: db_healthy = await database.health_check() except Exception as e: db_error = str(e) logger.warning(f"Database health check failed: {db_error}") elapsed_ms = int((time.time() - start_time) * 1000) status_code = 200 if db_healthy else 503 response.status_code = status_code return { "status": "healthy" if db_healthy else "unhealthy", "status_code": status_code, "response_time_ms": elapsed_ms, "components": { "database": { "status": "healthy" if db_healthy else "unhealthy", "error": db_error } } } @router.get( "/health/diagnostics", summary="Detailed system diagnostics", ) async def diagnostics(): """ System diagnostics with service information. """ import time start_time = time.time() diagnostics = { "timestamp": time.time(), "service": { "name": settings.app_name, "version": settings.app_version, "purpose": "Infrastructure management and tools API" }, "configuration": { "cors_origins": settings.cors_origins[:2] if len(settings.cors_origins) > 2 else settings.cors_origins } } elapsed_ms = int((time.time() - start_time) * 1000) diagnostics["response_time_ms"] = elapsed_ms return diagnostics return router # Create controller instance health_controller = HealthController()