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
Codectrait - Unary & server-streaming RPCs — with length-prefixed framing for HTTP/3 streams
- Middleware —
Interceptortrait for auth, logging, tracing, rate limiting - Connection pooling — QUIC-native multiplexing with automatic reconnection
- Retries —
RetryPolicywith 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 (for building Python wheels)
Generate TLS Certificates
QUIC requires TLS. For development, generate a self-signed cert:
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
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?;
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)
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
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)
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
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
# 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_TOKENfor crates.ioPYPI_TOKENfor 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:
| Transport | Throughput | p50 Latency |
|---|---|---|
| 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 for full benchmark results including codec comparisons, Python client/server benchmarks, and external framework comparisons.
License
Apache-2.0
Metadata
Release files for knafeh 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| knafeh-1.1.0-cp314-cp314-manylinux_2_34_x86_64.whl | CPython 3.14 | CPython 3.14 | Linux glibc 2.34+ x86-64 | Details |
| knafeh-1.1.0-cp313-cp313-manylinux_2_34_x86_64.whl | CPython 3.13 | CPython 3.13 | Linux glibc 2.34+ x86-64 | Details |
Total release size: 6.0 MB
Release files / knafeh-1.1.0-cp314-cp314-manylinux_2_34_x86_64.whl
| Download URL | knafeh-1.1.0-cp314-cp314-manylinux_2_34_x86_64.whl |
|---|---|
| Size | 3.0 MB |
| Tags | CPython 3.14 Linux glibc 2.34+ x86-64 |
|
SHA-256 checksum How to use checksums |
b2a0f3e2f08bfdecbb770e929bcc7f04bc8d8b534c89cec8dbc399d31a9f70e9
|
|
BLAKE2b-256 checksum How to use checksums |
a9744727070350dfe18af9a39d7cece0e78bc1c5071e7d4989864d53f0a09575
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / knafeh-1.1.0-cp313-cp313-manylinux_2_34_x86_64.whl
| Download URL | knafeh-1.1.0-cp313-cp313-manylinux_2_34_x86_64.whl |
|---|---|
| Size | 3.0 MB |
| Tags | CPython 3.13 Linux glibc 2.34+ x86-64 |
|
SHA-256 checksum How to use checksums |
d6746f636f38762f9ab737160136117e3495cad5c705b49b5ce072d0b5e4fd1f
|
|
BLAKE2b-256 checksum How to use checksums |
d5027b3689aeaa316d42375c71f0b53c0666cae2b0974b1d9eaec38619e7dab5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|