Skip to main content

A unified framework that turns any PraisonAI Python package into a web service on Azure

Project description

PraisonAI Service Framework

A unified framework that turns any PraisonAI Python package into a web service on Azure using just one file per package.

Features

One-file service creation - Only a handlers.py file needed
Azure-native - Uses Container Apps, Blob Storage, Queue, Table Storage
Cost-predictable - Scale-to-zero, hard-capped replicas (£15-25/month)
Production-ready - Retry logic, idempotency, monitoring
Secure - API keys, rate limiting, CORS
Fast - Built with FastAPI and async/await

Quick Start

Installation

# Using uv (recommended)
uv pip install praisonai-svc

# Using pip
pip install praisonai-svc

Create a New Service

praisonai-svc new my-service --package praisonaippt
cd my-service

Implement Your Handler

Edit handlers.py:

import io
from praisonai_svc import ServiceApp
from praisonaippt import build_ppt

app = ServiceApp("PraisonAI PPT")

@app.job
def generate_ppt(payload: dict) -> tuple[bytes, str, str]:
    """Generate PowerPoint from YAML."""
    buf = io.BytesIO()
    build_ppt(payload, out=buf)
    return (
        buf.getvalue(),
        "application/vnd.openxmlformats-officedocument.presentationml.presentation",
        "slides.pptx",
    )

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app.get_app(), host="0.0.0.0", port=8080)

Configure Environment

Create .env:

PRAISONAI_AZURE_STORAGE_CONNECTION_STRING=your_connection_string
PRAISONAI_API_KEY=your_secret_key

Run Locally

python handlers.py

Test the API

# Create a job
curl -X POST http://localhost:8080/jobs \
  -H "Content-Type: application/json" \
  -d '{"payload": {"title": "My Presentation"}}'

# Check job status
curl http://localhost:8080/jobs/{job_id}

# Download result
curl http://localhost:8080/jobs/{job_id}/download

Local Testing

Test locally in 4 simple steps:

1. Install

pip install praisonai-svc

2. Create Service

praisonai-svc new my-service
cd my-service

3. Set Up Azure (Choose One)

Option A: Local Testing (No Azure Account)

# Install and start Azurite
npm install -g azurite
azurite --silent

# Use this in .env:
PRAISONAI_AZURE_STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;"

Option B: Real Azure

# Get from Azure Portal → Storage Account → Access Keys
PRAISONAI_AZURE_STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;..."

4. Run & Test

# Start service
python handlers.py

# Test (in another terminal)
curl http://localhost:8080/health
curl -X POST http://localhost:8080/jobs \
  -H "Content-Type: application/json" \
  -d '{"payload": {"title": "Test"}}'

That's it! ✅

Architecture

┌─────────────┐
│  WordPress  │
│   Chatbot   │
└──────┬──────┘
       │ POST /jobs
       ▼
┌─────────────────────────────────────┐
│   Azure Container App (FastAPI)     │
│  ┌──────────┐      ┌──────────┐    │
│  │   API    │      │  Worker  │    │
│  └────┬─────┘      └─────┬────┘    │
└───────┼──────────────────┼──────────┘
        │                  │
        ▼                  ▼
   ┌─────────┐        ┌─────────┐
   │  Table  │        │  Queue  │
   │ Storage │        │ Storage │
   └─────────┘        └─────────┘
                           │
                           ▼
                      ┌─────────┐
                      │  Blob   │
                      │ Storage │
                      └─────────┘

API Endpoints

Method Path Description
POST /jobs Create new job
GET /jobs/{id} Get job status
GET /jobs/{id}/download Get fresh download URL
GET /health Health check

Configuration

All configuration via environment variables with PRAISONAI_ prefix:

# Required
PRAISONAI_AZURE_STORAGE_CONNECTION_STRING=...

# Optional
PRAISONAI_API_KEY=secret
PRAISONAI_CORS_ORIGINS=["https://example.com"]
PRAISONAI_MAX_JOB_DURATION_MINUTES=10
PRAISONAI_MAX_RETRY_COUNT=3

Deployment

Azure Container Apps

Quick deploy:

# Build and push image
docker build -t myregistry.azurecr.io/my-service:latest .
docker push myregistry.azurecr.io/my-service:latest

# Deploy to Azure Container Apps
az containerapp create \
  --name my-service \
  --resource-group my-rg \
  --environment my-env \
  --image myregistry.azurecr.io/my-service:latest \
  --target-port 8080 \
  --ingress external \
  --min-replicas 0 \
  --max-replicas 3

Security

Official Package

⚠️ The only official package is: praisonai-svc

Install via:

pip install praisonai-svc

Typosquatting Protection

We maintain a defensive package for common typo:

  • praisonai-svcs (plural) → redirects to praisonai-svc

PyPI's built-in name similarity protection prevents other typosquatting attempts.

Report Security Issues

GitHub Issues: https://github.com/MervinPraison/PraisonAI-SVC/issues

Development

# Clone repository
git clone https://github.com/MervinPraison/PraisonAI-SVC.git
cd praisonai-svc

# Install with dev dependencies
uv pip install -e ".[dev]"

# Run tests
pytest

# Format code
black src/
ruff check src/ --fix

# Type check
mypy src/

Project Structure

praisonai-svc/
├── src/praisonai_svc/          # Main package
│   ├── __init__.py             # Package exports
│   ├── app.py                  # ServiceApp class
│   ├── worker.py               # Worker with exponential backoff
│   ├── cli.py                  # CLI commands
│   ├── models/                 # Data models
│   └── azure/                  # Azure integrations
├── tests/                      # Test suite (20 tests)
├── examples/                   # Example services
├── pyproject.toml              # Package configuration
├── Dockerfile                  # Container image
└── LICENSE                     # MIT License

