| """ |
| Health check and system status endpoints. |
| """ |
|
|
| from datetime import datetime |
| from fastapi import APIRouter, HTTPException, status |
|
|
| from app.models.inference import HealthResponse, APIInfo, ModelInfo, ErrorResponse |
| from app.services.model_service import model_service |
| from app.core.config import settings |
| from app.core.logging import get_logger |
|
|
| logger = get_logger(__name__) |
|
|
| router = APIRouter() |
|
|
|
|
| @router.get( |
| "/health", |
| response_model=HealthResponse, |
| summary="Health Check", |
| description="Check the health status of the API and model" |
| ) |
| async def health_check() -> HealthResponse: |
| """ |
| Perform a comprehensive health check of the API and model. |
| |
| Returns the current status of the API, model loading status, and basic model information. |
| This endpoint can be used for monitoring and load balancer health checks. |
| """ |
| try: |
| logger.debug("Performing health check") |
| |
| |
| health_status = await model_service.health_check() |
| |
| model_info = None |
| if health_status.get("model_loaded", False): |
| model_info_dict = health_status.get("model_info", {}) |
| if model_info_dict: |
| model_info = ModelInfo(**model_info_dict) |
| |
| return HealthResponse( |
| status="healthy" if health_status.get("model_loaded", False) else "degraded", |
| model_loaded=health_status.get("model_loaded", False), |
| model_info=model_info, |
| timestamp=datetime.utcnow().isoformat() |
| ) |
| |
| except Exception as e: |
| logger.error(f"Health check failed: {str(e)}") |
| return HealthResponse( |
| status="unhealthy", |
| model_loaded=False, |
| model_info=None, |
| timestamp=datetime.utcnow().isoformat() |
| ) |
|
|
|
|
| @router.get( |
| "/info", |
| response_model=APIInfo, |
| summary="API Information", |
| description="Get comprehensive information about the API and model" |
| ) |
| async def get_api_info() -> APIInfo: |
| """ |
| Get comprehensive information about the API. |
| |
| Returns detailed information about the API version, capabilities, model information, |
| and available endpoints. |
| """ |
| try: |
| logger.debug("Fetching API information") |
| |
| |
| model_info_dict = model_service.get_model_info() |
| model_info = ModelInfo(**model_info_dict) |
| |
| |
| endpoints = [ |
| f"{settings.API_V1_STR}/detect", |
| f"{settings.API_V1_STR}/species", |
| f"{settings.API_V1_STR}/species/{{class_id}}", |
| f"{settings.API_V1_STR}/health", |
| f"{settings.API_V1_STR}/info" |
| ] |
| |
| return APIInfo( |
| name=settings.PROJECT_NAME, |
| version=settings.VERSION, |
| description=settings.DESCRIPTION, |
| model_info=model_info, |
| endpoints=endpoints |
| ) |
| |
| except Exception as e: |
| logger.error(f"Failed to get API info: {str(e)}") |
| raise HTTPException( |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
| detail=f"Failed to get API information: {str(e)}" |
| ) |
|
|
|
|
| @router.get( |
| "/ready", |
| summary="Readiness Check", |
| description="Check if the API is ready to serve requests" |
| ) |
| async def readiness_check() -> dict: |
| """ |
| Check if the API is ready to serve requests. |
| |
| This endpoint is specifically designed for Kubernetes readiness probes. |
| It returns 200 OK only when the model is loaded and ready to process requests. |
| """ |
| try: |
| health_status = await model_service.health_check() |
| |
| if health_status.get("model_loaded", False): |
| return {"status": "ready"} |
| else: |
| raise HTTPException( |
| status_code=status.HTTP_503_SERVICE_UNAVAILABLE, |
| detail="Model not ready" |
| ) |
| |
| except HTTPException: |
| raise |
| except Exception as e: |
| logger.error(f"Readiness check failed: {str(e)}") |
| raise HTTPException( |
| status_code=status.HTTP_503_SERVICE_UNAVAILABLE, |
| detail="Service not ready" |
| ) |
|
|
|
|
| @router.get( |
| "/live", |
| summary="Liveness Check", |
| description="Check if the API is alive" |
| ) |
| async def liveness_check() -> dict: |
| """ |
| Check if the API is alive. |
| |
| This endpoint is designed for Kubernetes liveness probes. |
| It performs a minimal check to ensure the API process is running. |
| """ |
| return {"status": "alive", "timestamp": datetime.utcnow().isoformat()} |
|
|