The authenticated, validated, observable entry point to the AtlasAI inference platform. Everything downstream (Inference Engine, LoRA Manager, foundation models) will sit behind this gateway. Week 1 ships the gateway with stubbed generation/embedding services so the API contract is real and testable before the engine exists (Week 2).
- FastAPI app factory (
create_app) with lifespan hooks and versioned/v1routing. - Contract-first endpoints:
POST /v1/generate,POST /v1/embeddings,GET /health,GET /ready. - Typed validation via Pydantic v2 schemas with field constraints.
- API-key auth (
X-API-Key), constant-time comparison, config-driven allow-list. - Structured JSON logging with per-request correlation IDs.
- Centralized error handling returning a consistent error envelope.
- Fixed-window rate limiting (in-memory; Redis-backed in Week 7).
- Python 3.12
cd AtlasAI
python3.12 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements-dev.txt
cp .env.example .env # adjust as neededpython -m api.main
# or:
uvicorn api.main:app --reloadInteractive docs: http://localhost:8000/docs
The gateway is backed by the Inference Engine (inference/). By default it
runs the deterministic mock backend (ATLAS_INFERENCE_BACKEND=mock) so it
works with no GPU. On a CUDA host, install requirements-inference.txt and set
ATLAS_INFERENCE_BACKEND=vllm to serve a real model (default
Qwen/Qwen2.5-0.5B-Instruct). See inference/README.md.
# Full completion
curl -s http://localhost:8000/v1/generate \
-H "Content-Type: application/json" \
-H "X-API-Key: dev-key-local" \
-d '{"model": "qwen2.5-0.5b-instruct", "prompt": "Explain LoRA in one line."}'
# Streaming (Server-Sent Events)
curl -N http://localhost:8000/v1/generate/stream \
-H "Content-Type: application/json" \
-H "X-API-Key: dev-key-local" \
-d '{"model": "qwen2.5-0.5b-instruct", "prompt": "Count to five."}'pytestAll settings use the ATLAS_ prefix (see .env.example). Notable variables:
| Variable | Default | Purpose |
|---|---|---|
ATLAS_ENV |
development |
Environment name. |
ATLAS_LOG_LEVEL |
INFO |
Logging level. |
ATLAS_API_KEYS |
dev-key-local |
Comma-separated accepted API keys. |
ATLAS_RATE_LIMIT_REQUESTS |
60 |
Requests allowed per window. |
ATLAS_RATE_LIMIT_WINDOW_SECONDS |
60 |
Window length in seconds. |
api/ # FastAPI Gateway (HTTP-specific)
main.py # app factory + ASGI entry point (uvicorn api.main:app)
middleware.py # correlation-id/timing + rate-limit middleware
security.py # API-key auth dependency
routers/ # health, generate, embeddings
services/ # Week-1 stub services (replaced by inference/ in Week 2)
shared/ # cross-cutting, component-agnostic building blocks
config.py # Pydantic settings
logging.py # structured JSON logging
context.py # request-id contextvar
errors.py # error types + exception handlers
rate_limit.py # fixed-window limiter (Redis-backed in Week 7)
schemas/ # domain contracts (common, generation, embedding)
orchestrator/ inference/ adapters/ models/ # future components (see each README)
storage/ monitoring/ deployment/ # infra (Postgres/Redis/MLflow, Prometheus/Grafana, Docker/K8s/cloud)
docs/ career/ # engineering docs + portfolio notes
tests/api/ # pytest suite (mirrors source tree)
Dependency direction is acyclic: api / orchestrator / inference / adapters → shared.
shared never imports from a component package.
The stub services (api/services/) expose the exact method signatures the real
Inference Engine (inference/) will implement in Week 2, so routers and tests
remain unchanged as the platform grows.