From ecf8c9a40102d83e9144eb029718a8309489b3c8 Mon Sep 17 00:00:00 2001 From: Gregor Klevze Date: Sat, 21 Mar 2026 10:07:20 +0100 Subject: [PATCH] Fix: use pydantic pattern; handle httpx RequestError in gateway and qdrant --- clip/main.py | 2 +- gateway/main.py | 10 ++++++++-- qdrant/main.py | 20 ++++++++++++++++---- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/clip/main.py b/clip/main.py index e1e8e5d..20480c8 100644 --- a/clip/main.py +++ b/clip/main.py @@ -39,7 +39,7 @@ class AnalyzeRequest(BaseModel): class EmbedRequest(BaseModel): url: Optional[str] = None - backend: Optional[str] = Field(default="openclip", regex="^(openclip|hf)$") + backend: Optional[str] = Field(default="openclip", pattern="^(openclip|hf)$") model: Optional[str] = None pretrained: Optional[str] = None diff --git a/gateway/main.py b/gateway/main.py index 5805e3d..1a25962 100644 --- a/gateway/main.py +++ b/gateway/main.py @@ -59,7 +59,10 @@ async def _get_health(client: httpx.AsyncClient, base: str) -> Dict[str, Any]: async def _post_json(client: httpx.AsyncClient, url: str, payload: Dict[str, Any]) -> Dict[str, Any]: - r = await client.post(url, json=payload) + try: + r = await client.post(url, json=payload) + except httpx.RequestError as e: + raise HTTPException(status_code=502, detail=f"Upstream request failed {url}: {str(e)}") if r.status_code >= 400: raise HTTPException(status_code=502, detail=f"Upstream error {url}: {r.status_code} {r.text[:1000]}") try: @@ -71,7 +74,10 @@ async def _post_json(client: httpx.AsyncClient, url: str, payload: Dict[str, Any async def _post_file(client: httpx.AsyncClient, url: str, data: bytes, fields: Dict[str, Any]) -> Dict[str, Any]: files = {"file": ("image", data, "application/octet-stream")} - r = await client.post(url, data={k: str(v) for k, v in fields.items()}, files=files) + try: + r = await client.post(url, data={k: str(v) for k, v in fields.items()}, files=files) + except httpx.RequestError as e: + raise HTTPException(status_code=502, detail=f"Upstream request failed {url}: {str(e)}") if r.status_code >= 400: raise HTTPException(status_code=502, detail=f"Upstream error {url}: {r.status_code} {r.text[:1000]}") try: diff --git a/qdrant/main.py b/qdrant/main.py index c243ffb..389cd9f 100644 --- a/qdrant/main.py +++ b/qdrant/main.py @@ -109,20 +109,32 @@ def _col(name: Optional[str]) -> str: async def _embed_url(url: str) -> List[float]: """Call the CLIP service to get an image embedding.""" async with httpx.AsyncClient(timeout=30) as http: - r = await http.post(f"{CLIP_URL}/embed", json={"url": url}) + try: + r = await http.post(f"{CLIP_URL}/embed", json={"url": url}) + except httpx.RequestError as e: + raise HTTPException(502, f"CLIP request failed: {str(e)}") if r.status_code >= 400: raise HTTPException(502, f"CLIP /embed error: {r.status_code} {r.text[:200]}") - return r.json()["vector"] + try: + return r.json()["vector"] + except Exception: + raise HTTPException(502, f"CLIP /embed returned non-JSON: {r.status_code} {r.text[:200]}") async def _embed_bytes(data: bytes) -> List[float]: """Call the CLIP service to embed uploaded file bytes.""" async with httpx.AsyncClient(timeout=30) as http: files = {"file": ("image", data, "application/octet-stream")} - r = await http.post(f"{CLIP_URL}/embed/file", files=files) + try: + r = await http.post(f"{CLIP_URL}/embed/file", files=files) + except httpx.RequestError as e: + raise HTTPException(502, f"CLIP request failed: {str(e)}") if r.status_code >= 400: raise HTTPException(502, f"CLIP /embed/file error: {r.status_code} {r.text[:200]}") - return r.json()["vector"] + try: + return r.json()["vector"] + except Exception: + raise HTTPException(502, f"CLIP /embed/file returned non-JSON: {r.status_code} {r.text[:200]}") def _build_filter(metadata: Dict[str, Any]) -> Optional[Filter]: