87 lines
2.4 KiB
Python
87 lines
2.4 KiB
Python
"""
|
|
Health check endpoints
|
|
"""
|
|
|
|
from fastapi import APIRouter, HTTPException, Query
|
|
from pydantic import BaseModel
|
|
from datetime import datetime
|
|
import requests
|
|
import logging
|
|
from typing import Optional
|
|
from urllib.parse import urlparse
|
|
from app.config import settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
class HealthResponse(BaseModel):
|
|
status: str
|
|
ollama_status: str
|
|
timestamp: datetime
|
|
|
|
class Config:
|
|
json_schema_extra = {
|
|
"example": {
|
|
"status": "healthy",
|
|
"ollama_status": "online",
|
|
"timestamp": "2024-01-15T10:30:00Z"
|
|
}
|
|
}
|
|
|
|
|
|
def resolve_ollama_host(host: Optional[str]) -> str:
|
|
"""Resolve target Ollama host, optionally overridden by query parameter."""
|
|
if not host:
|
|
return settings.OLLAMA_HOST
|
|
|
|
parsed = urlparse(host.strip())
|
|
if parsed.scheme not in {"http", "https"} or not parsed.netloc:
|
|
raise HTTPException(status_code=422, detail="Invalid Ollama host URL")
|
|
|
|
return host.rstrip("/")
|
|
|
|
@router.get("/health", response_model=HealthResponse)
|
|
async def health_check(host: Optional[str] = Query(default=None)):
|
|
"""
|
|
Health check dell'API e dello stato di Ollama
|
|
|
|
Returns:
|
|
HealthResponse: Status dell'API e di Ollama
|
|
"""
|
|
target_host = resolve_ollama_host(host)
|
|
try:
|
|
# Check Ollama
|
|
response = requests.get(
|
|
f"{target_host}/api/tags",
|
|
timeout=settings.OLLAMA_TIMEOUT
|
|
)
|
|
ollama_status = "online" if response.status_code == 200 else "offline"
|
|
except Exception as e:
|
|
logger.warning(f"Ollama health check failed: {e}")
|
|
ollama_status = "offline"
|
|
|
|
return HealthResponse(
|
|
status="healthy",
|
|
ollama_status=ollama_status,
|
|
timestamp=datetime.utcnow()
|
|
)
|
|
|
|
@router.get("/ready")
|
|
async def ready(host: Optional[str] = Query(default=None)):
|
|
"""
|
|
Readiness probe per Kubernetes/Docker
|
|
"""
|
|
target_host = resolve_ollama_host(host)
|
|
try:
|
|
response = requests.get(
|
|
f"{target_host}/api/tags",
|
|
timeout=5
|
|
)
|
|
if response.status_code == 200:
|
|
return {"status": "ready"}
|
|
else:
|
|
raise HTTPException(status_code=503, detail="Service unavailable")
|
|
except Exception as e:
|
|
logger.error(f"Readiness check failed: {e}")
|
|
raise HTTPException(status_code=503, detail="Service unavailable")
|