Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website, Klausur-Service, School-Service, Voice-Service, Geo-Service, BreakPilot Drive, Agent-Core Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
128 lines
3.9 KiB
Python
128 lines
3.9 KiB
Python
"""
|
|
Health Check Route.
|
|
"""
|
|
|
|
import logging
|
|
from datetime import datetime
|
|
from fastapi import APIRouter
|
|
from pydantic import BaseModel
|
|
|
|
from ..config import get_config
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(tags=["Health"])
|
|
|
|
|
|
class ComponentStatus(BaseModel):
|
|
"""Status einer Komponente."""
|
|
name: str
|
|
status: str # healthy, degraded, unhealthy
|
|
message: str = ""
|
|
|
|
|
|
class HealthResponse(BaseModel):
|
|
"""Health Check Response."""
|
|
status: str # ok, degraded, error
|
|
ts: str
|
|
version: str
|
|
components: list[ComponentStatus]
|
|
|
|
|
|
@router.get("/health", response_model=HealthResponse)
|
|
async def health_check():
|
|
"""
|
|
Health Check Endpoint.
|
|
|
|
Prüft den Status aller Komponenten:
|
|
- Gateway selbst
|
|
- LLM Backend Erreichbarkeit
|
|
- Datenbank (wenn konfiguriert)
|
|
"""
|
|
config = get_config()
|
|
components = []
|
|
overall_status = "ok"
|
|
|
|
# Gateway selbst
|
|
components.append(ComponentStatus(
|
|
name="gateway",
|
|
status="healthy",
|
|
message="Gateway is running",
|
|
))
|
|
|
|
# Ollama Backend
|
|
if config.ollama and config.ollama.enabled:
|
|
try:
|
|
import httpx
|
|
async with httpx.AsyncClient(timeout=5.0) as client:
|
|
response = await client.get(f"{config.ollama.base_url}/api/tags")
|
|
if response.status_code == 200:
|
|
components.append(ComponentStatus(
|
|
name="ollama",
|
|
status="healthy",
|
|
message="Ollama is reachable",
|
|
))
|
|
else:
|
|
components.append(ComponentStatus(
|
|
name="ollama",
|
|
status="degraded",
|
|
message=f"Ollama returned status {response.status_code}",
|
|
))
|
|
overall_status = "degraded"
|
|
except Exception as e:
|
|
components.append(ComponentStatus(
|
|
name="ollama",
|
|
status="unhealthy",
|
|
message=f"Cannot reach Ollama: {str(e)}",
|
|
))
|
|
# Nicht critical wenn andere Backends verfügbar
|
|
if not (config.vllm and config.vllm.enabled) and not (config.anthropic and config.anthropic.enabled):
|
|
overall_status = "error"
|
|
|
|
# vLLM Backend
|
|
if config.vllm and config.vllm.enabled:
|
|
try:
|
|
import httpx
|
|
headers = {}
|
|
if config.vllm.api_key:
|
|
headers["Authorization"] = f"Bearer {config.vllm.api_key}"
|
|
async with httpx.AsyncClient(timeout=5.0) as client:
|
|
response = await client.get(
|
|
f"{config.vllm.base_url}/v1/models",
|
|
headers=headers,
|
|
)
|
|
if response.status_code == 200:
|
|
components.append(ComponentStatus(
|
|
name="vllm",
|
|
status="healthy",
|
|
message="vLLM is reachable",
|
|
))
|
|
else:
|
|
components.append(ComponentStatus(
|
|
name="vllm",
|
|
status="degraded",
|
|
message=f"vLLM returned status {response.status_code}",
|
|
))
|
|
overall_status = "degraded"
|
|
except Exception as e:
|
|
components.append(ComponentStatus(
|
|
name="vllm",
|
|
status="unhealthy",
|
|
message=f"Cannot reach vLLM: {str(e)}",
|
|
))
|
|
|
|
# Anthropic Backend
|
|
if config.anthropic and config.anthropic.enabled:
|
|
components.append(ComponentStatus(
|
|
name="anthropic",
|
|
status="healthy",
|
|
message="Anthropic API configured (not checked)",
|
|
))
|
|
|
|
return HealthResponse(
|
|
status=overall_status,
|
|
ts=datetime.utcnow().isoformat() + "Z",
|
|
version="0.1.0",
|
|
components=components,
|
|
)
|