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 an app.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
cd my-service

Implement Your Application

Edit app.py - customize the job processing logic:

from dotenv import load_dotenv
from praisonai_svc import ServiceApp

# Load environment variables from .env file
load_dotenv()

app = ServiceApp("My Service")

@app.job
def process_job(payload: dict) -> tuple[bytes, str, str]:
    """Process job and return file data."""
    # Your processing logic here
    title = payload.get('title', 'Untitled')
    content = f"Processed: {title}\n\nFull payload:\n{payload}"
    
    return (
        content.encode(),  # File content as bytes
        "text/plain",      # Content type
        "result.txt"       # Filename
    )

if __name__ == "__main__":
    app.run(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 the Service

python app.py

Test the API

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

# Check job status (replace {job_id} with actual ID from response)
curl http://localhost:8080/jobs/{job_id}

# Get download URL
curl http://localhost:8080/jobs/{job_id}/download

# Download the result file
curl "$(curl -s http://localhost:8080/jobs/{job_id}/download | jq -r .download_url)"

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 app.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/

Version Management

When incrementing the version, update these files:

  1. pyproject.toml - Line 3: version = "X.Y.Z"
  2. src/praisonai_svc/cli.py - Line 7: @click.version_option(version="X.Y.Z")
  3. tests/AUTOTESTING.md - Lines 445-447: Update version references

Version numbering (Semantic Versioning):

  • Patch (X.Y.Z) - Bug fixes only: 1.2.01.2.1
  • Minor (X.Y.0) - New features, backward compatible: 1.2.01.3.0
  • Major (X.0.0) - Breaking changes: 1.2.02.0.0

Example:

# For a new feature (minor version bump)
# 1. Update pyproject.toml: version = "1.3.0"
# 2. Update cli.py: @click.version_option(version="1.3.0")
# 3. Update AUTOTESTING.md: Framework Version: 1.3.0
# 4. Commit and tag
git commit -am "Bump version to 1.3.0"
git tag v1.3.0

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 app.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/
   ├── app.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 app.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.2.0.tar.gz (142.5 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.2.0-py3-none-any.whl (19.4 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for praisonai_svc-1.2.0.tar.gz
Algorithm Hash digest
SHA256 533e471d48399dd9b0af2b9f5f9019c9283fd304bddb360072fb742de308ff13
MD5 b4e65e2653523633da86f09eb4ef3a4d
BLAKE2b-256 ddea68b987ff4189005c62b6311a9afe3f53b736b19e13506023ae105622b468

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for praisonai_svc-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 db8e737a529a9f1f2db302c0165b8c2024c3e600ff15e82b11530154d5cfc781
MD5 59e0495b45d7ae64152642843423f1f2
BLAKE2b-256 48da2bcc3bc26582cc74ac87fc852d95bf205ee5576fbfc960b1f68b6552e58d

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