Metadata-Version: 2.4
Name: ryne
Version: 0.2.0
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Rust
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Typing :: Typed
License-File: LICENSE
Summary: Fast, secure, full-stack Python backend framework with a native Rust core
Keywords: web,framework,backend,rust,http,orm,async
Author: RYNE contributors
License-Expression: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Changelog, https://github.com/ryne-framework/ryne/blob/main/CHANGELOG.md
Project-URL: Homepage, https://github.com/ryne-framework/ryne
Project-URL: Issues, https://github.com/ryne-framework/ryne/issues
Project-URL: Repository, https://github.com/ryne-framework/ryne

# RYNE

<p align="center">
  <a href="https://pypi.org/project/ryne/"><img src="https://img.shields.io/pypi/v/ryne?color=f59e0b" alt="PyPI version"></a>
  <a href="https://pypi.org/project/ryne/"><img src="https://img.shields.io/pypi/pyversions/ryne" alt="Python versions"></a>
  <a href="https://github.com/ryne-framework/ryne/actions/workflows/ci.yml"><img src="https://github.com/ryne-framework/ryne/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
  <a href="https://pypi.org/project/ryne/"><img src="https://img.shields.io/pypi/l/ryne" alt="License"></a>
</p>

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

```bash
pip install ryne
```

<p align="center">
  <img src="https://raw.githubusercontent.com/ryne-framework/ryne/main/docs/benchmarks/benchmark_rps_python.png" alt="RYNE vs Python web frameworks: RPS by scenario" width="780">
</p>

## 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](BENCHMARKS.md)).

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

<p align="center">
  <img src="https://raw.githubusercontent.com/ryne-framework/ryne/main/docs/benchmarks/benchmark_latency.png" alt="Latency percentiles: RYNE has the lowest p50/p95/p99 among Python frameworks" width="780">
</p>

<p align="center">
  <img src="https://raw.githubusercontent.com/ryne-framework/ryne/main/docs/benchmarks/benchmark_all_json.png" alt="Full picture including native Rust frameworks" width="780">
</p>

**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

```bash
pip install ryne
ryne startproject mysite
cd mysite
ryne makemigrations && ryne migrate
ryne run
```

Or in a single file:

```python
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

```python
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

```python
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)
```

```bash
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

```python
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-Policy` on every response
- **Per-IP rate limiting** (token bucket in Rust) → `429` + `Retry-After`
- **Backpressure**: `max_inflight` caps concurrent dispatches → instant `503`
  instead 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=False` by 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

```bash
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](CHANGELOG.md) and the issue tracker for the roadmap
(admin panel, templates, WebSockets, PostgreSQL).

## License

MIT — see [LICENSE](LICENSE).

