A small perpetuals exchange backend built with FastAPI, Redis streams, background FastStream services, and SQLAlchemy persistence.
The complete local runtime is managed with Docker Compose.
| Service | Purpose |
|---|---|
postgres |
Local Postgres database container. |
redis |
Redis broker used for streams and service communication. |
fastapi |
HTTP and WebSocket API exposed on port 8000. |
binance |
Publishes market price updates into Redis streams. |
orderbook |
Consumes exchange events and updates order/position state. |
db_ingestor |
Consumes update events and writes projections to the database. |
- Docker
- Docker Compose
uvfor local Python test commands
Create a .env file in the project root before starting the stack.
Required keys:
DATABASE_URL=sqlite+aiosqlite:///./test.db
JWT_SECRET=replace-me
POSTGRES_USER=python_perps
POSTGRES_PASSWORD=python_perps
POSTGRES_DB=python_perps
POSTGRES_PORT=5432The current app code reads DATABASE_URL directly. The included default uses SQLite inside the containers, while the Postgres container is available for local database work and future migration.
Start the whole stack:
make upStart it in the background:
make up-dOpen the API:
http://127.0.0.1:8000
Stop everything:
make downmake help # Show available commands
make build # Build all app images
make up # Build and run the stack
make up-d # Build and run the stack in the background
make logs # Follow logs for all services
make logs SERVICE=fastapi
make ps # Show container status
make restart # Restart the stack
make redis-cli # Open redis-cli in the Redis container
make shell-api # Open a shell in the FastAPI container
make test # Run local tests
make test-e2e # Run e2e tests against Docker Compose
make clean # Stop containers and remove volumes- Clients call the FastAPI service.
- FastAPI publishes exchange events to Redis stream
perps. orderbookconsumesperps, applies exchange logic, and publishes results toperps_updates.- FastAPI and
db_ingestorconsumeperps_updates. - FastAPI pushes live updates over WebSocket, while
db_ingestorstores projections.
Run the normal test suite:
make testRun end-to-end tests:
make test-e2eThe e2e tests recreate the relevant Docker services unless E2E_SKIP_RECREATE=1 is set.
Check resolved Compose configuration:
make configFollow logs for one service:
make logs SERVICE=orderbookReset containers and volumes:
make clean
make upIf port 8000, 6379, or 5432 is already in use, stop the conflicting local process or change the published port in docker-compose.yml.
