A real-time private messaging app built with FastAPI, WebSockets, PostgreSQL, and Redis. Users authenticate via Google OAuth and can send direct messages to each other with full chat history.
- FastAPI — async HTTP + WebSocket server
- PostgreSQL (via SQLAlchemy + asyncpg) — persistent message and user storage
- Redis — session storage + chat history cache (cache-aside pattern)
- Google OAuth 2.0 (via Authlib) — user authentication
- uv — dependency management
Browser ──HTTP──► FastAPI
◄──WS───► /ws (real-time messaging)
│
┌──────┴──────┐
Postgres Redis
(users/msgs) (sessions/cache)
- Sessions are stored in Redis with a 24-hour TTL, keyed by a random token in an
httponlycookie. - Chat history is cached in Redis for 10 minutes (cache-aside). Sending a new message invalidates the cache for that conversation.
- WebSocket connections are tracked in-memory per server instance.
app/
├── main.py # FastAPI app, HTTP routes
├── websocket.py # WebSocket endpoint
├── models.py # SQLAlchemy models + DB lifespan
├── auth.py # OAuth setup, session helpers
├── connect.py # WebSocket connection manager
└── config.py # Pydantic settings
static/
└── index.html # Frontend
docker compose up -dcp .env.example .envFill in your .env:
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/chatdb
REDIS_URL=redis://localhost:6379
GOOGLE_CLIENT_ID=<your-google-client-id>
GOOGLE_CLIENT_SECRET=<your-google-client-secret>
SESSION_SECRET=<long-random-string>
ENV=developmentTo get Google OAuth credentials, create a project at console.cloud.google.com, enable the Google Identity API, and add http://localhost:8000/api/auth/callback as an authorized redirect URI.
uv run uvicorn app.main:app --reloadOpen http://localhost:8000.
| Method | Path | Description |
|---|---|---|
GET |
/api/auth/login |
Redirect to Google OAuth |
GET |
/api/auth/callback |
OAuth callback, sets session cookie |
POST |
/api/auth/logout |
Clear session |
GET |
/api/me |
Current user profile |
GET |
/api/users |
All other users |
GET |
/api/chat/history/{peer_email} |
Chat history with a user |
WS |
/ws |
WebSocket for real-time messaging |
Send:
{ "to": "peer@example.com", "text": "Hello!" }Receive:
{ "sender": "me@example.com", "receiver": "peer@example.com", "text": "Hello!", "timestamp": 1718000000000 }