Recipe Serve Advanced CLI

CLI options for rate limiting, metrics, admin, workers, and tracing

Recipe Serve Advanced CLI

Advanced CLI options for the recipe server including rate limiting, metrics, admin endpoints, workers, and OpenTelemetry tracing.

Quick Reference

bash
praisonai serve recipe \
  --host 0.0.0.0 \
  --port 8765 \
  --auth api-key \
  --workers 4 \
  --rate_limit 100 \
  --max_request_size 10485760 \
  --enable_metrics \
  --enable_admin \
  --trace_exporter otlp

Command Options

OptionDescriptionDefault
--workers <num>Number of worker processes1
--rate_limit <num>Requests per minute per clientdisabled
--max_request_size <bytes>Maximum request body size10485760 (10MB)
--enable_metricsEnable /metrics endpointfalse
--enable_adminEnable /admin/* endpointsfalse
--trace_exporter <type>Tracing: none, otlp, jaeger, zipkinnone

Rate Limiting

Protect your server from abuse.

bash
# Enable rate limiting (100 requests/minute per client)
praisonai serve recipe --rate_limit 100

# Stricter limit for public API
praisonai serve recipe --rate_limit 30 --auth api-key

Test Rate Limiting

bash
# Start server with low limit for testing
praisonai serve recipe --rate_limit 5

# In another terminal, make rapid requests
for i in {1..10}; do
  curl -s http://localhost:8765/v1/recipes | head -c 50
  echo " - Request $i"
done

Expected output after 5 requests:

json
{"error":{"code":"rate_limited","message":"Too many requests"}}

Request Size Limits

Prevent oversized payloads.

bash
# Set 5MB limit
praisonai serve recipe --max_request_size 5242880

# Set 1MB limit for strict environments
praisonai serve recipe --max_request_size 1048576

Test Size Limit

bash
# Start server with small limit
praisonai serve recipe --max_request_size 100

# Send large request
curl -X POST http://localhost:8765/v1/recipes/run \
  -H "Content-Type: application/json" \
  -d '{"recipe": "test", "input": {"data": "'"$(head -c 200 /dev/urandom | base64)"'"}}'

Expected response:

json
{"error":{"code":"request_too_large","message":"Request body too large. Max: 100 bytes"}}

Metrics Endpoint

Expose Prometheus metrics.

bash
# Enable metrics
praisonai serve recipe --enable_metrics

# Verify metrics endpoint
curl http://localhost:8765/metrics

Sample Output

# HELP praisonai_http_requests_total Total HTTP requests
# TYPE praisonai_http_requests_total counter
praisonai_http_requests_total{path="/health",method="GET",status="200"} 5

# 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.025
praisonai_http_request_duration_seconds_count{path="/health",method="GET"} 5

Prometheus Integration

yaml
# prometheus.yml
scrape_configs:
  - job_name: 'praisonai'
    static_configs:
      - targets: ['localhost:8765']
    metrics_path: '/metrics'
    scrape_interval: 15s

Admin Endpoints

Hot-reload recipes without restart.

bash
# Enable admin endpoints (requires auth)
praisonai serve recipe --enable_admin --auth api-key

# Reload recipes
curl -X POST http://localhost:8765/admin/reload \
  -H "X-API-Key: $PRAISONAI_API_KEY"

Response

json
{
  "status": "reloaded",
  "timestamp": "2024-01-15T10:30:00Z"
}

Workers

Scale with multiple processes.

bash
# Start with 4 workers
praisonai serve recipe --workers 4 --auth api-key

# Recommended: 2 * CPU cores + 1
praisonai serve recipe --workers $(( $(nproc) * 2 + 1 )) --auth api-key

As of PraisonAI PR #5231, --workers N > 1 actually spawns N uvicorn worker processes; previously the CLI accepted the flag but silently ran a single worker.

Notes

  • Workers > 1 automatically disables --reload
  • Each worker has independent rate limiter state; --rate_limit is split across workers (rate_limit // workers, floor 1) with a startup warning
  • For distributed rate limiting, use external store (Redis)

OpenTelemetry Tracing

Distributed tracing support.

bash
# OTLP exporter
praisonai serve recipe --trace_exporter otlp

# With custom endpoint
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4317 \
  praisonai serve recipe --trace_exporter otlp

# Jaeger
praisonai serve recipe --trace_exporter jaeger

# Zipkin
praisonai serve recipe --trace_exporter zipkin

Install Dependencies

bash
# For OTLP
pip install opentelemetry-sdk opentelemetry-exporter-otlp

# For Jaeger
pip install opentelemetry-sdk opentelemetry-exporter-jaeger

# For Zipkin
pip install opentelemetry-sdk opentelemetry-exporter-zipkin

OpenAPI Specification

Get the API specification.

bash
# Get OpenAPI spec
curl http://localhost:8765/openapi.json

# Save to file
curl http://localhost:8765/openapi.json > openapi.json

# Pretty print
curl -s http://localhost:8765/openapi.json | python3 -m json.tool

Configuration File

All CLI options can be set in serve.yaml:

yaml
# serve.yaml
host: 0.0.0.0
port: 8765
auth: api-key
api_key: ${PRAISONAI_API_KEY}

# Advanced options
workers: 4
rate_limit: 100
max_request_size: 10485760
enable_metrics: true
enable_admin: true
trace_exporter: otlp
otlp_endpoint: http://otel-collector:4317
service_name: praisonai-recipe

Use with:

bash
praisonai serve recipe --config serve.yaml

Production Examples

Basic Production

bash
export PRAISONAI_API_KEY="your-secret-key"
praisonai serve recipe \
  --host 0.0.0.0 \
  --port 8765 \
  --auth api-key \
  --workers 4 \
  --preload

Full Production

bash
export PRAISONAI_API_KEY="your-secret-key"
praisonai serve recipe \
  --host 0.0.0.0 \
  --port 8765 \
  --auth api-key \
  --workers 4 \
  --rate_limit 100 \
  --max_request_size 10485760 \
  --enable_metrics \
  --enable_admin \
  --trace_exporter otlp \
  --preload

Docker

dockerfile
FROM python:3.11-slim
RUN pip install praisonai[serve]
COPY serve.yaml /app/
WORKDIR /app
EXPOSE 8765
CMD ["praisonai", "recipe", "serve", "--config", "serve.yaml"]

Kubernetes

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: recipe-server
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: server
        image: praisonai-recipe:latest
        args:
        - recipe
        - serve
        - --host=0.0.0.0
        - --port=8765
        - --auth=api-key
        - --workers=2
        - --enable_metrics
        ports:
        - containerPort: 8765
        env:
        - name: PRAISONAI_API_KEY
          valueFrom:
            secretKeyRef:
              name: api-secrets
              key: praisonai-key

Environment Variables

VariableDescription
PRAISONAI_API_KEYAPI key for authentication
PRAISONAI_SERVE_HOSTDefault host
PRAISONAI_SERVE_PORTDefault port
OTEL_EXPORTER_OTLP_ENDPOINTOTLP collector endpoint

Troubleshooting

Rate Limit Not Working

Check if path is exempt:

bash
# /health and /metrics are exempt by default
curl http://localhost:8765/health  # Always works

Metrics Endpoint 404

Enable metrics:

bash
praisonai serve recipe --enable_metrics

Admin Endpoint 401

Provide authentication:

bash
curl -X POST http://localhost:8765/admin/reload \
  -H "X-API-Key: your-key"

Workers with Reload

Cannot use both:

bash
# This will warn and disable reload
praisonai serve recipe --workers 4 --reload

Next Steps