"""Professional health check endpoints.""" import time import logging import sys from typing import Optional from datetime import datetime from fastapi import APIRouter, Request from pydantic import BaseModel, Field logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/v1/health", tags=["Health"]) start_time = time.time() class HealthResponse(BaseModel): """Health check response model.""" status: str = Field(..., description="Service status") uptime_seconds: float = Field(..., description="Service uptime in seconds") version: str = Field("2.0.0", description="API version") timestamp: str = Field(..., description="Health check timestamp (ISO 8601)") request_id: Optional[str] = Field(None, description="Request ID for tracing") @router.get("/", response_model=HealthResponse) async def health_check(request: Request): """ Health check endpoint. Returns the current health status of the API service including: - Service status (healthy/unhealthy) - Uptime in seconds - API version - Timestamp """ try: uptime = time.time() - start_time request_id = getattr(request.state, "request_id", None) return HealthResponse( status="healthy", uptime_seconds=round(uptime, 2), version="2.0.0", timestamp=datetime.utcnow().isoformat() + "Z", request_id=request_id ) except Exception as e: logger.error(f"Health check failed: {e}", exc_info=True) request_id = getattr(request.state, "request_id", None) return HealthResponse( status="unhealthy", uptime_seconds=0.0, version="2.0.0", timestamp=datetime.utcnow().isoformat() + "Z", request_id=request_id ) @router.get("/ready") async def readiness_check(request: Request): """ Readiness check endpoint for load balancers. Returns 200 if the service is ready to accept requests. """ try: # Check if critical services are available # Add your service health checks here return { "status": "ready", "timestamp": datetime.utcnow().isoformat() + "Z", "request_id": getattr(request.state, "request_id", None) } except Exception as e: logger.error(f"Readiness check failed: {e}") return { "status": "not_ready", "timestamp": datetime.utcnow().isoformat() + "Z", "request_id": getattr(request.state, "request_id", None) } @router.get("/live") async def liveness_check(request: Request): """ Liveness check endpoint for container orchestration. Returns 200 if the service is alive. """ return { "status": "alive", "timestamp": datetime.utcnow().isoformat() + "Z", "request_id": getattr(request.state, "request_id", None) }