Metadata-Version: 2.4
Name: superduperfastapi
Version: 0.1.3
Requires-Dist: pydantic>=2,<3
Summary: A from-scratch FastAPI-compatible framework with a Rust core.
Requires-Python: >=3.12
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# superduperfastapi

`superduperfastapi` is a from-scratch, Rust-powered framework that aims to be a
drop-in replacement for FastAPI while moving hot request-path work into Rust.

> [!WARNING]
> This project is in **pre-school-alpha**. Expect bugs, missing edge cases,
> incomplete FastAPI parity, rough packaging, and surprising failures. Do not
> use it for production traffic without your own compatibility and load tests.

> [!IMPORTANT]
> The package is published as `superduperfastapi`. It also ships local `fastapi`
> and `starlette` compatibility shims so existing `from fastapi import FastAPI`
> imports can be tested against this implementation.

> [!NOTE]
> This project was built using Codex's `/goal` feature. The work has been
> tracked as explicit performance and compatibility goals with audits and
> benchmark artifacts along the way.

## Installation

Install from PyPI:

```bash
uv pip install superduperfastapi
```

or:

```bash
pip install superduperfastapi
```

The package depends on Pydantic v2. It does not depend on upstream FastAPI at
runtime.

## Usage

Use the FastAPI-compatible import when testing an existing app:

```python
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    count: int


@app.post("/items")
def create_item(item: Item):
    return {"name": item.name, "total": item.count + 1}
```

Run it with the Rust HTTP server:

```python
from superduperfastapi._core import core

core.run(app, "127.0.0.1", 8000)
```

`core.run(...)` runs in the foreground and handles `Ctrl-C` by asking the Rust
server to stop accepting new connections, drain active requests, and exit.

For explicit lifecycle control:

```python
server = core.start_server(app, "127.0.0.1", 8000)
try:
    print(f"Serving on http://127.0.0.1:{server.port()}")
    server.wait()
finally:
    server.shutdown()
    server.wait()
```

## Drop-In Imports

Native import:

```python
from superduperfastapi import FastAPI
```

FastAPI-compatible import:

```python
from fastapi import FastAPI
```

The long-term goal is for production FastAPI apps to switch package/runtime
plumbing with minimal application-code changes. That goal is not complete yet;
treat every app migration as a compatibility exercise.

## Examples

Runnable examples live in `examples/`. Each example is a standalone
`uv run --script` file with inline dependencies that install
`superduperfastapi` from PyPI and start a local server:

```bash
uv run --script examples/basic.py
uv run --script examples/async_await.py
uv run --script examples/middleware.py
uv run --script examples/html_rendering.py
uv run --script examples/rust_server.py
```

Example requests:

```bash
curl -X POST http://127.0.0.1:8000/items \
  -H "content-type: application/json" \
  -d '{"name":"widget","count":41}'

curl http://127.0.0.1:8004/hello/Ada
```

Set `SUPERDUPERFASTAPI_HOST` or `SUPERDUPERFASTAPI_PORT` to override the default
bind address for any example.

## What Is Fast Today

SuperDuperFastAPI builds Rust route specs for supported routes and dispatches
those routes through the Rust core. Covered fast-path areas include:

- route matching with a Rust route index/trie
- path, query, header, and cookie primitive params
- primitive `application/x-www-form-urlencoded` form params
- primitive multipart `File()` bytes params, `UploadFile` params, and repeated file lists
- JSON request bodies through Pydantic-core validators
- response-model validation and serialization through Pydantic-core
- direct Rust JSON response construction for plain JSON-compatible returns
- built-in JSON, HTML, plain text, redirect, streaming, and file response classes
- sync and async endpoints/dependencies for the covered dependency graph
- request-scope sync/async generator dependencies with teardown on the native path
- `Security(...)` dependencies for API-key, HTTP bearer/basic, OAuth2 password-bearer, and scoped `SecurityScopes` helpers
- simple `StaticFiles(directory=...)` mounts
- direct `Response` returns, background tasks, request injection, and app state
- built-in CORS, GZip, trusted-host, and HTTPS redirect middleware
- user `@app.middleware("http")` routes through Rust dispatch
- custom `add_middleware(...)` ASGI middleware through the Rust bridge
- Rust-side 422 response construction for validation errors

