Files
LockInBroAPI/app/services/hex_service.py
2026-03-29 06:57:34 -04:00

50 lines
1.6 KiB
Python

import asyncio
import httpx
from app.config import settings
HEX_API_BASE = "https://app.hex.tech/api/v1"
HEADERS = {
"Authorization": f"Bearer {settings.HEX_API_TOKEN}",
"Content-Type": "application/json",
}
NOTEBOOKS = {
"distraction_patterns": settings.HEX_NB_DISTRACTIONS,
"focus_trends": settings.HEX_NB_FOCUS_TRENDS,
"weekly_report": settings.HEX_NB_WEEKLY_REPORT,
}
async def run_notebook(notebook_key: str, user_id: str) -> dict:
project_id = NOTEBOOKS.get(notebook_key)
if not project_id:
raise ValueError(f"Unknown notebook: {notebook_key}")
async with httpx.AsyncClient(timeout=60) as http:
# Trigger run — POST /projects/{projectId}/runs
resp = await http.post(
f"{HEX_API_BASE}/projects/{project_id}/runs",
headers=HEADERS,
json={"inputParams": {"user_id": user_id}},
)
resp.raise_for_status()
run_id = resp.json()["runId"]
# Poll for completion — GET /projects/{projectId}/runs/{runId}
for _ in range(30):
status_resp = await http.get(
f"{HEX_API_BASE}/projects/{project_id}/runs/{run_id}",
headers=HEADERS,
)
status_resp.raise_for_status()
data = status_resp.json()
if data["status"] == "COMPLETED":
return {"status": "COMPLETED", "elapsed": data.get("elapsedTime")}
if data["status"] in ("ERRORED", "KILLED", "UNABLE_TO_ALLOCATE_KERNEL"):
raise RuntimeError(f"Hex run failed: {data['status']}")
await asyncio.sleep(2)
raise TimeoutError("Hex notebook run timed out")