High-performance WSGI/ASGI server powered by Rust
Tsuno aims to be a drop-in replacement for Gunicorn and Uvicorn with a Rust-powered transport layer. Run your Django, Flask, FastAPI, Starlette, and connect-python applications with HTTP/2 support.
pip install tsunotsuno myapp:app --workers 4 --bind 0.0.0.0:8000Flask (WSGI):
from flask import Flask
from tsuno import run
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World"
if __name__ == "__main__":
run(app)FastAPI (ASGI):
from fastapi import FastAPI
from tsuno import run
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
if __name__ == "__main__":
run(app)See examples/ for complete working examples.
- Mixed Protocol Serving: Serve WSGI and ASGI apps simultaneously on the same server (example)
- High Performance: Powered by Tokio and hyper
- API Compatibility: Aims for complete compatibility with both Gunicorn and Uvicorn APIs
- Unix Domain Sockets: Full UDS support for nginx integration (example)
Complete working examples in the examples/ directory:
| Example | Description |
|---|---|
| wsgi_flask_app.py | Flask WSGI application |
| asgi_fastapi_app.py | FastAPI ASGI application |
| mixed_wsgi_asgi.py | Mixed WSGI + ASGI serving (unique to Tsuno!) |
| wsgi_multi_app.py | Multiple Flask apps on different paths |
| asgi_multi_app.py | Multiple FastAPI apps on different paths |
| uds_example.py | Unix Domain Socket server |
| lifespan_test.py | ASGI Lifespan events demo |
| tsuno.toml | TOML configuration example |
# Basic
tsuno myapp:app --bind 0.0.0.0:8000 --workers 4
# With auto-reload (development)
tsuno myapp:app --reload
# With Unix domain socket
tsuno myapp:app --uds /tmp/tsuno.sock
# With configuration file
tsuno myapp:app -c tsuno.tomlPython format (Gunicorn-compatible):
# tsuno.conf.py
bind = "0.0.0.0:8000"
workers = 4
threads = 2
log_level = "info"TOML format:
# tsuno.toml
bind = "0.0.0.0:8000"
workers = 4
threads = 2
log_level = "info"See examples/tsuno.toml for all options.
from tsuno import run
run(
app,
host="0.0.0.0",
port=8000,
workers=4,
reload=True, # Development only
)- Auto-restart crashed workers
- Graceful shutdown and reload
- Worker timeout monitoring
- Max requests per worker (memory leak prevention)
# Start with PID file
tsuno myapp:app --pid /var/run/tsuno.pid
# Graceful reload (no downtime)
kill -HUP $(cat /var/run/tsuno.pid)- Structured logging (text/JSON)
- Access log support
- Customizable log formats
Performance varies by workload, platform, and configuration.
Run wrk or h2load benchmarks to measure performance on your specific hardware.
# Before
gunicorn myapp:app --workers 4 --bind 0.0.0.0:8000
# After (same syntax!)
tsuno myapp:app --workers 4 --bind 0.0.0.0:8000# Before
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000, workers=4)
# After (compatible API!)
import tsuno
tsuno.run(app, host="0.0.0.0", port=8000, workers=4)Tsuno is in early development (alpha stage).
⚠️ Real-world production testing needed
Help us test! Report issues at github.com/i2y/tsuno/issues
- Python 3.11-3.14
- Rust toolchain (for building from source)
- macOS: Fully supported
- Linux: Fully supported
- Windows: Not tested yet
Project Status: Alpha - production testing needed
Not Implemented Yet:
- SSL/TLS support
- CLI daemon mode (Python API supports it via
daemon=True) - Custom
worker_connectionslimits - Error log file redirection
Contributions are welcome! Please:
- Report issues at github.com/i2y/tsuno/issues
- Submit pull requests for bug fixes or new features
- Help improve documentation and examples
MIT License - see LICENSE
- Repository: github.com/i2y/tsuno
- Issues: github.com/i2y/tsuno/issues
Tsuno is inspired by and builds upon excellent work from:
- Gunicorn & Uvicorn: Server standards
- Granian: Rust-Python hybrid architecture
- Tokio, hyper, PyO3: Rust ecosystem