The compatibility matrix records whether each covered feature is `passed`,
`fallback`, `unsupported`, or `broken`.

## Current Gaps

The target is maximum request-path performance while preserving drop-in FastAPI
behavior. Remaining work includes deeper dependency graph optimization,
response-model hot-path tuning, eliminating future fallback areas where
possible, more upstream FastAPI test coverage, and production packaging
hardening.

## Benchmarks

Benchmark summaries are written under `benchmarks/results/`.

| benchmark | summary |
| --- | --- |
| plain JSON | `benchmarks/results/bombardier_summary.md` |
| CRUD endpoint matrix | `benchmarks/results/crud_bombardier_summary.md` |
| dependency graph matrix | `benchmarks/results/dependency_bombardier_summary.md` |
| multipart upload matrix | `benchmarks/results/multipart_bombardier_summary.md` |
| response model matrix | `benchmarks/results/response_model_bombardier_summary.md` |
| security dependency matrix | `benchmarks/results/security_bombardier_summary.md` |
| route count scaling | `benchmarks/results/route_count_bombardier_summary.md` |
| validation-heavy payloads | `benchmarks/results/validation_bombardier_summary.md` |
| OpenAPI generation | `benchmarks/results/openapi_generation_summary.md` |
| JSONable response matrix | `benchmarks/results/jsonable_bombardier_summary.md` |
| user middleware matrix | `benchmarks/results/middleware_bombardier_summary.md` |

Run a benchmark:

```bash
.venv/bin/python benchmarks/run_validation_bombardier.py
.venv/bin/python benchmarks/run_dependency_bombardier.py
.venv/bin/python benchmarks/run_openapi_generation.py
```

## Local Development

Local installation and build steps are for contributors working from this
repository.

Create or use the local virtualenv, then install the Rust extension:

```bash
.venv/bin/python -m pip install maturin
.venv/bin/maturin develop
```

Package build:

```bash
.venv/bin/maturin build --release
```

In this repository, `PYTHONPATH=python` makes `fastapi` resolve to
`python/fastapi`, a compatibility shim that re-exports `superduperfastapi`. When
present locally, the upstream FastAPI checkout in `references/fastapi` is a
behavior and test reference only. Runtime code must not import upstream FastAPI.

## Verification

Local unit suite:

```bash
PYTHONPATH=python .venv/bin/python -m unittest discover -s tests
```

Rust core tests:

```bash
cargo test --manifest-path rust/superduperfastapi-core/Cargo.toml
```

Full recursive FastAPI reference subset:

```bash
.venv/bin/python scripts/run_reference_subset.py references/fastapi/tests
```

Current verified reference result: `3117 passed, 14 skipped, 5 xfailed`.

## Compatibility Audits

```bash
.venv/bin/python scripts/audit_fastapi_compatibility.py
.venv/bin/python scripts/audit_middleware_fast_path.py
.venv/bin/python scripts/audit_validation_errors.py
.venv/bin/python scripts/audit_openapi_parity.py
.venv/bin/python scripts/audit_packaging.py
.venv/bin/python scripts/audit_goal_progress.py
.venv/bin/python scripts/classify_fastapi_features.py
```

These write Markdown and JSON evidence into `benchmarks/results/`. The feature
matrix exits non-zero if any generated row is `broken`.

## Publishing

Publishing is handled by `.github/workflows/publish-pypi.yml`. It publishes only
when a pull request is merged with the `release` label. The published package
name is `superduperfastapi`, and the version is read from `pyproject.toml`.

Configure PyPI trusted publishing for the GitHub repository before running the
workflow. The workflow runs on GitHub releases and can also be started manually
with `workflow_dispatch`.

