High-Performance Web Framework for Python
Powered by Rust and Axum, Rupy delivers blazing-fast performance with the simplicity and elegance of Python. Build modern web applications with ease.
Combining the performance of Rust with the simplicity of Python
Built on Rust and Axum, Rupy delivers exceptional performance that rivals the fastest web frameworks available.
Intuitive Python API that feels natural. Write clean, readable code with decorators and type hints.
Full support for GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS with convenient decorators.
Define dynamic path parameters with ease using angle brackets. Perfect for RESTful APIs.
Powerful middleware system for authentication, CORS, logging, rate limiting, and more.
Built-in observability with OpenTelemetry for metrics, tracing, and structured logging.
Get started with Rupy in minutes
Add Rupy to your pyproject.toml:
[project]
dependencies = [
"rupy @ git+https://github.com/manoelhc/rupy.git"
]
Then install:
pip install .
For development or customization:
1. Install maturin:
pip install maturin
2. Build and install:
maturin develop
Or for production:
maturin build --release
pip install target/wheels/rupy-*.whl
Build your first Rupy application in seconds
from rupy import Rupy, Request, Response
app = Rupy()
@app.route("/", methods=["GET"])
def index(request: Request) -> Response:
return Response("Hello, World!")
@app.route("/user/<username>", methods=["GET"])
def get_user(request: Request, username: str) -> Response:
return Response(f"User: {username}")
@app.route("/echo", methods=["POST"])
def echo(request: Request) -> Response:
return Response(f"Echo: {request.body}")
if __name__ == "__main__":
app.run(host="127.0.0.1", port=8000)
python app.py
curl http://127.0.0.1:8000/
curl http://127.0.0.1:8000/user/alice
curl -X POST -d '{"name": "test"}' http://127.0.0.1:8000/echo
Everything you need to build powerful web applications
Rupy provides convenient decorators for all HTTP methods:
@app.get("/items")
def list_items(request: Request) -> Response:
return Response("List of items")
@app.post("/items")
def create_item(request: Request) -> Response:
return Response(f"Created: {request.body}")
@app.put("/items/<item_id>")
def update_item(request: Request, item_id: str) -> Response:
return Response(f"Updated item {item_id}")
@app.patch("/items/<item_id>")
def patch_item(request: Request, item_id: str) -> Response:
return Response(f"Patched item {item_id}")
@app.delete("/items/<item_id>")
def delete_item(request: Request, item_id: str) -> Response:
return Response(f"Deleted item {item_id}")
Define dynamic path parameters using angle brackets:
@app.route("/user/<username>", methods=["GET"])
def user_profile(request: Request, username: str) -> Response:
return Response(f"User Profile: {username}")
@app.route("/blog/<author>/<post_id>", methods=["GET"])
def blog_post(request: Request, author: str, post_id: str) -> Response:
return Response(f"Blog post {post_id} by {author}")
@app.route("/products/<category>/<product_id>", methods=["GET"])
def product_details(request: Request, category: str, product_id: str) -> Response:
return Response(f"Product {product_id} in category {category}")
Middlewares execute before route handlers and can inspect, modify, or block requests:
@app.middleware
def logging_middleware(request: Request):
print(f"Processing {request.method} {request.path}")
return request # Continue to next middleware/handler
@app.middleware
def auth_middleware(request: Request):
if request.path.startswith("/admin"):
return Response("Unauthorized", status=401)
return request
Handle cross-origin requests with CORS middleware:
@app.middleware
def cors_middleware(request: Request):
# Handle preflight OPTIONS requests
if request.method == "OPTIONS":
return Response("", status=204)
return request
Protect routes with JWT authentication:
@app.middleware
def jwt_auth_middleware(request: Request):
# Skip auth for public routes
if request.path in ["/", "/login", "/public"]:
return request
# Check for protected routes
if request.path.startswith("/protected"):
# Validate JWT token from headers
return Response(
'{"error": "Unauthorized"}',
status=401
)
return request
Programmatically enable OpenTelemetry:
app = Rupy()
# Enable telemetry with optional configuration
app.enable_telemetry(
endpoint="http://localhost:4317", # OTLP gRPC endpoint
service_name="my-service" # Service name for traces
)
# Check telemetry status
is_enabled = app.is_telemetry_enabled()
# Disable telemetry
app.disable_telemetry()
Configure telemetry using environment variables:
export OTEL_ENABLED=true
export OTEL_SERVICE_NAME=my-service
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export RUST_LOG=info
python app.py
http.server.requests - Total HTTP requests counterhttp.server.duration - Request duration histogramhttp.method - HTTP method (GET, POST, etc.)http.route - Matched route patternhttp.scheme - Protocol scheme (http/https)Learn from real-world examples
Simple GET and POST routes demonstrating the basics of Rupy.
examples/basic_app.py
Complete RESTful API with all HTTP methods (GET, POST, PUT, PATCH, DELETE).
examples/rest_api.py
Demonstrates dynamic path parameters with multiple examples.
examples/dynamic_routes.py
Comprehensive example showing all supported HTTP methods.
examples/all_methods.py
OpenTelemetry integration for metrics, tracing, and logging.
examples/telemetry_example.py
Cross-Origin Resource Sharing (CORS) middleware example.
examples/cors_middleware.py
JWT-based authentication middleware with protected routes.
examples/jwt_middleware.py
Using convenient method-specific decorators (@app.get, @app.post, etc.).
examples/method_decorators.py
Multiple middlewares working together: logging, rate limiting, and auth.
examples/combined_middlewares.py
Powered by Rust and Axum for unmatched speed
Rust-powered backend delivers exceptional performance
Handle thousands of requests with minimal overhead
Battle-tested Axum framework under the hood
wrk -t12 -c400 -d30s http://127.0.0.1:8000/
Designed to outperform traditional Python frameworks like FastAPI and Flask