rsgi-wsrpc: Reactive Full-Featured Python Framework
"Everything Django should have been, and everything FastAPI forgot."
High-performance asynchronous web framework built on Rust (Granian RSGI) with bidirectional WSRPC (JSON-RPC 2.0), built-in async database ORM, modern authentication, and transactional two-phase file uploading.
🧭 Table of Contents
- Core Philosophy & Manifesto
- Architecture: Core + Plugins + Application
- Comparison: rsgi-wsrpc vs Django vs FastAPI
- 🤖 AI-Native: Token-Efficient & Purpose-Built for LLMs
- Quickstart in 60 Seconds
- Core Network Engine
- Official System Plugins
- Creating Custom Plugins & Modules in the app Directory
- Client Library (TypeScript/JavaScript)
- License
💡 Core Philosophy & Manifesto
The modern web has changed: users no longer tolerate static web pages reloading for hundreds of milliseconds. Users expect instant interactions (1–5 ms), reactive real-time state synchronization, and live progress streaming.
Yet Python developers were forced to choose between two extremes:
- Django — a 20-year-old monolithic design from the Web 2.0 era. Adding websockets and reactivity requires bundling
Django + DRF + Channels + Redis + Celery + Daphne, consuming hundreds of megabytes of RAM per worker. - FastAPI — performant, but trapped in the flat HTTP/1.1 REST paradigm (Request-Response). Every user action opens a new TCP connection, exchanges kilobytes of redundant HTTP headers, and lacks built-in batteries (auth, sessions, file transactions) — forcing developers to stitch together 50 disparate third-party libraries.
rsgi-wsrpc combines the best of both worlds:
- From Rust and Granian — blistering RSGI runtime performance without Python GIL overhead.
- From WSRPC (JSON-RPC 2.0) — a single persistent, multiplexed channel for all operations, symmetric RPC invocation (server can call client), and native multi-return streaming.
- From Django — production-grade batteries (Auth, DB, Two-Phase File uploads) delivered as decoupled, lightweight plugins.
🏛 Architecture: Core + Plugins + Application
The architecture enforces a strict unidirectional dependency hierarchy (Clean Architecture):
┌─────────────────────────────────────────────────────────────────────────┐
│ 1. YOUR APPLICATION (Application) │
│ │
│ Knows about all components: configures application in code (Code-First),
│ activates necessary system plugins, and executes domain business logic
│ Examples: Social Network, CRM, Forum, Customer Portal, IoT Server. │
└────────────────────────────────────┬────────────────────────────────────┘
│ consumes and aggregates
┌────────────────────────────────────▼────────────────────────────────────┐
│ 2. SYSTEM & APPLICATION PLUGINS │
│ │
│ [ Plugin: DB ] [ Plugin: Auth ] [ Plugin: Files ] │
│ Async SQLAlchemy 2.0 Users, JWT, 2PC file streaming, │
│ SQLite / PostgreSQL roles and permissions registry & Nginx offload │
│ │
│ [ Domain Plugins: Forum, Billing, Notifications, Analytics... ] │
└────────────────────────────────────┬────────────────────────────────────┘
│ registers into
┌────────────────────────────────────▼────────────────────────────────────┐
│ 3. NETWORK CORE (Core) │
│ │
│ Pure high-performance socket and RSGI runtime (Granian in Rust). │
│ ZERO knowledge of databases or application domain models. │
│ Responsible for: WSRPC (JSON-RPC 2.0), multi-return, sessions, 2PC. │
└─────────────────────────────────────────────────────────────────────────┘
Core Architectural Rules:
- The Core is Autonomous:
core/contains zero imports from application domains or database models. - Plugins are Modular: Each plugin tackles one concern and registers its handlers via core APIs (
@rpc_method,@on_startup,session.register_on_close). - Application Governs Composition: Need a lightweight microservice without a database? Simply omit the
dbplugin. Need a full-stack portal? Import the complete battery bundle.
📁 Recommended Project Structure (Directory Tree)
Below is the production-tested repository layout, clearly demarcating the network engine (core/), official batteries (app/system/), and custom application modules (app/<modules>/):
my_project/
├── core/ # ⚡ NETWORK CORE (RSGI + WSRPC)
│ ├── lib/
│ │ └── config.py # Code-First configuration & configure()
│ ├── constants.py # System constants and roles (UserRole)
│ ├── lifecycle.py # Async hooks @on_startup and @on_shutdown
│ ├── logger.py # High-performance structured logging
│ ├── router.py # HTTP routing on top of RSGI (@http_route)
│ ├── security.py # Argon2id, JWT tokens, RSA cryptography
│ ├── session.py # JsonRpcSession, @rpc_method, ContextVars, Rate-Limiter
│ └── tabular.py # Deterministic tabular payload compression (RFC 0002, pack_tabular)
│
├── app/ # 📦 APPLICATION & PLUGIN LAYER
│ ├── system/ # 🔌 System Plugins (Official Batteries)
│ │ ├── db.py # Async SQLAlchemy 2.0 engine (async_session, Base)
│ │ ├── broadcast.py # Event broadcaster across active sockets
│ │ ├── auth/ # Users, scopes, and Row-Level Security (RLS)
│ │ │ ├── models.py # Models: User, Role, Permit
│ │ │ ├── handlers.py # RPC methods: auth.*
│ │ │ ├── permissions.py # Scope and role verification logic
│ │ │ └── security.py # Hashing & authorization rules
│ │ ├── login/ # Authentication, RSA handshake, RefreshToken
│ │ │ ├── handlers.py # RPC methods: login.submit, login.refresh, login.whoami
│ │ │ └── db.py # Active sessions and token persistence
│ │ ├── files/ # File metadata registry & storage service
│ │ │ ├── models.py # FileMetadata ORM model
│ │ │ ├── service.py # FileStorageService (quota, schema migration, deletion)
│ │ │ └── handlers.py # HTTP route /upload and RPC methods: files.*
│ │ ├── admin/ # Administration control plane (sessions, cache, users)
│ │ │ └── handlers.py
│ │ └── internal_api/ # Interactive RPC documentation generator
│ │ ├── api.html # Built-in UI sandbox
│ │ ├── handlers.py # API inspection endpoints
│ │ └── generate_docs.py # Docstring and signature parser
│ │
│ └── <business_modules>/ # 🚀 Your application business domains
│ ├── forum/ # Example: Community discussion module
│ │ ├── models.py # Topic, Message, Tag models
│ │ └── handlers.py # RPC methods: forum.get_topics, forum.create_topic
│ ├── billing/ # Example: Billing and invoicing module
│ │ ├── models.py # Invoice, Transaction models
│ │ └── handlers.py # RPC methods: billing.create_invoice, billing.pay
│ └── notifications/ # Example: Real-time notification service
│ └── handlers.py # Push dispatching via broadcast
│
├── client/ # 💻 CLIENT LIBRARIES
│ └── wsrpc.ts # Official TypeScript/JavaScript WSRPC client
│
├── docs/ # 📚 Framework Documentation (EN)
│ ├── readme.md
│ ├── core.md # Comprehensive Core developer guide
│ └── files.md # Two-phase file upload guide (2PC)
│
├── docs_ru/ # 📚 Framework Documentation (RU Twin)
│ ├── readme.md
│ ├── core.md # Comprehensive Core developer guide
│ └── files.md # Two-phase file upload guide (2PC)
│
├── main.py # 🚀 Entrypoint: plugin composition, RSGI application
└── pyproject.toml # 📦 Dependencies and package manifest
⚡ Comparison: rsgi-wsrpc vs Django vs FastAPI
1. Client-Server Interaction Model
Traditional REST (FastAPI / Django):
Every operation re-initiates a TCP/TLS handshake, transfers cookies/headers, and terminates:
[ Client ] ──── TCP + TLS Handshake (50-100 ms) ────► [ Server ]
[ Client ] ──── POST /api/items (Headers + Body) ───► [ Server ]
[ Client ] ◄─── 200 OK (Headers + Body) ──────────── [ Server ] (connection closed)
[ Client ] ──── TCP + TLS Handshake (50-100 ms) ────► [ Server ]
[ Client ] ──── GET /api/user/profile ──────────────► [ Server ]
[ Client ] ◄─── 200 OK ───────────────────────────── [ Server ]
Reactive WSRPC (rsgi-wsrpc):
A single persistent, multiplexed WebSocket channel. Zero handshake latency, instant 1–3 ms roundtrips:
[ Client ] ═════════════════════════════════════════► [ Server ]
(Persistent secure WSRPC socket)
─── id: 1, method: "items.create" ───────► (1 ms)
◄── id: 1, result: { id: 42 } ──────────── (1 ms)
─── id: 2, method: "user.get_profile" ───► (1 ms)
◄── id: 2, result: { name: "Alex" } ────── (1 ms)
◄── SERVER PUSH: method: "notify" ──────── (Server initiates RPC on client!)
2. Feature Matrix
| Feature | Django | FastAPI | rsgi-wsrpc |
|---|---|---|---|
| Network Engine | Python WSGI / slow ASGI | Uvicorn (ASGI) | Granian (Rust RSGI) 🚀 |
| Response Latency | 80–250 ms | 30–120 ms | 1–5 ms |
| Symmetry | ❌ Client ➔ Server only | ❌ Client ➔ Server only | ✅ Client ⇄ Server (Bidirectional) |
| Progress Streaming | ❌ Requires Redis + Channels | ❌ Heavy websocket boilerplate | ✅ Native multi-return (stream: true) |
| RAM Footprint | ~150–250 MB per worker | ~80–120 MB per worker | ~25–40 MB per worker |
| File Transfers | Buffered in worker RAM | Buffered in RAM / SpooledFile | Streaming O(1) RAM + 2PC + Nginx Offload |
| Built-in Auth | ✅ Included (Synchronous) | ❌ None (Roll your own) | ✅ Included (JWT + Refresh + Argon2) |
| Infrastructure | Python + Postgres + Redis + Celery | Python + Postgres + ... | Single Granian binary + SQLite/Postgres |
| AI-Native Engineering | ❌ Highly Inefficient | ⚠️ Moderate (heavy boilerplate) | 🚀 Maximum (AI-Native Architecture) |
| LLM Token Consumption | ~3,000 – 5,000 tokens / feature | ~2,000 – 3,500 tokens / feature | ~300 – 600 tokens (5–10x savings!) |
| Files Touched per Feature | 5–7 files | 4–6 files | 1–2 files (handlers.py + rpc.call) |
| Code Boilerplate | Extreme (DTOs, URLs, views, redux) | High (Pydantic schemas, Depends) | Minimal (clean @rpc_method) |
🤖 AI-Native: Token-Efficient & Purpose-Built for LLMs
rsgi-wsrpc is engineered from the ground up for modern AI-assisted engineering: code authored, reviewed, and refactored by LLMs and Autonomous AI Agents (Claude, Cursor, Gemini, GPT-4o, GitHub Copilot).
In conventional frameworks (FastAPI / Django), up to 80% of generated tokens are squandered on glue code, serialization boilerplate, and redundant plumbing. In rsgi-wsrpc, the unified contract yields massive savings on LLM context windows and developer token budgets.
TOKEN CONSUMPTION FOR IMPLEMENTING A FEATURE (E.G. ADD COMMENT WITH REAL-TIME PUSH)
Django REST: ████████████████████████████████████████ (~4,200 tokens)
FastAPI: █████████████████████████ (~2,600 tokens)
rsgi-wsrpc: ███ (~350 tokens) ──► UP TO 85% TOKEN REDUCTION!
Why AI Writes rsgi-wsrpc Code Faster, More Accurately, and Cheaper:
1. Zero-Boilerplate Simplicity
You no longer need to burn context asking models to generate Pydantic request DTOs, response DTOs, HTTP error handlers, route registration boilerplate, and mirrored frontend fetch() wrappers.
- Backend: One decorator
@rpc_method("domain.action"). User (current_user_ctx) and session context are accessible natively without intricateDepends()dependency graphs. - Frontend: One line:
await rpc.call("domain.action", { ... }).
2. Unified Protocol vs Stack Sprawl
In traditional systems, developers must explain multiple disparate transport layers to the AI: REST for CRUD, WebSockets/SSE for notifications, Redis Pub/Sub for worker tasks, and Multipart for file uploads. Models exhaust their attention budgets and hallucinate.
With rsgi-wsrpc, all communication adheres to one symmetrical protocol WSRPC (JSON-RPC 2.0): queries, mutations, progress streams (stream: true), server push notifications (rpc.on), and interactive server-to-client dialogs (rpc.registerMethod).
3. High Context Locality
Modules in app/<module>/ are strictly decoupled. When assigning an AI agent a feature or bug fix, you only need to provide 1 single file (handlers.py), rather than sprawling architectural files.
- Fewer Input Tokens: Instant, near-zero latency generation from AI agents.
- Higher Precision: Eliminates hallucinations caused by oversized, noisy context windows.
- Direct Cost Reduction: Lowers operational API billing on commercial models.
🚀 Installation & Quickstart
📦 Installation via PIP
Install the minimal core (Granian RSGI, Orjson, WSRPC, Cryptography):
pip install rsgi-wsrpc
Or install with database support and drivers depending on your target stack:
pip install "rsgi-wsrpc[sqlite]" # Async SQLite (aiosqlite + SQLAlchemy 2.0)
pip install "rsgi-wsrpc[postgres]" # Async PostgreSQL (asyncpg + SQLAlchemy 2.0)
pip install "rsgi-wsrpc[mysql]" # Async MySQL (asyncmy + SQLAlchemy 2.0)
pip install "rsgi-wsrpc[full]" # All drivers and plugins included
⚡ Option A: Interactive Showcase Demo (1-Click)
The repository includes a ready-to-run interactive showcase (examples/showcase/):
# Linux / macOS:
./examples/showcase/run.sh
# macOS (without terminal):
# Double-click examples/showcase/run_mac.command directly in Finder!
# Windows (cmd):
examples\showcase\run.bat
# Windows (PowerShell):
.\examples\showcase\run.ps1
The launcher automatically provisions a .venv, installs dependencies, and boots the Granian server. Open http://127.0.0.1:8080 in your browser to inspect real-time WSRPC operations, the reactive database, Tabular payload compression, and streaming progress.
🛠 Option B: Minimal Server (main.py)
from core.session import rpc_method, JsonRpcSession
from core.lifecycle import on_startup
# Register RPC method
@rpc_method("math.add")
async def add_numbers(session: JsonRpcSession, params: dict):
a = params.get("a", 0)
b = params.get("b", 0)
return {"result": a + b}
# Multi-return streaming progress method
@rpc_method("task.run_long")
async def run_task(session: JsonRpcSession, params: dict):
rpc_id = params.get("rpc_id")
for step in range(1, 4):
# Transmit intermediate progress chunk to the socket
await session.send_stream_chunk(rpc_id, {"progress": step * 33})
return {"status": "completed"}
2. Launch Server via Granian
granian --interface rsgi --host 127.0.0.1 --port 8080 main:app
3. Invoke from Client (JavaScript / TypeScript)
import { BinaryWSRPC } from './wsrpc.js';
const client = new BinaryWSRPC('ws://127.0.0.1:8080');
await client.connect();
// Regular RPC call
const sum = await client.call('math.add', { a: 10, b: 25 });
console.log(sum.result); // 35
// Multi-return streaming call
await client.callStream('task.run_long', {}, (chunk) => {
console.log(`Progress: ${chunk.progress}%`);
});
⚙️ Core Network Engine
📖 For the complete technical manual with code examples, see: docs/core.md.
The network core resides in the core/ directory and exposes the following building blocks:
-
JsonRpcSession: Manages persistent client sockets.- Multiplexes incoming and outgoing RPC requests by numeric
id. - Built-in Rate-Limiter (Token Bucket) for protection against flooding (30 req/s) with zero runtime overhead.
- Isolated Python
ContextVarinstances (current_user_ctx,current_session_ctx,current_rpc_id_ctx,current_transport_ctx), accessible anywhere in the async execution context. - Session termination hooks:
session.register_on_close(callback)for clean resource teardown. - Symmetric client invocation from server:
await session.send_request("client_method", params).
-
@http_route(path, methods)decorator to register raw RSGI HTTP handlers.- High-throughput file streams, webhooks, and health checks.
-
- Deterministic tabular payload compression (RFC 0002,
pack_tabular,@tabular_response). - Cuts 50–70% of network traffic by transmitting property schemas once and packing records into a 2D matrix.
- Direct SQL tuple optimization bypasses dictionary allocations, minimizing Python GC overhead.
- Deterministic tabular payload compression (RFC 0002,
-
- Password hashing using Argon2id.
- JWT access token issuance and validation.
- Asymmetric RSA encryption for secure credential exchange.
-
- Application startup dispatcher
@on_startup(runs migrations, cache warming, and background daemons before opening sockets).
- Application startup dispatcher
-
- Settings parser for
settings.yamlsupporting environment variable overrides.
- Settings parser for
🔌 Official System Plugins
The framework includes pre-built and tested system batteries in app/system/:
1. Database Plugin (plugins/db)
- Stack: Async SQLAlchemy 2.0 +
orjsonfor ultra-fast JSON serialization. - Engines: SQLite out-of-the-box (zero configuration). Seamless switch to PostgreSQL via
settings.yaml. - Usage:
from app.system.db import async_session, Base from sqlalchemy import select async with async_session() as db: users = (await db.execute(select(User))).scalars().all()
2. Authentication & User Plugin (plugins/auth)
- Features:
Usermodel, flexible role architecture (dynamic roles inauth_roleDB table, customUserRolesubclasses, superadmin bypass).- Row-Level Security (RLS): base classes
BasicSecureModelandRowSecureModelfor tenant/owner scoping. - Reliable session extension via
RefreshTokenand multi-device tracking inActiveSession. - Context-based user retrieval anywhere without passing parameters:
from core.session import current_user_ctx user = current_user_ctx.get()
3. Two-Phase File Upload Plugin (plugins/files)
- Comprehensive architecture: see docs/files.md.
- Two-Phase Commit Workflow:
- Client initiates upload transaction: server provisions isolated
/tmp/app_uploads/<folder_hash>/. - Client streams files via
POST /upload. Bytes stream directly to disk without memory buffering. - If client disconnects — core triggers
session.on_closeand erases the temp folder immediately. - On completion — folder moves atomically to production storage
/files/<folder_hash>/in 0 milliseconds. - Files are indexed in unified
file_metadatadatabase table (quotas, original names, MIME types). - Downloads are served directly by Nginx with zero Python overhead.
- Client initiates upload transaction: server provisions isolated
4. Smart Reactive Cache Plugin (plugins/smart_cache)
- Comprehensive architecture: see docs/smart_cache.md and RFC 0001.
- 0 ms Latency Principle & Push Invalidation:
- Instant screen rendering from L1 RAM (or L2 IndexedDB/localStorage) with zero network wait.
- Server automatically tracks mutations and pushes
cache.invalidateimpulses or targetedcache.patchvia@invalidates(tags=...). - Zero blind polling — the WebSocket stays completely silent until data actually changes.
- Version handshake (
cache.sync_check) on reconnect syncs only tags that changed during offline state.
5. Modular Backend Test Framework (tests/)
- Comprehensive guide: see docs/testing.md.
- Client-Perspective Black-Box Testing:
- Validates the backend exactly as a real frontend client interacts with it (over WebSocket WSRPC and HTTP).
PersonaManager: pre-authenticated sessions (admin,user,guest) with automatic local database seeding and RLS bypass.- Native verification of streaming (
stream: true), push notification interception (cache.invalidate,cache.patch), and two-phase uploads. - Built-in stress & load testing (
tests/suites/test_load.py): benchmarks RPS, latency percentiles (p50/p95/p99), and broadcast fan-out reliability.
🛠 Creating Custom Plugins & Modules in the app Directory
Creating a custom feature module (e.g. support ticket system app/tickets/) is straightforward:
# app/tickets/handlers.py
from core.session import rpc_method, RPCError, current_user_ctx
from app.system.db import async_session
from app.system.files.service import FileStorageService
@rpc_method("tickets.create")
async def create_ticket(session, params):
user = current_user_ctx.get()
if not user:
raise RPCError("Authentication required")
title = params.get("title")
text = params.get("text")
folder_hash = params.get("folder_hash") # If files were attached
# Persist ticket in database
async with async_session() as db:
async with db.begin():
ticket = Ticket(title=title, text=text, author_id=user.id, folder=folder_hash)
db.add(ticket)
return {"status": "ok", "ticket_id": ticket.id}
@rpc_method("tickets.delete")
async def delete_ticket(session, params):
ticket_id = params.get("ticket_id")
async with async_session() as db:
ticket = await db.get(Ticket, ticket_id)
if ticket and ticket.folder:
# Atomically delete all bundled files from disk and registry
await FileStorageService.delete_bundle(ticket.folder)
await db.delete(ticket)
await db.commit()
return {"deleted": True}
To enable the module, import its handlers in main.py:
# main.py
import app.tickets.handlers # noqa: F401
💻 Client Library (TypeScript/JavaScript)
The framework includes the official zero-dependency client client/wsrpc.ts:
import { BinaryWSRPC, wsConnected, wsStatus } from './wsrpc';
const rpc = new BinaryWSRPC('wss://api.example.com/ws');
await rpc.connect();
// 1. Standard typed RPC call
const profile = await rpc.call<UserProfile>('user.get_profile', { user_id: 42 });
console.log('User profile:', profile.name);
// 2. Multi-return: Progress streaming for long-running workloads
const report = await rpc.callStream<ReportResult>(
'reports.generate',
{ period: '2026-Q3' },
(chunk) => {
console.log(`[${chunk.percent}%] Progress: ${chunk.message}`);
updateProgressBar(chunk.percent); // Real-time UI progress update!
}
);
console.log('Report ready:', report.download_url);
// 3. Receive unsolicited Server Push notifications
const unsubscribe = rpc.on('chat.new_message', (msg) => {
console.log(`[${msg.author}]: ${msg.text}`);
messagesList.update(items => [...items, msg]);
});
// 4. Symmetric RPC: Server initiates an interactive prompt on the client
rpc.registerMethod('ui.confirm', async (params) => {
const isApproved = await showConfirmationModal(params.title, params.message);
return { confirmed: isApproved }; // Transmitted back to the server!
});
📖 For in-depth UI framework integrations (Svelte, React, Vue), error handling, and unsubscription patterns, see: docs/core.md.
📄 License
This project is licensed under the MIT License.
Free for commercial use, modification, and distribution.
Release files for rsgi-wsrpc 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 | |
|---|---|---|---|
| rsgi_wsrpc-0.2.0.tar.gz | 74.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rsgi_wsrpc-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 154.5 kB
Release files / rsgi_wsrpc-0.2.0.tar.gz
| Download URL | rsgi_wsrpc-0.2.0.tar.gz |
|---|---|
| Size | 74.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7f2070b33c0d80da1f1bb4cc20b914383bfc5305627518b54f5ed9653537b68b
|
|
BLAKE2b-256 checksum How to use checksums |
f58af7546f9feefff7d423a806c1b8c46463d0c72dd9153ff465713befdd8139
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / rsgi_wsrpc-0.2.0-py3-none-any.whl
| Download URL | rsgi_wsrpc-0.2.0-py3-none-any.whl |
|---|---|
| Size | 80.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ba734143bda08c5c117cefd901732d49613a24f4a0ac7199a6865080fb69c297
|
|
BLAKE2b-256 checksum How to use checksums |
4fa0ae8abec24b57aa0689208a5fb7e83fbab2522a36b9f6e8586a9a98204c47
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|