Download src/api/v1/charts.py from DataEyond/Agentic-Service-Data-Eyond-Catalog: direct link, hf CLI and curl.
- Browser
- Download file 2.61 kB
-
https://huggingface.co/spaces/DataEyond/Agentic-Service-Data-Eyond-Catalog/resolve/refs%2Fpr%2F21/src/api/v1/charts.py
- Command line
-
hf download hf://spaces/DataEyond/Agentic-Service-Data-Eyond-Catalog@refs/pr/21/src/api/v1/charts.py
-
curl -L -o charts.py https://huggingface.co/spaces/DataEyond/Agentic-Service-Data-Eyond-Catalog/resolve/refs%2Fpr%2F21/src/api/v1/charts.py
2.61 kB
| """Charts endpoint — user-facing chart retrieval for one turn (S2 visualization, | |
| SPINE_V2_PLAN §4.4/§4.5). | |
| `GET /api/v1/charts?message_id=` returns every chart a `render_chart` tool call | |
| produced during one assistant turn, as `dataeyond.chart.v1` envelopes | |
| (SPINE_V2_PLAN §4.2). Rows are written by the chat pipeline right before the `done` | |
| SSE event; the FE fires this GET on `done` with the `message_id` from that event. | |
| Lookup is by `message_id` alone (Python-minted UUID4 — lead decision 2026-07-13). | |
| Every response is HTTP 200 with an explicit `status` marker (lead ask 2026-07-13): | |
| - `success` — ≥1 chart; render them. | |
| - `empty` — the turn completed but produced no charts (the common case). | |
| - `not_found` — no completed turn is known for this message_id (mistyped/stale | |
| id, or an error turn — those never write a row). Distinguished | |
| from `empty` via the turn's traceability row. | |
| No auth — Go fronts Python. | |
| """ | |
| from typing import Literal | |
| from fastapi import APIRouter, Query | |
| from pydantic import BaseModel | |
| from src.charts import ChartRecord, PostgresChartStore | |
| from src.middlewares.logging import get_logger, log_execution | |
| logger = get_logger("charts_api") | |
| router = APIRouter(prefix="/api/v1", tags=["Charts"]) | |
| # Warm, process-shared store (mirrors the chat endpoints' module-level instances). | |
| _store = PostgresChartStore() | |
| class ChartsResponse(BaseModel): | |
| status: Literal["success", "empty", "not_found"] | |
| message: str | |
| count: int | |
| charts: list[ChartRecord] | |
| async def get_charts( | |
| message_id: str = Query( | |
| ..., description="Assistant turn id, taken from the `done` SSE event" | |
| ), | |
| ) -> ChartsResponse: | |
| """Fetch every chart for one turn. Always 200 — the `status` field carries the | |
| outcome, so the FE can call this unconditionally on every `done`.""" | |
| charts = await _store.list_for_message(message_id) | |
| if charts: | |
| return ChartsResponse( | |
| status="success", | |
| message=f"{len(charts)} chart(s) for this message.", | |
| count=len(charts), | |
| charts=charts, | |
| ) | |
| if await _store.turn_exists(message_id): | |
| return ChartsResponse( | |
| status="empty", | |
| message="This message completed without producing charts.", | |
| count=0, | |
| charts=[], | |
| ) | |
| return ChartsResponse( | |
| status="not_found", | |
| message="No completed turn is known for this message_id.", | |
| count=0, | |
| charts=[], | |
| ) | |