Skip to main content
The backend is a Python 3.11+ FastAPI app hosted on AWS EC2. It handles three concerns: market data (prices + forex), AI agent orchestration, and CRUD for transactions, holdings, and accounts.

Server setup


Routers

/market — market data

/ai — agent endpoints

/transactions, /holdings, /accounts

Standard CRUD. All endpoints require JWT auth via get_current_user dependency. All Supabase queries are scoped to user_id and protected by RLS.

/newsletter

/rag


TTL cache

Cache instances:
  • price_cache — stocks and crypto (60s TTL)
  • forex_cache — currency pairs (300s TTL)
  • auth_cache — validated JWTs (300s TTL)
  • history_cache — OHLCV data (300s TTL)
  • earnings_cache — earnings calendar (3600s TTL)
All caches are in-memory, per-process. On EC2, a single uvicorn worker handles all requests — no Redis needed at MVP scale.

Supabase client

The backend uses the service role key (not the anon key). This allows writing to tables like user_insights and user_newsletters without being blocked by user-scoped RLS. User data access is still scoped by passing user_id explicitly to all queries.

Claude clients

Two logical clients, same AsyncAnthropic instance under the hood. Model is specified per-call: Haiku is used wherever the task is classification or extraction (cheap, fast). Sonnet is used wherever reasoning or synthesis is required (higher quality).

APScheduler — background jobs

Three RAG ingestion jobs run automatically:
Each job fetches all users from Supabase, generates a summary string for each, embeds it via the BAAI embedding server, and upserts into user_embeddings.

Environment variables


Health check

Used by nginx upstream checks and monitoring. No auth required.

Production deployment

The full deployment guide is in Self-Hosting → EC2 Deployment. Summary:
  • uvicorn with --workers 1 (single process — in-memory caches are process-local)
  • nginx reverse proxy on port 443, forwards to uvicorn on 8000
  • systemd service for auto-restart on crash
  • Certbot for TLS certificate
For higher load: run multiple workers behind nginx with load balancing, but switch the in-memory cache to Redis to share state across workers.