Skip to content
swadhinbiswasPublic

About

The speed of Rust with the elegance of Python. A blazingly fast, zero-copy web framework built for extreme throughput

Resources

Contributing

Security policy

Stars

7 stars

Watchers

0 watching

Forks

Latest commit

 

History

271 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

pip install justapi
# 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()
$ 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.

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.

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.


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

Build & test

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 benchmarks/run_baselines.sh                    # FastAPI / Granian / JustAPI A/B

See BENCHMARKS.md for methodology, hardware, and history.


Deployment

# 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 · GKE · AKS · Fly.io · Railway
  • Observability: OTel tracing + Prometheus metrics + health probes out of the box

Documentation

Document Description
docs_site Full documentation site — 141 pages, 13 sections, search
Migration guide Step-by-step from FastAPI
BENCHMARKS.md Performance ledger (append-only)
PLAN.md Living roadmap and current phase
DECISIONS.md Architecture decision records (ADR-001 → ADR-093)
AGENTS.md Development conventions & review checklist

Contributing

Contributions welcome. Read AGENTS.md for conventions before opening a PR.

git clone [email protected]: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 © JustAPI contributors

About

The speed of Rust with the elegance of Python. A blazingly fast, zero-copy web framework built for extreme throughput

Resources

Contributing

Security policy

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages