Compare commits

..

2 commits

Author SHA1 Message Date
e6b64d6efe fix: imitate extractor + health_path — support CF cloud API shapes
- _extract_sample: add saved_searches, entries, calls, records as
  recognized list-wrapper keys (snipe/osprey response shapes)
- _is_online: accept health_path param (default /api/health) so
  products using /api/v1/health/ (kiwi) report correctly
- products endpoint: pass health_path from config into _is_online
2026-04-09 20:24:26 -07:00
fee0cdb4a8 Merge pull request 'feat: Imitate tab — pull CF product samples, compare LLM responses' (#23) from feat/imitate into main 2026-04-09 20:13:20 -07:00

View file

@ -94,10 +94,10 @@ def _http_get_json(url: str, timeout: int = 5) -> Any:
return json.loads(resp.read().decode("utf-8")) return json.loads(resp.read().decode("utf-8"))
def _is_online(base_url: str) -> bool: def _is_online(base_url: str, health_path: str = "/api/health") -> bool:
"""Return True if the product's /api/health endpoint responds OK.""" """Return True if the product's health endpoint responds OK."""
try: try:
data = _http_get_json(f"{base_url.rstrip('/')}/api/health", timeout=2) data = _http_get_json(f"{base_url.rstrip('/')}{health_path}", timeout=2)
return bool(data) return bool(data)
except Exception: except Exception:
return False return False
@ -114,7 +114,8 @@ def _extract_sample(
item = raw[min(sample_index, len(raw) - 1)] item = raw[min(sample_index, len(raw) - 1)]
elif isinstance(raw, dict): elif isinstance(raw, dict):
# may be {items: [...]} or the item itself # may be {items: [...]} or the item itself
for key in ("items", "results", "data", "jobs", "listings", "pantry"): for key in ("items", "results", "data", "jobs", "listings", "pantry",
"saved_searches", "entries", "calls", "records"):
if key in raw and isinstance(raw[key], list): if key in raw and isinstance(raw[key], list):
lst = raw[key] lst = raw[key]
item = lst[min(sample_index, len(lst) - 1)] if lst else {} item = lst[min(sample_index, len(lst) - 1)] if lst else {}
@ -189,7 +190,7 @@ def get_products() -> dict:
"icon": p.get("icon", "📦"), "icon": p.get("icon", "📦"),
"description": p.get("description", ""), "description": p.get("description", ""),
"base_url": base_url, "base_url": base_url,
"online": _is_online(base_url) if base_url else False, "online": _is_online(base_url, p.get("health_path", "/api/health")) if base_url else False,
}) })
return {"products": products} return {"products": products}