JustAPI — Built to handle pressure.
--- **Documentation**: https://github.com/swadhinbiswas/JustAPI/docs_site **Source Code**: https://github.com/swadhinbiswas/JustAPI --- JustAPI is a Python web framework powered by a Rust core. Python writes the logic. Rust handles everything else — networking, TLS, routing, serialization, compression. Built to handle real traffic. **Python writes the logic. Rust does everything else.** ## Performance *Hello-world benchmark · 100 concurrent connections · 30 seconds · same hardware* | Framework | Requests/sec | p50 Latency | p99 Latency | |---|--:|--:|--:| | **JustAPI (native fast path)** | **701,234** | **0.07 ms** | **0.19 ms** | | **JustAPI (Python handler)** | **60,297** | **1.03 ms** | **5.21 ms** | | Robyn 0.88 | 39,103 | 1.78 ms | 11.47 ms | | Granian | 69,195 | 0.72 ms | 3.87 ms | | FastAPI + Uvicorn | 36,189 | 1.72 ms | 24.63 ms | All measurements on the same hardware (i5-13600K, 20 threads), 100 concurrent connections, 30s duration. See [BENCHMARKS.md](BENCHMARKS.md) for full methodology and workload scripts. ### Request pipeline JustAPI runs the entire request path in Rust. Python executes only application logic: ``` Kernel (epoll/io_uring) → Connection Manager (tokio) → TLS termination (rustls) → HTTP parse (hyper) → Router (matchit) → Middleware chain (Rust: auth, CORS, rate-limit, compression) → ┌─────────────────────────────────────────────────────┐ │ Python handler path (default): │ │ → Python boundary (zero-copy via PyO3 buffer) │ │ → Your async Python handler │ │ → Rust serializer (serde_json / simd-json) │ ├─────────────────────────────────────────────────────┤ │ Native fast path (native=True + Schema): │ │ → Rust validator → Rust response (no Python) │ └─────────────────────────────────────────────────────┘ → Response write → Socket ``` The Python path is used for general routes. For schema-backed routes with `native=True`, the entire handler executes in Rust — eliminating the GIL acquire, Python dispatch, and per-request JSON schema compilation. ## What makes JustAPI different 1. **Rust-native request pipeline.** Networking, TLS, routing, serialization, middleware, and auth all execute in Rust — Python runs only your application logic. This yields ~60k rps on the Python handler path and ~724k rps on the native fast path for schema-backed routes, both measured on a single machine. 2. **Agent-native serving.** Beyond REST, JustAPI exposes routes as MCP tools, streams validated structured output per-token, and carries multi-turn session state — without external SDKs. See [`ROADMAP.md`](ROADMAP.md) for the full agent roadmap. ## Competitors, named honestly JustAPI is not the first Rust-backed Python web framework. The following table compares the closest alternatives on raw throughput (Python handler path, same hardware): | Workload | JustAPI | Robyn 0.88 | Faster | |---|---:|---:|---| | Hello-world (GET) | 60,297 rps | 39,103 rps | JustAPI ×1.54 | | JSON echo (POST) | 47,415 rps | 36,899 rps | JustAPI ×1.29 | | Validated JSON (POST) | 40,080 rps | 32,919 rps | JustAPI ×1.22 | For routes registered with `native=True` and a schema, JustAPI serves entirely in Rust at **~724k rps** — bypassing the Python handler entirely. ### Where each competitor fits - **Robyn** — Rust runtime with a decorator API, the closest architectural peer. Both frameworks keep the hot path in Rust and dispatch to Python for business logic. JustAPI's edge is: (a) measured throughput advantage on all three standard workloads, (b) a native fast path (`native=True`) that eliminates the Python dispatch entirely for schema-backed routes, (c) an ASGI shim for compatibility with the Starlette middleware ecosystem, and (d) built-in MCP agent serving as a first-class primitive rather than an add-on. - **Granian** — Rust ASGI *server*. It drops under existing FastAPI/Starlette apps without changing framework code. If your goal is a faster transport layer without migrating frameworks, Granian is the lower-friction choice. JustAPI wins when you want the full Rust stack — routing, serialization, middleware, auth, and agent serving — all native. - **Litestar / BlackSheep** — Python-native frameworks with first-class ASGI support and rich feature sets (DI, validation, OpenAPI). JustAPI shares their design philosophy for ergonomics but implements the critical path in Rust. Migration from these is similar to FastAPI. - **FastAPI** — the compatibility target. JustAPI mirrors its decorator API and Pydantic model integration so existing FastAPI applications can migrate with minimal changes — often just the import statement. ### Honest caveats - **Native fast path requires a schema.** Routes without a `Schema` registered fall back to the Python handler path (~60k rps). The 724k rps number only applies to routes with `native=True` + `Schema`. - **Python handler throughput is GIL-bound.** On CPython, the Python dispatch path is capped at ~100-120k rps on this hardware regardless of framework — that is the GIL, not a framework limitation. Free-threaded Python (3.13t/3.14t) removes this ceiling. - **Agent-native workloads are the differentiator.** The benchmarks that matter most for JustAPI are structured-LLM streaming, MCP tool dispatch, and durable agent sessions — not hello-world req/s. These workloads are impossible or awkward in every alternative listed above. ## Non-goals & not-yet-built JustAPI is **not** trying to be everything in v1. We do not ship a custom edge/WASM runtime, a from-scratch ORM/migrations system, a multi-tenant auth platform, or a new validator (we wrap Pydantic v2 core / JSON Schema). See [`ROADMAP.md`](ROADMAP.md) for the full, explicitly-labeled future list. ## Requirements * **Python 3.11+** * **Rust 1.85+** (only for building from source) ## Installation ### From PyPI (recommended) ```bash pip install justapi ``` With optional features (Pydantic v2, Jinja2, XML): ```bash pip install "justapi[full]" ``` ### Via uv (faster) [uv](https://docs.astral.sh/uv/) is the recommended Python package manager: ```bash uv pip install justapi uv pip install "justapi[full]" ``` ### Run without installing ```bash uvx justapi create my_app uvx justapi serve --reload ``` ### Build from source ```bash cd crates/justapi-py maturin develop --release ``` ## Example ### Create it Create a file `main.py` with: ```python 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} ``` ### Run it ```console $ python main.py INFO: JustAPI running on http://127.0.0.1:8000 INFO: Rust runtime started with 4 worker threads ``` ### Check it Open your browser at http://127.0.0.1:8000/items/5?q=somequery. You will see the JSON response as: ```json {"item_id": 5, "q": "somequery"} ``` You already created an API that: * Receives HTTP requests at the paths `/` and `/items/{item_id}`. * Both paths take `GET` operations (also known as HTTP methods). * The path `/items/{item_id}` has a **path parameter** `item_id` that should be an `int`. * The path `/items/{item_id}` has an optional `str` **query parameter** `q`. ### Interactive API docs Now go to http://127.0.0.1:8000/docs. You will see the automatic interactive API documentation (provided by Swagger UI), auto-generated from your code. ## Example upgrade Now modify the file `main.py` to receive a body from a `PUT` request. Declare the body using standard Python types, thanks to Pydantic: ```python from justapi import JustAPIApp from pydantic import BaseModel app = JustAPIApp() class Item(BaseModel): name: str description: str | None = None price: float tax: float | None = None @app.get("/") def read_root(): return {"Hello": "World"} @app.get("/items/{item_id}") def read_item(item_id: int): return {"item_id": item_id} @app.put("/items/{item_id}") def update_item(item_id: int, item: Item): return {"item_name": item.name, "item_id": item_id, "price_with_tax": item.price + (item.tax or 0)} ``` The server will reload automatically (when using `--reload`). ### Interactive API docs upgrade Now go to http://127.0.0.1:8000/docs. * The interactive API documentation will be automatically updated, including the new body. * Click on the "Try it out" button, it allows you to fill the parameters and directly interact with the API. * Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen. ### Alternative API docs And now go to http://127.0.0.1:8000/redoc. * The alternative documentation will also reflect the new query parameter and body. ## Example with dependencies JustAPI supports FastAPI-style dependency injection: ```python from justapi import JustAPIApp, Depends app = JustAPIApp() def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100): return {"q": q, "skip": skip, "limit": limit} @app.get("/items/") def read_items(commons: dict = Depends(common_parameters)): return {"message": "Reading items", "params": commons} @app.get("/users/") def read_users(commons: dict = Depends(common_parameters)): return {"message": "Reading users", "params": commons} ``` ## Example with WebSockets ```python from justapi import JustAPIApp app = JustAPIApp() @app.websocket("/ws") async def websocket_endpoint(ws): await ws.accept() while True: data = await ws.receive_text() await ws.send_text(f"Echo: {data}") ``` ## Project Scaffolding CLI JustAPI includes an interactive project generator to create production-ready applications with zero boilerplate: ```bash # Interactive project creation (prompts for DB engine and API architecture): justapi create my_app # Or specify flags directly: justapi create analytics_app --db duckdb --api-type rest justapi create graph_app --db postgres --api-type graphql justapi create rpc_service --db redis --api-type grpc justapi create jsonrpc_api --db sqlite --api-type jsonrpc ``` ### Supported Backends & Protocols: * **Databases:** Transactional SQL (`sqlite`, `postgres`, `mysql`), Analytical OLAP (`duckdb`, `clickhouse`), NoSQL (`mongodb`, `redis`). * **Protocols:** REST (OpenAPI 3.1), GraphQL (GraphiQL UI), gRPC (Protobuf), JSON-RPC 2.0. * **Observability:** Includes pre-built OpenTelemetry & Jaeger stack (`docker-compose.otel.yml`). ## Features| Category | Feature | Details |
|---|---|---|
| Performance | HTTP/1.1 & HTTP/2 | 700k+ req/s (native fast path) |
| TLS (rustls) | ~10% overhead, no OpenSSL dependency | |
| Serialization | serde_json with optional simd-json | |
| Compression | gzip / deflate / brotli / zstd | |
| Security | JWT Authentication | RS256/ES256, per-route roles & scopes |
| Rate Limiting | GCRA algorithm, Redis-backed distributed | |
| CORS | Configurable, preflight caching | |
| Request Validation | JSON Schema, Pydantic v2 bridge | |
| Security Headers | HSTS, CSP, X-Frame-Options, etc. | |
| Protocols | REST | Full HTTP method support with OpenAPI 3.1 |
| WebSocket | Full-duplex with streaming support | |
| Server-Sent Events | Token-generation optimized streaming | |
| gRPC | Native Tonic integration | |
| GraphQL | async-graphql with Apollo Federation | |
| Application | Dependency Injection | Litestar-style tiered DI container |
| Background Tasks | Thread-safe task scheduling | |
| Database ORM | SQLite / PostgreSQL / MySQL via sqlx | |
| Template Engine | Jinja2 integration | |
| File Uploads | Streaming multipart/form-data | |
| Operations | Observability | OpenTelemetry tracing, Prometheus metrics |
| Resilience | Circuit breakers, retry, fallback, bulkhead | |
| Health Checks | Liveness & readiness probe endpoints | |
| Plugin System | Third-party extension API with lifecycle hooks | |
| WASM Plugins | wasmtime-powered WebAssembly middleware | |
| Quality | Memory Safety | Miri-verified, 6 fuzz targets |
| Supply Chain Security | cargo-deny v0.20 — advisories, bans, licenses, sources | |
| Type Stubs | Complete .pyi for all public modules | |
| Test Utilities | Built-in TestClient & snapshot testing |
| FastAPI | JustAPI | |
|---|---|---|
| Import | from fastapi import FastAPI |
from justapi import JustAPIApp |
| Create app | app = FastAPI() |
app = JustAPIApp() |
| Decorators | @app.get("/items/{id}") |
@app.get("/items/{id}") |
| Pydantic | Native | Native |
| Depends() | Built-in | Built-in |
| OpenAPI docs | /docs and /redoc |
/docs and /redoc |
| Server | uvicorn (Python) | Built-in Rust server (hyper + tokio) |
| Performance | ~36k req/s | ~700k req/s |