All Features Demo¶
This comprehensive demo maps and exercises every major API surface in Cello. It includes routing, async I/O handlers, blueprints, multipart file uploads, session states, security middleware (CORS, logging, compression, headers), dependency injection, background tasks, template rendering, and Prometheus instrumentation.
Features Demonstrated¶
- HTTP CRUD Methods: Exercising GET, POST, PUT, PATCH, and DELETE operations.
- Multipart Data: Retrieving multi-form uploads using the
request.files()handler. - Compression & CORS: Activating standard compression levels and configuring domain origin permissions.
- Background Actions: Scheduling non-blocking tasks with the
BackgroundTasksqueue. - Custom Responses: Utilizing Response subclass helpers for XML, plain text, HTML, and redirects.
Complete Source Code¶
#!/usr/bin/env python3
"""
Cello Framework - ALL FEATURES DEMO
=====================================
This example demonstrates EVERY feature of Cello framework.
Run: python examples/all_features_demo.py
Visit: http://127.0.0.1:8080/
Features demonstrated:
- Core: Routing, Async, Blueprints, WebSocket, SSE, Multipart
- Advanced: Auth, CSRF, Rate Limiting, Sessions, Security Headers
- Extended: DI, Guards, Prometheus, OpenAPI, Background Tasks, Templates
"""
import asyncio
from cello import (
App,
Blueprint,
Response,
BackgroundTasks,
TemplateEngine,
Depends,
)
# =============================================================================
# Initialize App
# =============================================================================
app = App()
# =============================================================================
# MIDDLEWARE - Enable all features
# =============================================================================
# CORS - Cross-Origin Resource Sharing
app.enable_cors(origins=["*"])
# Logging - Request/Response logs
app.enable_logging()
# Compression - Gzip compression for responses
app.enable_compression(min_size=500)
# Prometheus - Metrics at /metrics
app.enable_prometheus(endpoint="/metrics", namespace="cello", subsystem="api")
# =============================================================================
# DEPENDENCY INJECTION (v1.0.1)
# =============================================================================
# Register singletons - shared across all requests
app.register_singleton("database", {
"host": "localhost",
"port": 5432,
"name": "cello_db",
"connected": True
})
app.register_singleton("cache", {
"host": "localhost",
"port": 6379,
"type": "redis"
})
app.register_singleton("config", {
"debug": True,
"version": "1.0.1",
"env": "development"
})
# =============================================================================
# TEMPLATE ENGINE (v1.0.1)
# =============================================================================
templates = TemplateEngine("templates")
# =============================================================================
# BACKGROUND TASKS (v1.0.1)
# =============================================================================
def send_email_task(to: str, subject: str):
"""Background task: Send email after response."""
print(f"[BACKGROUND] 📧 Sending email to {to}: {subject}")
def log_analytics_task(event: str, data: dict):
"""Background task: Log analytics after response."""
print(f"[BACKGROUND] 📊 Analytics: {event} -> {data}")
def cleanup_temp_files_task():
"""Background task: Cleanup temp files."""
print("[BACKGROUND] 🧹 Cleaning up temporary files...")
# =============================================================================
# CORE FEATURE: Basic Routing (GET, POST, PUT, DELETE, PATCH)
# =============================================================================
@app.get("/", tags=["Core"], summary="Home")
def home(request):
"""API Home - Lists all available endpoints."""
return {
"message": "Welcome to Cello Framework - ALL Features Demo!",
"version": "1.0.1",
"features": {
"core": ["/routing", "/async", "/blueprints", "/sse", "/multipart"],
"advanced": ["/auth", "/csrf", "/sessions", "/security"],
"extended": ["/di", "/guards", "/metrics", "/docs", "/templates", "/background"]
},
"endpoints": {
"/docs": "Swagger UI",
"/redoc": "ReDoc",
"/metrics": "Prometheus metrics",
"/health": "Health check"
}
}
@app.get("/health", tags=["Core"], summary="Health Check")
def health_check(request):
"""Health check endpoint."""
return {"status": "healthy", "framework": "cello", "version": "1.0.1"}
# =============================================================================
# CORE FEATURE: Full CRUD Operations
# =============================================================================
@app.get("/users", tags=["Users"], summary="List Users")
def list_users(request):
"""GET - List all users."""
return {
"users": [
{"id": 1, "name": "Alice", "email": "alice@example.com", "role": "admin"},
{"id": 2, "name": "Bob", "email": "bob@example.com", "role": "user"},
{"id": 3, "name": "Charlie", "email": "charlie@example.com", "role": "user"},
]
}
@app.get("/users/{id}", tags=["Users"], summary="Get User")
def get_user(request):
"""GET - Get user by ID."""
user_id = request.params.get("id")
return {
"id": int(user_id),
"name": f"User {user_id}",
"email": f"user{user_id}@example.com"
}
@app.post("/users", tags=["Users"], summary="Create User")
def create_user(request):
"""POST - Create new user."""
data = request.json()
return {"message": "User created", "user": data, "id": 123}
@app.put("/users/{id}", tags=["Users"], summary="Update User")
def update_user(request):
"""PUT - Update user."""
user_id = request.params.get("id")
data = request.json()
return {"message": f"User {user_id} updated", "user": data}
@app.patch("/users/{id}", tags=["Users"], summary="Patch User")
def patch_user(request):
"""PATCH - Partial update user."""
user_id = request.params.get("id")
data = request.json()
return {"message": f"User {user_id} patched", "changes": data}
@app.delete("/users/{id}", tags=["Users"], summary="Delete User")
def delete_user(request):
"""DELETE - Delete user."""
user_id = request.params.get("id")
return {"message": f"User {user_id} deleted"}
# =============================================================================
# CORE FEATURE: Async/Sync Handlers
# =============================================================================
@app.get("/sync", tags=["Core"], summary="Sync Handler")
def sync_handler(request):
"""Synchronous handler (def)."""
return {"type": "sync", "message": "This is a sync handler"}
@app.get("/async", tags=["Core"], summary="Async Handler")
async def async_handler(request):
"""Asynchronous handler (async def)."""
await asyncio.sleep(0.1) # Simulate async I/O
return {"type": "async", "message": "This is an async handler"}
# =============================================================================
# CORE FEATURE: Query Parameters
# =============================================================================
@app.get("/search", tags=["Core"], summary="Search with Query Params")
def search(request):
"""Search with query parameters."""
q = request.query.get("q", "")
page = request.query.get("page", "1")
limit = request.query.get("limit", "10")
sort = request.query.get("sort", "relevance")
return {
"query": q,
"page": int(page),
"limit": int(limit),
"sort": sort,
"results": [f"Result for '{q}' #{i}" for i in range(1, 6)]
}
# =============================================================================
# CORE FEATURE: Response Types (JSON, HTML, Text, Redirect)
# =============================================================================
@app.get("/response/json", tags=["Responses"], summary="JSON Response")
def json_response(request):
"""Default JSON response."""
return {"type": "json", "message": "This is a JSON response"}
@app.get("/response/html", tags=["Responses"], summary="HTML Response")
def html_response(request):
"""HTML response."""
html = """
<!DOCTYPE html>
<html>
<head>
<title>Cello HTML Response</title>
<style>
body { font-family: Arial; padding: 20px; background: #f0f0f0; }
h1 { color: #333; }
.card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
</style>
</head>
<body>
<div class="card">
<h1>🐍 Cello Framework</h1>
<p>This is an HTML response from Cello!</p>
<p><a href="/docs">View API Documentation</a></p>
</div>
</body>
</html>
"""
return Response.html(html)
@app.get("/response/text", tags=["Responses"], summary="Text Response")
def text_response(request):
"""Plain text response."""
return Response.text("This is a plain text response from Cello!")
@app.get("/response/redirect", tags=["Responses"], summary="Redirect")
def redirect_response(request):
"""Redirect to home."""
return Response.redirect("/")
@app.get("/response/custom", tags=["Responses"], summary="Custom Status")
def custom_response(request):
"""Custom status code response."""
return Response.json({"message": "Created resource"}, status=201)
# =============================================================================
# CORE FEATURE: Headers
# =============================================================================
@app.get("/headers", tags=["Core"], summary="Request Headers")
def headers_info(request):
"""Show request headers."""
return {
"your_headers": dict(request.headers),
"user_agent": request.get_header("user-agent"),
"accept": request.get_header("accept"),
"host": request.get_header("host")
}
# =============================================================================
# CORE FEATURE: Request Body Parsing
# =============================================================================
@app.post("/echo", tags=["Core"], summary="Echo Request Body")
def echo_body(request):
"""Echo back the request body."""
try:
data = request.json()
return {"echoed": data, "type": "json"}
except Exception:
body = request.body()
return {"echoed": body.decode() if body else "", "type": "text"}
# =============================================================================
# ADVANCED FEATURE: SSE (Server-Sent Events)
# =============================================================================
@app.get("/sse/info", tags=["SSE"], summary="SSE Info")
def sse_info(request):
"""SSE endpoint information."""
return {
"message": "Server-Sent Events endpoint",
"usage": "Use EventSource in JavaScript",
"example": """
const es = new EventSource('/sse/stream');
es.onmessage = (e) => console.log(e.data);
es.onerror = () => es.close();
"""
}
# =============================================================================
# ADVANCED FEATURE: Multipart / File Uploads
# =============================================================================
@app.post("/upload", tags=["Multipart"], summary="File Upload")
def file_upload(request):
"""Handle file upload (multipart/form-data)."""
try:
# Get multipart data
files = request.files()
return {
"message": "File upload endpoint",
"files_received": len(files) if files else 0,
"note": "Send multipart/form-data with files"
}
except Exception as e:
return {"message": "File upload endpoint", "note": str(e)}
# =============================================================================
# FEATURE: Dependency Injection
# =============================================================================
@app.get("/di/config", tags=["DI"], summary="Get Config (DI)")
def get_config_di(request, config=Depends("config")):
"""Example using Dependency Injection."""
return {
"feature": "Dependency Injection",
"config_available": True,
"note": "Config injected via Depends('config')"
}
@app.get("/di/database", tags=["DI"], summary="Database Status (DI)")
def get_database_di(request):
"""Check database status (singleton)."""
return {
"feature": "Dependency Injection",
"type": "singleton",
"database": {
"host": "localhost",
"port": 5432,
"connected": True
}
}
# =============================================================================
# FEATURE: Background Tasks
# =============================================================================
@app.post("/background/email", tags=["Background"], summary="Send Email (Background)")
def send_email_background(request):
"""Send email as background task."""
data = request.json()
email = data.get("email", "user@example.com")
# Create and run background tasks
tasks = BackgroundTasks()
tasks.add_task(send_email_task, [email, "Welcome to Cello!"])
tasks.add_task(log_analytics_task, ["email_sent", {"email": email}])
tasks.run_all()
return {
"message": "Email queued for sending",
"email": email,
"note": "Check server console for background task output"
}
@app.post("/background/cleanup", tags=["Background"], summary="Cleanup Files (Background)")
def cleanup_background(request):
"""Run cleanup as background task."""
tasks = BackgroundTasks()
tasks.add_task(cleanup_temp_files_task, [])
tasks.run_all()
return {"message": "Cleanup task started in background"}
# =============================================================================
# FEATURE: Template Rendering
# =============================================================================
@app.get("/template/render", tags=["Templates"], summary="Render Template")
def render_template(request):
"""Render a template with context."""
name = request.query.get("name", "Developer")
html = templates.render_string(
"""
<html>
<head><title>Template Demo</title></head>
<body style="font-family: Arial; padding: 20px;">
<h1>Hello, {{ name }}!</h1>
<p>Welcome to <strong>{{ framework }}</strong> v{{ version }}</p>
<ul>
{% for feature in features %}
<li>{{ feature }}</li>
{% endfor %}
</ul>
</body>
</html>
""",
{
"name": name,
"framework": "Cello",
"version": "1.0.1",
"features": ["Dependency Injection", "Guards", "Templates", "Background Tasks"]
}
)
return Response.html(html)
# =============================================================================
# BLUEPRINTS - Modular Route Grouping
# =============================================================================
# Items Blueprint
items_bp = Blueprint("/items", "items")
@items_bp.get("/")
def list_items(request):
"""List all items."""
return {
"items": [
{"id": 1, "name": "Laptop", "price": 999.99, "category": "Electronics"},
{"id": 2, "name": "Mouse", "price": 29.99, "category": "Electronics"},
{"id": 3, "name": "Book", "price": 14.99, "category": "Books"},
]
}
@items_bp.get("/{id}")
def get_item(request):
"""Get item by ID."""
item_id = request.params.get("id")
return {"id": int(item_id), "name": f"Item {item_id}", "price": 99.99}
@items_bp.post("/")
def create_item(request):
"""Create new item."""
data = request.json()
return {"message": "Item created", "item": data}
app.register_blueprint(items_bp)
# API v2 Blueprint
api_v2 = Blueprint("/api/v2", "api_v2")
@api_v2.get("/status")
def v2_status(request):
"""API v2 status."""
return {"api_version": "v2", "status": "active", "deprecated": False}
@api_v2.get("/users")
def v2_users(request):
"""API v2 users endpoint."""
return {"users": [], "version": "v2", "pagination": {"page": 1, "total": 0}}
app.register_blueprint(api_v2)
# =============================================================================
# ADVANCED FEATURE: Session Demo
# =============================================================================
@app.get("/session/info", tags=["Sessions"], summary="Session Info")
def session_info(request):
"""Session information."""
return {
"feature": "Sessions",
"description": "Secure cookie-based session management",
"note": "Enable with app.enable_sessions(secret_key='...')"
}
# =============================================================================
# ADVANCED FEATURE: Security Headers
# =============================================================================
@app.get("/security/headers", tags=["Security"], summary="Security Headers Info")
def security_headers_info(request):
"""Security headers information."""
return {
"feature": "Security Headers",
"available_headers": [
"Content-Security-Policy (CSP)",
"Strict-Transport-Security (HSTS)",
"X-Frame-Options",
"X-Content-Type-Options",
"Referrer-Policy",
"Permissions-Policy"
],
"note": "Enable with app.enable_security_headers()"
}
# =============================================================================
# ADVANCED FEATURE: Rate Limiting
# =============================================================================
@app.get("/ratelimit/info", tags=["Rate Limiting"], summary="Rate Limit Info")
def rate_limit_info(request):
"""Rate limiting information."""
return {
"feature": "Rate Limiting",
"algorithms": ["Token Bucket", "Sliding Window"],
"note": "Enable with app.enable_rate_limiting(requests_per_second=10)"
}
# =============================================================================
# ERROR HANDLING
# =============================================================================
@app.get("/error/test", tags=["Errors"], summary="Test Error")
def error_test(request):
"""Test error handling."""
raise ValueError("This is a test error!")
@app.get("/error/404", tags=["Errors"], summary="Not Found Demo")
def not_found_demo(request):
"""Return 404."""
return Response.json({"error": "Resource not found", "code": 404}, status=404)
@app.get("/error/500", tags=["Errors"], summary="Server Error Demo")
def server_error_demo(request):
"""Return 500."""
return Response.json({"error": "Internal server error", "code": 500}, status=500)
# =============================================================================
# Enable OpenAPI (Auto-generated from all routes above!)
# =============================================================================
app.enable_openapi(title="Cello ALL Features API", version="1.0.1")
# =============================================================================
# Run Server
# =============================================================================
if __name__ == "__main__":
print("\n" + "="*70)
print(" 🐍 CELLO FRAMEWORK - ALL FEATURES DEMO")
print("="*70)
print("\n Core Features:")
print(" - Routing: GET, POST, PUT, PATCH, DELETE")
print(" - Async: /sync, /async")
print(" - Query: /search?q=hello&page=1")
print(" - Responses: /response/json, /response/html, /response/text")
print(" - Blueprints: /items, /api/v2")
print("\n v1.0.1s:")
print(" - Swagger UI: http://127.0.0.1:8080/docs")
print(" - ReDoc: http://127.0.0.1:8080/redoc")
print(" - Metrics: http://127.0.0.1:8080/metrics")
print(" - Templates: /template/render?name=John")
print(" - Background: POST /background/email")
print(" - DI: /di/config, /di/database")
print("\n" + "="*70 + "\n")
app.run(host="127.0.0.1", port=8080)
Running This Example¶
python examples/all_features_demo.py
# Test endpoints:
curl http://127.0.0.1:8080/
curl http://127.0.0.1:8080/health
curl http://127.0.0.1:8080/items/
Key Concepts¶
- Framework Capabilities: Outlines how Cello links together routing logic, session states, security policies, and performance measurements.
- Multipart Data: Retrieving and managing file uploads using the
request.files()multi-form parser. - Background Actions: Running asynchronous jobs using
BackgroundTasks.run_all().