/ justapi / README.md
swadhinbiswas docs: update README tagline to match docs site · 7/25/2026
789ba73
595 lines · 21.0 KB
Raw Download

JustAPI

JustAPI — Built to handle pressure.

CI Wheels Publish License: MIT Python versions Rust version cargo-deny PyPI


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 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 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 for the full, explicitly-labeled future list.

Requirements

  • Python 3.11+
  • Rust 1.85+ (only for building from source)

Installation

From PyPI (recommended)

pip install justapi

With optional features (Pydantic v2, Jinja2, XML):

pip install "justapi[full]"

Via uv (faster)

uv is the recommended Python package manager:

uv pip install justapi
uv pip install "justapi[full]"

Run without installing

uvx justapi create my_app
uvx justapi serve --reload

Build from source

cd crates/justapi-py
maturin develop --release

Example

Create it

Create a file main.py with:

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

$ 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:

{"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:

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:

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

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:

# 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

CategoryFeatureDetails
Performance HTTP/1.1 & HTTP/2700k+ req/s (native fast path)
TLS (rustls)~10% overhead, no OpenSSL dependency
Serializationserde_json with optional simd-json
Compressiongzip / deflate / brotli / zstd
Security JWT AuthenticationRS256/ES256, per-route roles & scopes
Rate LimitingGCRA algorithm, Redis-backed distributed
CORSConfigurable, preflight caching
Request ValidationJSON Schema, Pydantic v2 bridge
Security HeadersHSTS, CSP, X-Frame-Options, etc.
Protocols RESTFull HTTP method support with OpenAPI 3.1
WebSocketFull-duplex with streaming support
Server-Sent EventsToken-generation optimized streaming
gRPCNative Tonic integration
GraphQLasync-graphql with Apollo Federation
Application Dependency InjectionLitestar-style tiered DI container
Background TasksThread-safe task scheduling
Database ORMSQLite / PostgreSQL / MySQL via sqlx
Template EngineJinja2 integration
File UploadsStreaming multipart/form-data
Operations ObservabilityOpenTelemetry tracing, Prometheus metrics
ResilienceCircuit breakers, retry, fallback, bulkhead
Health ChecksLiveness & readiness probe endpoints
Plugin SystemThird-party extension API with lifecycle hooks
WASM Pluginswasmtime-powered WebAssembly middleware
Quality Memory SafetyMiri-verified, 6 fuzz targets
Supply Chain Securitycargo-deny v0.20 — advisories, bans, licenses, sources
Type StubsComplete .pyi for all public modules
Test UtilitiesBuilt-in TestClient & snapshot testing

Coming from FastAPI?

JustAPI is designed to feel familiar. Here's a side-by-side:

FastAPIJustAPI
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

👉 See the full migration guide.

Architecture

justapi/
├── crates/
│   ├── justapi-core/       # Networking, routing, middleware, serialization
│   ├── justapi-py/         # PyO3 bindings, native Python API
│   ├── justapi-cli/        # CLI binary (serve, create, migrate)
│   ├── justapi-bench/      # Internal benchmark harness
│   └── justapi-inference/  # ML inference engine (optional)
├── examples/               # Tutorial examples
├── tests/                  # Integration tests
├── fuzz/                   # cargo-fuzz security targets (6)
├── docs/                   # MkDocs documentation
├── deploy/                 # Cloud deployment guides
├── helm/                   # Kubernetes Helm chart
├── benchmarks/             # Performance workload scripts
└── website/                # Project landing page

Crate dependency graph

justapi-cli  ──→  justapi-core
justapi-py   ──→  justapi-core
justapi-bench ─→  justapi-core

Development

Prerequisites

Building

# Build the workspace
cargo build --workspace

# Build in release mode
cargo build --workspace --release

# Build the Python package (dev mode)
cd crates/justapi-py && maturin develop --release

Testing

# Run all Rust tests
cargo test --workspace

# Lint
cargo clippy --workspace --tests -- -D warnings

# Format check
cargo fmt --check

# Supply chain security audit
cargo deny check

# Memory safety verification (requires nightly)
cargo miri test -p justapi-core

# Python tests
cd crates/justapi-py && python -m pytest

# Python tests with uv
uv run pytest

Benchmarking

# Install load generator
cargo install oha

# Run the baselines (FastAPI, Granian, JustAPI)
bash benchmarks/run_baselines.sh

See BENCHMARKS.md for full methodology, hardware specs, and historical results.

Deployment

Docker (uv-based)

docker build -t justapi-app .
docker run -p 8000:8000 justapi-app

The multi-stage Dockerfile uses uv for fast, reproducible pip installs.

Docker Compose

docker-compose up

Kubernetes (Helm)

helm install my-api helm/justapi/ \
  --set image.repository=your-registry/justapi-app \
  --set image.tag=latest

Cloud platforms

Step-by-step deployment guides are available for:

Documentation

Document Description
Getting Started Installation, first app, and core concepts
API Reference Complete API documentation
Migrating from FastAPI Step-by-step migration guide
Plugin Guide Building and distributing plugins
Security OWASP checklist, pentest guide, disclosure policy
BENCHMARKS.md Performance results (append-only ledger)
PLAN.md Living roadmap and current phase
ROADMAP.md Aspirational future work — explicitly not yet built
DECISIONS.md Architecture decision records
PRODUCTION_PLAN.md 2.0.8 pre-release hardening plan
AGENTS.md Development rules and conventions

Contributing

Contributions are welcome! Please read AGENTS.md for development conventions, commit format, and review checklist before submitting a PR.

# Fork and clone
git clone https://github.com/YOUR_USERNAME/JustAPI.git
cd JustAPI

# Create a branch
git checkout -b feat/my-feature

# Make changes, then run the full check suite
cargo test --workspace
cargo clippy --workspace --tests -- -D warnings
cargo fmt --check
cargo deny check

# Submit a PR

License

This project is licensed under the terms of the MIT License.