JustAPI — Python writes the logic. Rust does everything else.

CI Wheels & Release PyPI Python Rust MIT Free-threaded cargo-deny

--- **JustAPI** is a Python web framework with a Rust core. You write Python logic. Rust handles everything else — networking, TLS, routing, validation, serialization, SSE, database I/O, rate limiting. One `pip install`, a server that starts in milliseconds, and numbers that hold up under real traffic. > **Python writes the logic. Rust does everything else.** --- ## Quickstart ```bash pip install justapi ``` ```python # main.py from justapi import JustAPIApp app = JustAPIApp() @app.get("/") def read_root(): return {"Hello": "World"} @app.get("/items/{item_id}") def read_item(item_id: int, q: str | None = None): return {"item_id": item_id, "q": q} app.run() ``` ```console $ python main.py INFO: JustAPI running on http://127.0.0.1:8000 ``` Interactive OpenAPI docs at http://127.0.0.1:8000/docs — generated from your code, zero configuration. ### Async? Native. DB? Native. SSE? Native. ```python import asyncio from justapi import JustAPIApp, native_async app = JustAPIApp() app.set_database("postgres://user:pass@host/db") app.sse_native("/events", count=1000, interval_ms=0) # Rust streams events — 0 Python per event @app.get("/users/{uid}") @native_async async def get_user(request, uid: int): row = await app.db.query_async( # runs on the DB's tokio runtime "SELECT * FROM users WHERE id = ?", [uid]) # GIL released — loop never blocks return row app.run() ``` --- ## Performance

Benchmark — JustAPI vs Granian vs FastAPI vs Robyn

Hello-world, 100 concurrent connections, 30s, same hardware. Full methodology in [BENCHMARKS.md](BENCHMARKS.md). | Framework | Hello-world | JSON echo | p99 hello-world | RSS | |---|--:|--:|--:|--:| | **JustAPI (native fast path)** | **766k req/s** | **782k req/s** | **0.48 ms** | **12 MB** | | Granian (ASGI) | 314k | 145k | 0.74 ms | 37 MB | | Robyn | 39k | — | — | — | | FastAPI + Uvicorn | 36k | 33k | 24.63 ms | 29 MB | More numbers, honestly: - **Route lookup:** 51 ns average on a 500-route table (matchit radix trie) - **Rust-native CRUD:** 181k SELECT req/s — **×125 vs FastAPI** on the same DB fixture - **Native async DB awaits** (`query_async`): **53× faster than the blocking path** on slow queries (320 vs 6 RPS) — the asyncio loop is never blocked - **Multi-worker prefork** (`justapi serve --workers N`): **1.88× throughput at 4 workers** (99.7k RPS), auto-scale included - **Free-threaded CPython (3.14t):** CPU-bound Python handlers **12.4× faster** — the GIL ceiling is gone ### Honest caveats - **Native fast path requires a schema.** Routes without a `Schema` fall back to the Python handler path (~60k req/s). The ~700k numbers apply to routes with `native=True` + `Schema`. - **Python handler throughput is GIL-bound.** On GIL-locked CPython, the Python dispatch path caps at ~100-120k req/s on this hardware regardless of framework — that is the GIL, not a framework limitation. Free-threaded Python (3.14t) removes this ceiling. - **Light async handlers are loop-bound.** Async handlers that only sleep/echo (~4-12k req/s) are capped by the asyncio loop + thread hop. Three experiments (ADR-090/091/092) proved no coroutine driver, bridge, or multi-loop approach beats asyncio's own stepping. We win where it matters: real async workloads (1ms-sleep handlers: 3.9k vs Granian 2.9k RPS) and anything DB/SSE-heavy via native ops. - **LLM-serving claims are NOT part of this release.** Inference phases are unverified (no real GPU run, ADR-067) — the tested story is the web framework. --- ## How a request flows

Request pipeline — Rust end to end

