Documentation Index
Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
Use this file to discover all available pages before exploring further.
Recipe Serve Advanced Features
This guide covers advanced server features including rate limiting, metrics, admin endpoints, workers, and OpenTelemetry tracing.
Rate Limiting
Protect your server from abuse with configurable rate limiting.
Configuration
from praisonai.recipe.serve import create_app, serve
# Create app with rate limiting
app = create_app(config={
"rate_limit": 100, # 100 requests per minute per client
"rate_limit_exempt_paths": ["/health", "/metrics"]
})
# Or via serve()
serve(
host="127.0.0.1",
port=8765,
config={"rate_limit": 100}
)
Rate Limiter Class
from praisonai.recipe.serve import create_rate_limiter, RateLimiter
# Create rate limiter
limiter = create_rate_limiter(requests_per_minute=100)
# Check if request is allowed
allowed, retry_after = limiter.check("client-ip-or-key")
if not allowed:
print(f"Rate limited. Retry after {retry_after} seconds")
When rate limited, clients receive:
{
"error": {
"code": "rate_limited",
"message": "Too many requests"
}
}
With headers:
Request Size Limits
Prevent oversized payloads from overwhelming your server.
Configuration
from praisonai.recipe.serve import create_app, DEFAULT_MAX_REQUEST_SIZE
# Default is 10MB
print(f"Default max size: {DEFAULT_MAX_REQUEST_SIZE} bytes")
# Custom size limit
app = create_app(config={
"max_request_size": 5 * 1024 * 1024 # 5MB
})
When request is too large:
{
"error": {
"code": "request_too_large",
"message": "Request body too large. Max: 5242880 bytes"
}
}
Metrics Endpoint
Expose Prometheus-format metrics for monitoring.
Enable Metrics
from praisonai.recipe.serve import create_app
app = create_app(config={
"enable_metrics": True
})
Response (Prometheus exposition format):
# HELP praisonai_http_requests_total Total HTTP requests
# TYPE praisonai_http_requests_total counter
praisonai_http_requests_total{path="/health",method="GET",status="200"} 42
# HELP praisonai_http_request_duration_seconds HTTP request duration
# TYPE praisonai_http_request_duration_seconds histogram
praisonai_http_request_duration_seconds_sum{path="/health",method="GET"} 0.123456
praisonai_http_request_duration_seconds_count{path="/health",method="GET"} 42
# HELP praisonai_http_errors_total Total HTTP errors
# TYPE praisonai_http_errors_total counter
praisonai_http_errors_total{path="/v1/recipes/run",method="POST",error_type="client_error"} 5
Using with Prometheus
# prometheus.yml
scrape_configs:
- job_name: 'praisonai-recipe'
static_configs:
- targets: ['localhost:8765']
metrics_path: '/metrics'
Admin Reload Endpoint
Hot-reload recipes without restarting the server.
Enable Admin Endpoints
from praisonai.recipe.serve import create_app
app = create_app(config={
"enable_admin": True,
"auth": "api-key",
"api_key": "admin-secret-key"
})
Reload Recipes
curl -X POST http://localhost:8765/admin/reload \
-H "X-API-Key: admin-secret-key"
Response:
{
"status": "reloaded",
"timestamp": "2024-01-15T10:30:00Z"
}
Programmatic Reload
from praisonai.recipe.core import reload_registry
# Clear cached recipes and reload
reload_registry()
Workers (Multi-Process)
Scale with multiple worker processes.
Configuration
from praisonai.recipe.serve import serve
# Start with 4 workers
serve(
host="0.0.0.0",
port=8765,
workers=4,
config={"auth": "api-key", "api_key": "secret"}
)
Notes
- Workers > 1 automatically disables hot reload
- Each worker has its own rate limiter state (use Redis for distributed limiting)
- Recommended: 2 * CPU cores + 1
OpenTelemetry Tracing
Distributed tracing with OpenTelemetry.
Configuration
from praisonai.recipe.serve import serve
serve(
host="127.0.0.1",
port=8765,
config={
"trace_exporter": "otlp", # otlp, jaeger, zipkin
"otlp_endpoint": "http://localhost:4317",
"service_name": "praisonai-recipe"
}
)
Supported Exporters
| Exporter | Config Key | Default Endpoint |
|---|
| OTLP | otlp_endpoint | http://localhost:4317 |
| Jaeger | jaeger_host, jaeger_port | localhost:6831 |
| Zipkin | zipkin_endpoint | http://localhost:9411/api/v2/spans |
Install Dependencies
# OTLP
pip install opentelemetry-sdk opentelemetry-exporter-otlp
# Jaeger
pip install opentelemetry-sdk opentelemetry-exporter-jaeger
# Zipkin
pip install opentelemetry-sdk opentelemetry-exporter-zipkin
Lazy Import
OpenTelemetry dependencies are lazily imported. If not installed, a warning is logged but the server continues to work.
OpenAPI Specification
Get the OpenAPI spec for your server.
Endpoint
curl http://localhost:8765/openapi.json
Response
{
"openapi": "3.0.3",
"info": {
"title": "PraisonAI Recipe Runner API",
"version": "2.7.1"
},
"paths": {
"/health": {...},
"/v1/recipes": {...},
"/v1/recipes/run": {...},
"/metrics": {...},
"/admin/reload": {...}
}
}
Template Search Paths
Configure where recipes are discovered.
Search Order
PRAISONAI_RECIPE_PATH environment variable
./recipes in current directory
~/.praisonai/recipes in home directory
- Agent-Recipes package (if installed)
- Built-in templates
Get Search Paths
from praisonai.recipe.core import get_template_search_paths
paths = get_template_search_paths()
for path in paths:
print(f"Searching: {path}")
Custom Path
export PRAISONAI_RECIPE_PATH="/custom/recipes:/another/path"
praisonai serve recipe
Complete Example
from praisonai.recipe.serve import serve
# Production-ready configuration
serve(
host="0.0.0.0",
port=8765,
workers=4,
config={
# Authentication
"auth": "api-key",
"api_key": "production-secret-key",
# Rate limiting
"rate_limit": 100,
# Request size
"max_request_size": 10 * 1024 * 1024, # 10MB
# Monitoring
"enable_metrics": True,
"enable_admin": True,
# Tracing
"trace_exporter": "otlp",
"otlp_endpoint": "http://otel-collector:4317",
"service_name": "praisonai-recipe-prod",
# CORS
"cors_origins": "https://app.example.com"
}
)
Configuration Reference
| Key | Type | Default | Description |
|---|
rate_limit | int | 0 (disabled) | Requests per minute per client |
rate_limit_exempt_paths | list | ["/health", "/metrics"] | Paths exempt from rate limiting |
max_request_size | int | 10485760 (10MB) | Maximum request body size |
enable_metrics | bool | false | Enable /metrics endpoint |
enable_admin | bool | false | Enable /admin/* endpoints |
trace_exporter | str | ”none” | Tracing exporter (none, otlp, jaeger, zipkin) |
otlp_endpoint | str | ”http://localhost:4317” | OTLP collector endpoint |
service_name | str | ”praisonai-recipe” | Service name for tracing |
Next Steps