v0.6.0 Release Notes¶
Release Date: December 2025
This release brings significant improvements to caching, rate limiting, and data validation, making Cello more suitable for enterprise deployments.
Highlights¶
- Smart Caching - Decorator-based caching with TTL and tag-based invalidation
- Adaptive Rate Limiting - Dynamic limits based on server load
- DTO Validation - Automatic request validation with detailed error responses
- Circuit Breaker - Fault tolerance for external service calls
- Enhanced Guards - Improved RBAC with route and controller-level support
New Features¶
Smart Caching¶
The new @cache decorator provides intelligent response caching:
from cello import App, cache
app = App()
@app.get("/users")
@cache(ttl=300, tags=["users"])
def list_users(request):
# This response is cached for 5 minutes
return {"users": fetch_users_from_db()}
@app.post("/users")
def create_user(request):
user = create_user_in_db(request.json())
# Invalidate the users cache
app.cache.invalidate_tag("users")
return {"user": user}
Features:
- TTL-based expiration
- Tag-based invalidation
- Key generation from request parameters
- Automatic cache headers (ETag, Cache-Control)
Adaptive Rate Limiting¶
Rate limits now adjust based on server health:
from cello.middleware import AdaptiveRateLimitConfig
config = AdaptiveRateLimitConfig(
base_requests=100,
window=60,
cpu_threshold=0.8, # Reduce limits at 80% CPU
memory_threshold=0.9, # Reduce limits at 90% memory
latency_threshold=100, # Reduce limits if latency > 100ms
min_requests=10 # Never go below 10 req/min
)
app.enable_rate_limit(config)
DTO Validation¶
Automatic request body validation with detailed error responses:
from cello import App
from cello.validation import validate_field, Required, Email, MinLength
class CreateUserDTO(DTO):
name: str = Required(MinLength(2))
email: str = Required(Email())
password: str = Required(MinLength(8))
@app.post("/users")
def create_user(request, body: CreateUserDTO):
# body is validated and typed
return {"name": body.name, "email": body.email}
Invalid requests return RFC 7807 Problem Details:
{
"type": "/errors/validation",
"title": "Validation Error",
"status": 422,
"detail": "Request body validation failed",
"errors": [
{"field": "email", "message": "Invalid email format"},
{"field": "password", "message": "Must be at least 8 characters"}
]
}
Circuit Breaker¶
Protect against cascading failures:
from cello.middleware import CircuitBreaker, CircuitBreakerConfig
config = CircuitBreakerConfig(
failure_threshold=5, # Open after 5 failures
recovery_timeout=30, # Try again after 30 seconds
half_open_requests=3 # Allow 3 test requests
)
circuit = CircuitBreaker(config)
@app.get("/external-api")
@circuit.protect
async def call_external(request):
return await external_service.fetch()
Enhanced Guards¶
Guards can now be applied at multiple levels:
from cello import App, Blueprint
from cello.guards import RoleGuard, PermissionGuard
# Controller-level guard
admin_bp = Blueprint("/admin", guards=[RoleGuard(["admin"])])
@admin_bp.get("/dashboard")
def dashboard(request):
return {"admin": True}
# Route-level guard (combined with controller guard)
@admin_bp.delete("/users/{id}", guards=[PermissionGuard(["users:delete"])])
def delete_user(request):
return {"deleted": True}
Improvements¶
Performance¶
- 15% faster JSON parsing through improved SIMD utilization
- 20% lower memory usage with optimized arena allocators
- Reduced middleware overhead through better chain optimization
Security¶
- Improved constant-time comparison for token validation
- Better CSRF token generation using cryptographically secure random
- Enhanced session security with automatic rotation
Developer Experience¶
- Better error messages for configuration issues
- Improved type hints for better IDE support
- More detailed logging in debug mode
Breaking Changes¶
Cache Middleware¶
The cache middleware configuration has changed:
# Before (v0.5.x)
app.enable_cache(max_age=300)
# After (v0.6.0)
from cello.middleware import CacheConfig
config = CacheConfig(default_ttl=300, max_size=1000)
app.enable_cache(config)
Rate Limit Response¶
Rate limit exceeded responses now include more details:
# Before
{"error": "Rate limit exceeded"}
# After
{
"type": "/errors/rate-limit",
"title": "Rate Limit Exceeded",
"status": 429,
"detail": "You have exceeded the rate limit of 100 requests per minute",
"retry_after": 45
}
Bug Fixes¶
- Fixed WebSocket connection cleanup on client disconnect
- Fixed memory leak in long-running SSE connections
- Fixed race condition in concurrent session updates
- Fixed incorrect Content-Length for compressed responses
- Fixed path parameter extraction with special characters
Dependencies Updated¶
| Dependency | Old Version | New Version |
|---|---|---|
| tokio | 1.35 | 1.38 |
| hyper | 1.1 | 1.3 |
| simd-json | 0.12 | 0.13 |
| dashmap | 5.4 | 5.5 |
Migration Guide¶
See the Migration Guide for detailed upgrade instructions.
Quick Migration¶
-
Update your dependency:
-
Update cache middleware (if used):
-
Update rate limit error handling (if you rely on response format)
-
Test your application thoroughly
Contributors¶
Thanks to all contributors who made this release possible!
Full Changelog¶
See the complete changelog for all changes.