The entire request path runs in Rust. Python executes only your application logic: ``` Kernel (epoll/io_uring) → tokio connection manager → TLS (rustls) → HTTP parse (hyper) → Router (matchit, 51ns) → Middleware chain (auth, CORS, rate-limit, compression) → Python boundary (zero-copy PyO3, GIL pool) → Your async Python handler → Rust serializer (serde_json / simd-json) → Response write → socket ``` Routes marked `native=True` + `Schema` skip Python entirely — Rust validates the body and writes the response. That is the ~700k req/s path. --- ## Feature highlights

Feature matrix

CategoryFeatureDetails
Performance HTTP/1.1 · HTTP/2 · HTTP/3~766k req/s native fast path; QUIC (HTTP/3) is feature-gated — no other Python framework ships it
TLS (rustls)~10% overhead, zero OpenSSL dependency
Serializationserde_json with optional simd-json (89 ns/op)
Compressiongzip / deflate / brotli / zstd
Multi-worker preforkjustapi serve --workers N --scale — shared-socket process fleet with load-based auto-scaling
Native ops Async DB awaitsawait app.db.query_async() — SQL on the DB's tokio runtime, GIL released, loop never blocked (ADR-093)
Rust-native CRUDRust validates + queries + serializes — 181k SELECT req/s, ×125 vs FastAPI
Native SSEapp.sse_native(path, count, interval_ms) — events generated in Rust, zero Python per event
@native_asyncMarks async handlers for the fastest dispatch; true parallel dispatch on free-threaded CPython
Adaptive batchingBatch + window decorator for bursty workloads
Security JWT AuthenticationHS256/RS256/ES256, per-route roles & scopes, OAuth2 password flow
Rate LimitingGCRA, Redis-backed distributed, IP + per-route
CORSConfigurable, preflight caching
Request ValidationJSON Schema compiled in Rust, Pydantic v2 bridge
Security HeadersHSTS, CSP, X-Frame-Options, nosniff, and more
Protocols RESTFull HTTP methods with OpenAPI 3.1
WebSocketFull-duplex with streaming support
Server-Sent EventsGenerator-driven + Rust-native streaming
gRPCNative Tonic integration
GraphQLasync-graphql wiring
Application Dependency InjectionLitestar-style tiered DI, sync/async generators, cleanup
Background TasksThread-safe task scheduling
DatabaseSQLite / PostgreSQL / MySQL / DuckDB via sqlx — pool, migrations, transaction middleware
Template EngineJinja2 integration
File UploadsStreaming multipart/form-data
Operations ObservabilityOpenTelemetry tracing, Prometheus metrics, health checks
ResilienceCircuit breakers, retry, fallback, bulkhead — 44 resilience tests
Hot Reloadjustapi serve --reload with graceful drain
Plugin SystemThird-party extension API with lifecycle hooks
WASM Pluginswasmtime-powered WebAssembly middleware
DX & Quality Type Stubspy.typed + complete .pyi — mypy-clean on user code
Scaffoldingjustapi create — full CRUD project (7 DB backends, 4 API styles) that demos every differentiator
Memory SafetyASan on the full suite + Miri on all unsafe code, 6 fuzz targets
Supply Chaincargo-deny — advisories, bans, licenses, sources
--- ## Coming from FastAPI? JustAPI mirrors FastAPI's decorator API and Pydantic integration, so existing apps migrate with minimal changes — often just the import: | | FastAPI | JustAPI | |---|---|---| | **Import** | `from fastapi import FastAPI` | `from justapi import JustAPIApp` | | **Create** | `app = FastAPI()` | `app = JustAPIApp()` | | **Decorators** | `@app.get("/items/{id}")` | `@app.get("/items/{id}")` | | **Pydantic** | Native | Native | | **Depends()** | Built-in | Built-in (incl. generator deps + cleanup) | | **OpenAPI** | `/docs` and `/redoc` | `/docs` and `/redoc` | | **Server** | uvicorn (Python) | Built-in Rust server (tokio + hyper) | | **Hello-world** | ~36k req/s | **~766k req/s** (native fast path) | 👉 Full [migration guide](docs/migrating_from_fastapi.md). --- ## Architecture ``` justapi/ ├── crates/ │ ├── justapi-core/ # Networking, routing, middleware, serialization │ ├── justapi-py/ # PyO3 bindings + Python package (python/justapi) │ ├── justapi-cli/ # CLI binary (serve, create, check, gen-client) │ └── justapi-bench/ # Internal benchmark harness ├── assets/ # README diagrams (animated SVG) ├── benchmarks/ # Workload scripts for baseline comparisons ├── docs_site/ # Full documentation site (141 pages) ├── skills/ # Reusable engineering knowledge ├── PLAN.md # Living roadmap (single source of truth) ├── DECISIONS.md # Append-only ADR log └── BENCHMARKS.md # Append-only performance ledger ``` Crate dependency graph: ``` justapi-cli ──→ justapi-core justapi-py ──→ justapi-core justapi-bench ─→ justapi-core ``` --- ## Development ### Prerequisites - **Rust** 1.85+ — [install via rustup](https://rustup.rs/) - **Python** 3.11+ — [download](https://www.python.org/downloads/) - **maturin** — `pip install maturin` ### Build & test ```bash cargo build --workspace --release cd crates/justapi-py && maturin develop --release # build the Python package cargo test --workspace # Rust tests cargo clippy --workspace --tests -- -D warnings # lint cargo fmt --check # format cargo deny check # supply-chain audit bash scripts/sanitize.sh # ASan + Miri memory-safety gate python -m pytest # Python tests (in the venv) ``` ### Benchmark ```bash bash benchmarks/run_baselines.sh # FastAPI / Granian / JustAPI A/B ``` See [BENCHMARKS.md](BENCHMARKS.md) for methodology, hardware, and history. --- ## Deployment ```bash # Docker (multi-stage, uv-based — fast reproducible builds) docker build -t justapi-app . docker run -p 8000:8000 justapi-app # Multi-worker + auto-scale (saturate all cores) justapi serve --workers 4 --scale ``` - **Kubernetes:** `helm install my-api helm/justapi/ --set image.repository=your-registry/justapi-app` - **Cloud guides:** [EKS](deploy/clouds/eks.md) · [GKE](deploy/clouds/gke.md) · [AKS](deploy/clouds/aks.md) · [Fly.io](deploy/clouds/flyio.md) · [Railway](deploy/clouds/railway.md) - **Observability:** OTel tracing + Prometheus metrics + health probes out of the box --- ## Documentation | Document | Description | |---|---| | [**docs_site**](docs_site/) | Full documentation site — 141 pages, 13 sections, search | | [**Migration guide**](docs/migrating_from_fastapi.md) | Step-by-step from FastAPI | | [**BENCHMARKS.md**](BENCHMARKS.md) | Performance ledger (append-only) | | [**PLAN.md**](PLAN.md) | Living roadmap and current phase | | [**DECISIONS.md**](DECISIONS.md) | Architecture decision records (ADR-001 → ADR-093) | | [**AGENTS.md**](AGENTS.md) | Development conventions & review checklist | --- ## Contributing Contributions welcome. Read [AGENTS.md](AGENTS.md) for conventions before opening a PR. ```bash git clone git@github.com:swadhinbiswas/JustAPI.git cd JustAPI git checkout -b feat/my-feature # ... make changes ... cargo test --workspace cargo clippy --workspace --tests -- -D warnings cargo fmt --check ``` Every PR is gated on: tests green, clippy `-D warnings`, fmt clean, sanitizers clean (core touched), benchmarks appended (perf touched), ADR recorded (architecture touched). --- ## License [MIT](LICENSE) © JustAPI contributors