Spaces:
Sleeping
Sleeping
| """Normalize Supabase `jobs` rows for polling / WebSocket clients (stable `job_id` + JSON `result`).""" | |
| from __future__ import annotations | |
| import json | |
| import logging | |
| from typing import Any | |
| logger = logging.getLogger(__name__) | |
| def _coerce_result(value: Any) -> Any: | |
| if value is None: | |
| return None | |
| if isinstance(value, (dict, list)): | |
| return value | |
| if isinstance(value, str): | |
| try: | |
| return json.loads(value) | |
| except json.JSONDecodeError: | |
| logger.warning("job_poll: result is non-JSON string, returning raw") | |
| return {"raw": value} | |
| return value | |
| def normalize_job_row_for_client(row: dict[str, Any]) -> dict[str, Any]: | |
| """ | |
| Build a JSON-serializable dict that always includes: | |
| - ``job_id`` (alias of DB ``id``) for clients that expect it on poll bodies | |
| - ``status`` as str | |
| - ``result`` as object/array when stored as JSON string | |
| All other columns are passed through (UUID/datetime become JSON-safe via FastAPI encoder). | |
| """ | |
| out = dict(row) | |
| jid = out.get("id") | |
| if jid is not None: | |
| out["job_id"] = str(jid) | |
| st = out.get("status") | |
| if st is not None: | |
| out["status"] = str(st) | |
| if "result" in out: | |
| out["result"] = _coerce_result(out.get("result")) | |
| if out.get("user_id") is not None: | |
| out["user_id"] = str(out["user_id"]) | |
| if out.get("session_id") is not None: | |
| out["session_id"] = str(out["session_id"]) | |
| return out | |