API server
From the Life-Dashboard wiki
| Also known as | FastAPI, main application, health check, startup, middleware, /brief, /health, /ingest, /logout, /me, /overview, /readiness-summary, /refresh-today |
|---|---|
| Files | 27 |
| Lines of code | 2,300 |
| Languages | Python, Markdown |
| Entry points | backend/app/__main__.pyscripts/benchmark_speed.pybackend/app/routers/__init__.py |
| First commit | 4 November 2025 |
| Last commit | 7 June 2026 |
| Main contributors | Sean May (100%) |
| Revision | e662257 |
API server is the FastAPI application that runs Life-Dashboard's backend, handling authentication, HTTP routing, middleware, and the startup sequence for all integrated services. It exposes routes for user authentication, system metrics, daily insights, morning briefs, and admin operations, and coordinates with background jobs, Garmin integration, and nutrition tracking on request.
Overview
The API server starts with uvicorn.run() on port 8000 and is built around FastAPI, a web framework that handles HTTP requests asynchronously.[1][2] Its main components are configuration and logging, database session management, service layer business logic, HTTP routers grouped by domain, and Pydantic request/response schemas.[3]
Metrics and insights routers expose /metrics/overview, /metrics/daily, /metrics/readiness-summary, and /insights/daily to show Garmin readiness scores, HRV, sleep, and training load.[4][5] System and admin routers expose /system/refresh-today to trigger background refresh jobs and /admin/ingest to manually start metrics and insight ingestion.[6][7] Auth routers expose /auth/google/login, /auth/google/callback, /auth/me, and /auth/logout for Google OAuth and session management.[8][9][10][11][12]
How it works
On startup, the startup_event() initializes the database and runs any pending migrations.[13] The SecurityHeadersMiddleware adds standard security headers like Content-Security-Policy and X-Frame-Options to every response.[14]
Auth endpoints are rate-limited using a KVStore-backed counter per client IP that increments on each attempt and resets after a 60-second window, raising HTTP 429 if the limit of 10 is exceeded.[15] The POST /api/morning/brief endpoint builds a prompt from readiness, events, tasks, and reads signals, calls OpenAIResponsesClient.generate_text() with temperature 0.4 and max tokens 220, and returns the generated paragraph or HTTP 502 on failure.[16]
The /metrics/overview endpoint queries MetricsRepository.list_metrics_since() with a configurable range (1–365 days), caches the result for 5 minutes with a bounded LRU eviction policy, and returns averaged deltas for HRV, sleep, and training load.[17][18] The GET /time router returns the current time in US Eastern timezone as ISO 8601 and a computed moment (morning, noon, twilight, or night) based on the hour.[19]
The /auth router handles Google OAuth via _exchange_code_for_tokens() and _verify_id_token_async(), which are called by the google_callback() endpoint; it stores sessions in the database via create_user_session() and validates them per request with get_current_user().[20][21][10][22][23]
Data flow
flowchart LR n3["backend/app/main.py"] n6["backend/app/routers/auth.py"] n8["backend/app/routers/metrics.py"] n9["backend/app/routers/morning_brief.py"] n10["backend/app/routers/system.py"] n1["backend/app/core/auth.py"] n18[["Configuration"]] n22[["Todo management"]] n17[["Background jobs"]] n3 -->|"mounts auth routes"| n6 n3 -->|"mounts metrics routes"| n8 n3 -->|"mounts morning brief"| n9 n3 -->|"mounts system routes"| n10 n3 -->|"initializes config"| n18 n6 -->|"calls user session"| n22 n10 -->|"enqueues refresh job"| n17
Authentication starts when a client calls GET /auth/google/login with an optional redirect URL; the server sets OAuth state and remember-me cookies and redirects to Google's authorization endpoint.[24] Google redirects back to GET /auth/google/callback with an authorization code; the server exchanges it for tokens, verifies the ID token, upserts the user in the database, and returns a session token cookie.[25]
On each request, get_current_user() extracts the session token from cookies, looks it up in the database, and returns the associated user if the session has not been revoked.[26] Metrics flow from Garmin via the background job queue into DailyMetric rows; the /metrics router fetches them from the database and caches the result.[17] Morning brief requests carry readiness, events, tasks, and reads as JSON; the router assembles them into a prompt, sends it to OpenAI, and streams back a generated paragraph.[27]
History
- The
/healthendpoint was added on 7 June 2026 and returns{"status": "ok"}to support Fargate readiness and liveness probes.[28] - The morning brief endpoint was implemented on 7 June 2026 to synthesize readiness, schedule, tasks, and reads into a single LLM-generated paragraph.[29]
- On 4 June 2026, the API was refactored to use Mangum as the AWS Lambda handler and KVStore-backed caching and rate limiting to support serverless deployment.[30][31]
- Google OAuth was added on 13 January 2026 to enable multi-user authentication with role-based access control (admin vs. user).[32]
- Auth endpoints were hardened on 24 March 2026 with rate limiting, strict cookie attributes, CORS method and header restrictions, and disabled loguru diagnose to prevent secret leakage in error logs.[33][34][35]
See also
References
-
^
backend/app/__main__.py:L3-8@e662257 -
^
backend/app/app-readme.md:L4@e662257 -
^
backend/app/app-readme.md:L4-18@e662257 -
^
backend/app/routers/metrics.py:L22-136@e662257 -
^
backend/app/routers/insights.py:L19-46@e662257 -
^
backend/app/routers/system.py:L12-22@e662257 -
^
backend/app/routers/admin.py:L14-31@e662257 -
^
backend/app/routers/auth.py:L32@e662257(router) -
^
backend/app/routers/auth.py:L96-114@e662257 -
^ a b
backend/app/routers/auth.py:L209-220@e662257(google_callback) -
^
backend/app/routers/auth.py:L258-274@e662257 -
^
backend/app/routers/auth.py:L276-292@e662257(logout) -
^
backend/app/main.py:L84-89@e662257 -
^
backend/app/main.py:L13-48@e662257 -
^
backend/app/routers/auth.py:L35-49@e662257 -
^
backend/app/routers/morning_brief.py:L78-115@e662257(generate_morning_brief) -
^ a b
backend/app/routers/metrics.py:L22-82@e662257 -
^
backend/app/db/repositories/metrics_repository.py:L54-61@e662257(MetricsRepository.list_metrics_since) -
^
backend/app/routers/time.py:L8-36@e662257 -
^
backend/app/routers/auth.py:L116-132@e662257 -
^
backend/app/routers/auth.py:L142-146@e662257 -
^
backend/app/core/auth.py:L43-60@e662257 -
^
backend/app/core/auth.py:L149-154@e662257 -
^
backend/app/routers/auth.py:L96-113@e662257(google_login) -
^
backend/app/routers/auth.py:L209-255@e662257(google_callback) -
^
backend/app/core/auth.py:L135-161@e662257 -
^
backend/app/routers/morning_brief.py:L21-115@e662257 -
^ Commit
7bcb6ad: "fix(final-review): worker cold-start ordering (critical), arm64 CI, SQS encryption, Fargate SG, runbook env-wipe + health check, HSTS, docs hardening" (PR #49) -
^ Commit
840d23d: "feat(rework): backend LLM morning-brief endpoint (POST /api/morning/brief) (C1)" (PR #52) -
^ Commit
5fa44de: "feat(aws): Mangum API handler + cold-start bootstrap (secrets, runtime validation, engine init)" (PR #49) -
^ Commit
47fbf9b: "refactor(api): back metrics cache + auth rate-limit with KVStore" (PR #49) -
^ Commit
96fddd2: "Add google auth, users, rate limits for non-admin" -
^ Commit
d83aad9: "Add rate limiting on auth endpoints and fix auth router security issues" (PR #15) -
^ Commit
b3a9f4a: "Disable loguru diagnose to prevent secret leakage in tracebacks" (PR #15) -
^ Commit
00de4f0: "Restrict CORS methods/headers and add security response headers" (PR #15)
This page was last edited on 8 June 2026, at commit e662257.