# Knafeh
A high-performance QUIC-based RPC framework written in Rust with first-class Python bindings.
Knafeh provides two transport backends — raw QUIC (quinn) for maximum throughput and HTTP/3 (tokio-quiche) for gRPC compatibility — with pluggable codecs, middleware, server-streaming, and connection pooling.
## Features
- **Dual transport** — Raw QUIC (~13K rpc/s) or HTTP/3 (~4K rpc/s), selectable per use case
- **Pluggable codecs** — Protobuf (default), JSON, or implement the `Codec` trait
- **Unary & server-streaming RPCs** — with length-prefixed framing for HTTP/3 streams
- **Middleware** — `Interceptor` trait for auth, logging, tracing, rate limiting
- **Connection pooling** — QUIC-native multiplexing with automatic reconnection
- **Retries** — `RetryPolicy` with exponential backoff, jitter, status-code awareness
- **Python bindings** — Native async (pyo3-async-runtimes) + sync API, anyio structured concurrency
- **gRPC-compatible status codes** — 17 standard codes with proper error propagation
## Quick Start
### Prerequisites
- Rust 1.94+
- Python >= 3.13 (for Python bindings)
- [maturin](https://github.com/PyO3/maturin) (for building Python wheels)
### Generate TLS Certificates
QUIC requires TLS. For development, generate a self-signed cert:
```bash
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \
-keyout key.pem -out cert.pem -days 365 -nodes -subj '/CN=localhost'
```
Tests generate certs automatically via `rcgen` — no manual setup needed.
### Rust — HTTP/3 Server + Client
```rust
use knafeh::server::Server;
use knafeh::codec::JsonCodec;
use knafeh::transport::tls::TlsConfig;
let server = Server::builder()
.bind_str("0.0.0.0:4433")?
.tls(TlsConfig::server("cert.pem", "key.pem"))
.codec(JsonCodec::new())
.add_service(my_service)
.build()?;
server.serve().await?;
```
```rust
use knafeh::client::Client;
use knafeh::codec::JsonCodec;
let client = Client::builder()
.endpoint("localhost:4433")
.codec(JsonCodec::new())
.build()
.await?;
let response = client.call("greeter/say_hello", body).await?;
```
### Rust — Raw QUIC (maximum performance)
```rust
use knafeh::transport::quic_native::{QuicClient, QuicServer};
// Server
let server = QuicServer::bind(addr, &cert_pem, &key_pem, router, codec, middleware)?;
server.serve().await?;
// Client
let client = QuicClient::connect_insecure(addr, codec, middleware).await?;
let response = client.call("echo/echo", body).await?;
```
### Python — Async Client
```python
from knafeh import Client, TlsConfig
async with Client("localhost:4433", tls=TlsConfig.client_insecure()) as client:
response = await client.call("greeter/say_hello", b'{"name": "World"}')
# Batch concurrent calls with structured cancellation (anyio TaskGroup)
responses = await client.call_many("echo/echo", [b'msg1', b'msg2', b'msg3'])
```
### Python — Sync Client (scripts, notebooks)
```python
from knafeh import SyncClient
with SyncClient("localhost:4433") as client:
response = client.call("echo/echo", b"hello")
for chunk in client.server_stream("count/count", b'{"count": 5}'):
print(chunk)
```
### Python — Server
```python
from knafeh import Server, TlsConfig
server = Server("0.0.0.0:4433", tls=TlsConfig.server("cert.pem", "key.pem"))
@server.service("greeter")
class Greeter:
def say_hello(self, request: bytes) -> bytes:
import json
name = json.loads(request)["name"]
return json.dumps({"message": f"Hello, {name}!"}).encode()
await server.serve()
```
## Building & Testing
```bash
# Rust crate (Python bindings are opt-in via the python feature)
cargo build
cargo test
# Python
uv sync --python 3.13 --group dev
PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 uv run maturin develop --features python
uv run pytest tests/test_knafeh.py -v
# Performance benchmarks (release mode)
cargo test --no-default-features --release --test e2e_perf_test -- --ignored --nocapture
```
TLS certificates are generated at runtime via `rcgen` — no manual cert setup needed for tests.
## Releasing
Releases are published by the GitHub Actions release workflow when a semver tag like `v1.0.0` is pushed. Before tagging, update the matching versions in `Cargo.toml` and `pyproject.toml`. For an existing tag, run the workflow manually and provide the tag value.
Required repository secrets:
- `CARGO_REGISTRY_TOKEN` for crates.io
- `PYPI_TOKEN` for PyPI
The workflow publishes the Rust crate and Linux x86_64 PyPI wheels for Python 3.13 and 3.14.
## Performance
Benchmarked on localhost, release mode, 10K sequential requests:
| Raw QUIC (quinn) | **12,680 rpc/s** | **76 us** |
| HTTP/3 (tokio-quiche) | 4,300 rpc/s | 230 us |
Parallel (32 in-flight): Raw QUIC reaches **104K rpc/s**, HTTP/3 reaches **15K rpc/s**.
See [`docs/E2E_TESTING_REPORT_v1.0.0.md`](docs/E2E_TESTING_REPORT_v1.0.0.md) for full benchmark results including codec comparisons, Python client/server benchmarks, and external framework comparisons.
## License
Apache-2.0