RYNE
Fast, secure, full-stack Python backend framework with a native Rust core.
Write your entire application in pure Python. RYNE runs the HTTP server (HTTP/1.1 + HTTP/2), routing, JSON, validation, the SQLite driver and cryptography in compiled Rust — and installing it never requires a Rust toolchain:
pip install ryne
Why RYNE
| Goal | How RYNE delivers it |
|---|---|
| Python-only install | Prebuilt wheels (CPython 3.10+, Windows / Linux / macOS, abi3) bundle the Rust core via PyO3. |
| Native Rust core | hyper + tokio event loop, trie router, JSON, schema validation, SQLite and argon2 — all native. |
| Developer experience | Django-style models, migrations, decorators and a CLI. No Rust knowledge needed, ever. |
| Full-stack | REST API, ORM, migrations, authentication, sessions, CSRF — admin panel, templates and WebSockets on the roadmap. |
| Performance-first | Rust owns the socket; Python is invoked exactly once per request. Sync handlers skip the event loop entirely. |
| Security-first | Rate limiting, backpressure, security headers, CSRF, argon2id, parameterized SQL — safe defaults everywhere. |
Benchmarks
11 frameworks × 6 scenarios × 60 seconds per test, oha load generator,
50 concurrent connections, identical endpoints and payloads
(full methodology and complete tables).
| scenario | RYNE | Sanic | Starlette | Litestar | FastAPI | Flask | Django |
|---|---|---|---|---|---|---|---|
| json | 17 929 | 14 532 | 9 180 | 8 059 | 5 629 | 3 942 | 1 578 |
| plaintext | 18 054 | 12 881 | 9 098 | 7 546 | 6 447 | 4 281 | 925 |
| router | 16 765 | 10 984 | 8 168 | 6 861 | 4 641 | 3 995 | 988 |
| http | 14 419 | 12 506 | 7 347 | 6 159 | 4 316 | 3 929 | 1 281 |
| db (SQLite) | 5 883 | 2 162 | 2 104 | 2 520 | 1 625 | 1 488 | 1 323 |
| validation | 6 347 | 9 640 | 6 516 | 5 366 | 4 503 | 3 621 | 1 004 |
| peak RAM (db) | 41 MB | 79 MB | 73 MB | 204 MB | 87 MB | 115 MB | 125 MB |
How to read this. RYNE is the fastest full-featured Python framework in
5 of 6 scenarios (within measurement noise in the 6th) while using the least
memory. Native Rust frameworks (Actix, Axum, Hyper, Rocket — dark bars) are
5–8× faster still: that is the honest price of running user code in Python,
and the trade-off RYNE makes to stay a pure-Python framework. In the
validation scenario Sanic/Starlette edge ahead because their benchmark uses
minimal hand-written checks, while RYNE runs its full Rust schema engine
(parse → coerce → validate → convert).
Quickstart
pip install ryne
ryne startproject mysite
cd mysite
ryne makemigrations && ryne migrate
ryne run
Or in a single file:
from ryne import Ryne
app = Ryne()
@app.get("/hello/{name}")
async def hello(request, name: str):
return {"message": f"Hello, {name}!"}
app.run() # ryne run hello:app
The full stack
Validation — compiled to Rust at import time
import enum
from ryne import HTTPException
from ryne.validation import Schema, Str, Int, List, Enum, Object
class Color(enum.Enum):
RED = "red"
BLUE = "blue"
class Address(Schema):
city: Str(max_length=80)
class CreateArticle(Schema):
title: Str(min_length=1, max_length=200)
tags: List(Str(), max_items=10) = []
views: Int(ge=0) = 0
color: Enum(Color) # -> Color.RED member on output
author: Object(nested=Address) # nested schema
nickname: Str(max_length=30) = None # optional + nullable
@app.post("/articles")
async def create_article(request):
data = CreateArticle.validate(request.json()) # raises ValidationError(422)
...
ORM + migrations — Django-style
from ryne.models import Model, CharField, IntField, ForeignKey
class Article(Model):
title = CharField(max_length=200)
views = IntField(default=0)
author = ForeignKey(Author, null=True)
article = await Article.objects.create(title="Hi")
articles = await Article.objects.filter(views__gte=1).order_by("-id").limit(10)
ryne makemigrations # schema diff -> reviewable Python migration files
ryne migrate # applied atomically, recorded in ryne_migrations
SQLite ships compiled inside the wheel: WAL mode, a read connection pool and a single serialized writer connection (in-process writes never fight over SQLite's one-writer lock). The GIL is released during every query. PostgreSQL is planned.
Auth & sessions
from ryne.auth import authenticate, login, get_user, requires_login
@app.post("/login")
async def login_route(request):
user = await authenticate(request.json()["username"], request.json()["password"])
if user is None:
raise HTTPException(401)
await login(request, user)
return {"ok": True}
@app.get("/me")
@requires_login
async def me(request):
return {"user": (await get_user(request)).username}
Sessions are signed cookies (HMAC-SHA256, constant-time verification in Rust). Passwords are hashed with argon2id in native code.
Security defaults
X-Content-Type-Options,X-Frame-Options,Referrer-Policy,Permissions-Policyon every response- Per-IP rate limiting (token bucket in Rust) →
429+Retry-After - Backpressure:
max_inflightcaps concurrent dispatches → instant503instead of unbounded queues - CSRF tokens for form submissions (JSON APIs unaffected)
- HttpOnly / SameSite cookies, opt-in HSTS and CSP
- 1 MiB request-body limit, enforced mid-stream in Rust
DEBUG=Falseby default — unexpected errors never leak internals
For blocking sync workloads: settings.sync_pool = True runs sync handlers
on a bounded blocking executor (sync_pool_size, default 64) so a slow
handler can never starve the async runtime.
CLI
ryne startproject <name> scaffold a project
ryne run [module:app] run the server (Ctrl+C for graceful shutdown)
ryne makemigrations [--name] generate a migration from model changes
ryne migrate apply pending migrations
ryne createsuperuser create an admin user
ryne shell [module:app] interactive shell with your app loaded
ryne check [module:app] validate configuration
Development
python -m venv .venv && .venv/Scripts/pip install maturin pytest httpx psutil
python -m maturin develop # build the Rust core into the venv
python -m pytest # full test suite
cargo test --workspace # Rust unit tests
See CHANGELOG.md and the issue tracker for the roadmap (admin panel, templates, WebSockets, PostgreSQL).
License
MIT — see LICENSE.
Metadata
Release files for ryne 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ryne-0.2.0.tar.gz | 13.0 MB | Without provenance | Details for ryne-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ryne-0.2.0-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details for ryne-0.2.0-cp310-abi3-win_amd64.whl |
Total release size: 27.5 MB
Release files / ryne-0.2.0.tar.gz
| Download URL | ryne-0.2.0.tar.gz |
|---|---|
| Size | 13.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
515cfc9aa733bbfa66ac93b5313b4db90aa46c3c2e0c8f20ebdbdca859b655f1
|
|
BLAKE2b-256 checksum How to use checksums |
ad1a8d64781a2161048860ef6f049d234f05de1cccc93be85436d03637779446
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / ryne-0.2.0-cp310-abi3-win_amd64.whl
| Download URL | ryne-0.2.0-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 14.5 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
4585c5a9431bca0abd924cbc1f49006e1efc2a0a24fbe03d07675e27af1ac4e4
|
|
BLAKE2b-256 checksum How to use checksums |
fcd3597299be454b22aa732104454361eded79a02bf6c0adee50affee7024f07
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Security for ryne 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.