ramanna's picture
Deploy: unbuffer pipeline logs
4aa353b
|
Raw History Blame Contribute Delete
5.52 kB
# HTTP API
All backend routes live under `/api/` and are served by FastAPI. In
production, the browser hits them same-origin via a Next.js rewrite; in
dev they're at `http://localhost:8000/api/...`. Full auto-generated docs
are always at `http://localhost:8000/docs` (Swagger UI).
## Public endpoints (no auth)
### Health / readiness
| Method | Path | Response |
|---|---|---|
| GET | `/api/health` | `{status, data_dir, data_dir_exists}` β€” always 200 if process is up |
| GET | `/api/ready` | `{ready, checks, bills_count}` β€” 200 if data is loaded, 503 otherwise |
### Bills
| Method | Path | Notes |
|---|---|---|
| GET | `/api/bills` | List bills. Query: `state`, `status`, `session_year`, `category`, `search`, `limit`, `offset` |
| GET | `/api/bills/stats` | Totals: `{total_bills, federal_bills, state_bills, most_active_state, last_updated_at}` |
| GET | `/api/bills/filters` | Dropdown data: `{states, statuses, years, categories}` |
| GET | `/api/bills/{bill_id}` | Full bill detail (used by the row-detail modal) |
| GET | `/api/bills/by-state` | `{STATE: count}` for the choropleth. Optional `?year=YYYY` |
| GET | `/api/bills/export.csv` | Filtered CSV download (same filters as `/api/bills`) |
### Insights
| Method | Path |
|---|---|
| GET | `/api/insights/by-state?limit=N` |
| GET | `/api/insights/by-category?limit=N` |
| GET | `/api/insights/over-time` |
### Calendar
| Method | Path | Notes |
|---|---|---|
| GET | `/api/calendar` | Month view. Query: `year`, `month`, `types[]` |
| GET | `/api/calendar/upcoming` | Next N days. Query: `days` (default 7, max 30) |
### Newsletter
| Method | Path | Notes |
|---|---|---|
| GET | `/api/newsletters` | List available dates |
| GET | `/api/newsletters/{date}` | Markdown of one newsletter |
| GET | `/api/newsletters/{date}/changes` | Weekly changes CSV rows for that date |
| GET | `/api/newsletters/{date}/digest` | Stats + in-motion bills for the hero + Bills in Motion sections |
| GET | `/api/newsletters/{date}/featured-bill` | "Bill of the Week" β€” scored pick from the week's changes |
| GET | `/api/newsletters/{date}/category-trends` | Top IAPP categories affected this week |
### States
| Method | Path |
|---|---|
| GET | `/api/states/featured` |
| GET | `/api/states/{state}/spotlight?key_bills=N` |
### Feedback / subscribe
| Method | Path | Body |
|---|---|---|
| POST | `/api/feedback` | `{name?, email?, type, description}` |
| POST | `/api/newsletter/subscribe` | `{email}` |
| POST | `/api/newsletter/unsubscribe` | `{email}` |
### AI tools
| Method | Path | Body |
|---|---|---|
| GET | `/api/ai/bills/list` | Bills available in the AI tools dropdown |
| GET | `/api/ai/bill/{state}/{bill_number}` | Bill + summary + suggested questions + has_report flag |
| GET | `/api/ai/report/{state}/{bill_number}` | Pre-generated report markdown |
| POST | `/api/ai/qa` | `{state, bill_number, question}` |
| POST | `/api/ai/compare` | `{focus_state, focus_bill_number, compare[], question}` |
| POST | `/api/ai/eu-compare` | `{state, bill_number, question}` |
## Auth
| Method | Path | Notes |
|---|---|---|
| POST | `/api/auth/login` | `{username, password}` β†’ `{token, username, name}` |
| GET | `/api/auth/me` | Current user; requires `Authorization: Bearer <token>` |
| POST | `/api/auth/logout` | Client discards the token |
## Admin endpoints
All under `/api/admin/*`. Require `Authorization: Bearer <jwt>` where the
JWT was issued by `/api/auth/login`. Enforced by the `require_admin`
dependency in every admin route.
### Overview
| Method | Path | Notes |
|---|---|---|
| GET | `/api/admin/overview` | Card counts, including `new_feedback_count` (fed to the nav badge) |
### Users
| Method | Path | Body |
|---|---|---|
| GET | `/api/admin/users` | List |
| POST | `/api/admin/users` | `{username, name, email, password}` |
| PATCH | `/api/admin/users/{username}` | `{name?, email?, password?}` (any subset) |
| DELETE | `/api/admin/users/{username}` | |
### Subscribers
| Method | Path |
|---|---|
| GET | `/api/admin/subscribers` |
| DELETE | `/api/admin/subscribers/{email}` |
### Feedback
| Method | Path | Body |
|---|---|---|
| GET | `/api/admin/feedback` | |
| PATCH | `/api/admin/feedback/{id}` | `{status}` β€” one of `new`, `read`, `resolved` |
| DELETE | `/api/admin/feedback/{id}` | |
### Pipeline
| Method | Path | Body / Notes |
|---|---|---|
| GET | `/api/admin/pipeline/status` | Current or last run |
| GET | `/api/admin/pipeline/history?limit=N` | Last N runs |
| GET | `/api/admin/pipeline/scripts` | The 14 step list with names + indices |
| GET | `/api/admin/pipeline/log?tail=N` | Last N lines of the pipeline log |
| POST | `/api/admin/pipeline/run` | `{pull?, test?, test_count?, start_from?, stop_after?, reset_vectorstore?, upload_to_hf?}` (all optional) |
| POST | `/api/admin/pipeline/cancel` | Kills the running subprocess group |
| POST | `/api/admin/pipeline/rebuild-manifest` | Standalone `rebuild_vectorstore_manifest.py` run |
### Weekly changes
| Method | Path |
|---|---|
| GET | `/api/admin/weekly-changes` |
| GET | `/api/admin/weekly-changes/{week_of}` |
## Error format
Errors follow FastAPI's default `{"detail": "..."}` shape. Server-side
5xx errors also include a `request_id` β€” a short hex string echoed in
the `X-Request-ID` response header. When a user reports an error, ask
for the request ID and grep the backend logs for `rid=<id>`.
## Rate limiting
None currently. Add one at the ingress layer (HF's edge) if traffic ever
warrants it.