Key Features

Core Framework

  • ServiceApp class - FastAPI app factory
  • @app.job decorator - Simple handler registration
  • Automatic API generation - 4 endpoints created automatically
  • CORS middleware - Configurable cross-origin support
  • Idempotency - SHA256 JobHash prevents duplicate processing

Azure Integration

  • Blob Storage - File storage with retry logic (3 attempts)
  • Queue Storage - Job queue with poison queue for failures
  • Table Storage - Job state tracking with retry logic
  • SAS URLs - On-demand secure download links (1h expiry)

Reliability

  • Exponential backoff - Worker polling (1s → 30s)
  • Retry logic - Max 3 attempts before poison queue
  • Timeout detection - 10 minute job timeout
  • Error handling - Comprehensive error messages

CLI Commands

praisonai-svc new <name>

Purpose: Create a new service from template

Usage:

praisonai-svc new my-service
# or with package integration
praisonai-svc new my-service --package praisonaippt

What it does:

  1. Creates a new directory with your service name
  2. Generates handlers.py with ServiceApp boilerplate
  3. Creates .env.example with required configuration
  4. Creates README.md with setup instructions
  5. Generates pyproject.toml with dependencies

Output:

✅ Service created: my-service/
   ├── handlers.py
   ├── .env.example
   ├── README.md
   └── pyproject.toml

Next steps after creation:

cd my-service
cp .env.example .env
# Edit .env with your Azure credentials
# Edit handlers.py to implement your logic

praisonai-svc run

Purpose: Run the service locally for development

Usage:

cd my-service
praisonai-svc run

What it does:

  1. Loads environment variables from .env
  2. Starts FastAPI server on http://localhost:8080
  3. Starts worker process for job processing
  4. Enables hot-reload for development

Output:

INFO:     Started server process [12345]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8080

Test it:

# Health check
curl http://localhost:8080/health

# Create a job
curl -X POST http://localhost:8080/jobs \
  -H "Content-Type: application/json" \
  -d '{"payload": {"title": "Test"}}'

praisonai-svc deploy

Purpose: Deploy service to Azure Container Apps

Usage:

cd my-service
praisonai-svc deploy

What it does:

  1. Validates Azure CLI is installed and authenticated
  2. Builds Docker image from your service
  3. Pushes image to Azure Container Registry
  4. Creates/updates Azure Container App
  5. Configures environment variables
  6. Sets up scaling rules (min 0, max 3 replicas)

Prerequisites:

  • Azure CLI installed: brew install azure-cli
  • Logged in: az login
  • Resource group and container registry created

Output:

🔨 Building Docker image...
✅ Image built: myregistry.azurecr.io/my-service:latest

📤 Pushing to Azure Container Registry...
✅ Image pushed

🚀 Deploying to Azure Container Apps...
✅ Deployed: https://my-service.azurecontainerapps.io

📊 Service URL: https://my-service.azurecontainerapps.io

What happens:

  • Service is deployed with scale-to-zero (no cost when idle)
  • Auto-scales based on HTTP requests (0-3 replicas)
  • Environment variables from .env are configured
  • HTTPS endpoint is automatically provisioned

praisonai-svc logs

Purpose: View real-time logs from deployed service

Usage:

cd my-service
praisonai-svc logs

# Follow logs (like tail -f)
praisonai-svc logs --follow

# Show last 100 lines
praisonai-svc logs --tail 100

What it does:

  1. Connects to Azure Container Apps
  2. Streams application logs in real-time
  3. Shows both API and worker logs
  4. Displays timestamps and log levels

Output:

2025-11-04 21:00:15 INFO  [API] Started server
2025-11-04 21:00:20 INFO  [API] POST /jobs - 201 Created
2025-11-04 21:00:21 INFO  [Worker] Processing job abc123
2025-11-04 21:00:25 INFO  [Worker] Job abc123 completed
2025-11-04 21:00:26 INFO  [API] GET /jobs/abc123 - 200 OK

Useful for:

  • Debugging production issues
  • Monitoring job processing
  • Tracking API requests
  • Identifying errors

Testing

# Run all tests
pytest

# Run with coverage
pytest --cov=praisonai_svc

# Run specific test file
pytest tests/test_integration.py -v

Test Results: 20/20 tests passing ✅

Examples

See examples/ directory:

  • examples/ppt-service/ - PowerPoint generation example

Documentation

License

MIT License - see LICENSE file

Contributing

Contributions welcome! Please open an issue or pull request on GitHub.

Support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

praisonai_svc-1.1.0.tar.gz (141.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

praisonai_svc-1.1.0-py3-none-any.whl (18.6 kB view details)

Uploaded Python 3

File details

Details for the file praisonai_svc-1.1.0.tar.gz.

File metadata

  • Download URL: praisonai_svc-1.1.0.tar.gz
  • Upload date:
  • Size: 141.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.22

File hashes

Hashes for praisonai_svc-1.1.0.tar.gz
Algorithm Hash digest
SHA256 ff63827d9babe2858e7227665c12cca01c2a27009f6bdb8e6c68e8aae2746406
MD5 33552cb9e803267f6d9b7203b11e404f
BLAKE2b-256 d03122cc638a191c0ea8a46305c42260a62ae261167ce7e6ec6389de80a98e16

See more details on using hashes here.

File details

Details for the file praisonai_svc-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for praisonai_svc-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 54e9bec2267deb0dd7915a8ff9bfdb93957f4009c1dd10e4919a134c4f79e78d
MD5 c719c45e7a0c3dc8fc15dd8a6f3d719f
BLAKE2b-256 84d1d22033222473e7fcc542f533a100377ce267b493d9e17f7c5377f0e927f0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page