from __future__ import annotations import httpx from .config import Settings _TIMEOUT = 3.0 async def check_vllm(settings: Settings) -> dict: base_url = ( f"http://{settings.spark1_host}:{settings.vllm_port}/v1" if settings.spark1_host else None ) if not settings.spark1_host: return {"ok": False, "error": "spark1 not configured", "base_url": base_url} try: async with httpx.AsyncClient(timeout=_TIMEOUT) as c: r = await c.get(f"http://{settings.spark1_host}:{settings.vllm_port}/v1/models") r.raise_for_status() ids = [m["id"] for m in r.json().get("data", [])] return { "ok": True, "current_model": ids[0] if ids else None, "all": ids, "base_url": base_url, } except Exception as e: return {"ok": False, "error": str(e), "base_url": base_url} async def check_parakeet(settings: Settings) -> dict: base_url = ( f"http://{settings.parakeet_host}:{settings.parakeet_port}" if settings.parakeet_host else None ) if not settings.parakeet_host: return {"ok": False, "error": "parakeet host not configured", "base_url": base_url} try: async with httpx.AsyncClient(timeout=_TIMEOUT) as c: r = await c.get(f"http://{settings.parakeet_host}:{settings.parakeet_port}/health") r.raise_for_status() return {"ok": True, "detail": r.json(), "base_url": base_url} except Exception as e: return {"ok": False, "error": str(e), "base_url": base_url} async def check_kokoro(settings: Settings) -> dict: base_url = ( f"http://{settings.kokoro_host}:{settings.kokoro_port}" if settings.kokoro_host else None ) if not settings.kokoro_host: return {"ok": False, "error": "kokoro host not configured", "base_url": base_url} try: async with httpx.AsyncClient(timeout=_TIMEOUT) as c: r = await c.get(f"http://{settings.kokoro_host}:{settings.kokoro_port}/health") r.raise_for_status() return { "ok": True, "detail": r.json() if r.headers.get("content-type", "").startswith("application/json") else r.text, "base_url": base_url, } except Exception as e: return {"ok": False, "error": str(e), "base_url": base_url} async def check_embeddings(settings: Settings) -> dict: base_url = ( f"http://{settings.embed_host}:{settings.embed_port}" if settings.embed_host else None ) if not settings.embed_host: return {"ok": False, "error": "embedding host not configured", "base_url": base_url} try: async with httpx.AsyncClient(timeout=_TIMEOUT) as c: r = await c.get(f"{base_url}/health") r.raise_for_status() detail = r.json() if r.headers.get("content-type", "").startswith("application/json") else r.text # spark-embed reports {"status":"ready"|"loading", ...} — only "ready" is healthy. ready = isinstance(detail, dict) and detail.get("status") == "ready" return {"ok": ready, "detail": detail, "base_url": base_url, "model": detail.get("dense_model") if isinstance(detail, dict) else None} except Exception as e: return {"ok": False, "error": str(e), "base_url": base_url} async def check_qdrant(settings: Settings) -> dict: base_url = ( f"http://{settings.qdrant_host}:{settings.qdrant_port}" if settings.qdrant_host else None ) if not settings.qdrant_host: return {"ok": False, "error": "qdrant host not configured", "base_url": base_url} try: async with httpx.AsyncClient(timeout=_TIMEOUT) as c: # /readyz returns 200 "all shards are ready" when serving. r = await c.get(f"{base_url}/readyz") r.raise_for_status() return {"ok": True, "detail": r.text.strip()[:120], "base_url": base_url} except Exception as e: return {"ok": False, "error": str(e), "base_url": base_url}