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 topraisonai-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:
- Creates a new directory with your service name
- Generates
handlers.pywith ServiceApp boilerplate - Creates
.env.examplewith required configuration - Creates
README.mdwith setup instructions - Generates
pyproject.tomlwith 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:
- Loads environment variables from
.env - Starts FastAPI server on
http://localhost:8080 - Starts worker process for job processing
- 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:
- Validates Azure CLI is installed and authenticated
- Builds Docker image from your service
- Pushes image to Azure Container Registry
- Creates/updates Azure Container App
- Configures environment variables
- 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
.envare 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:
- Connects to Azure Container Apps
- Streams application logs in real-time
- Shows both API and worker logs
- 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
- PRD - Complete product requirements
- GitHub: https://github.com/MervinPraison/PraisonAI-SVC
- Issues: https://github.com/MervinPraison/PraisonAI-SVC/issues
License
MIT License - see LICENSE file
Contributing
Contributions welcome! Please open an issue or pull request on GitHub.
Support
- GitHub Issues: https://github.com/MervinPraison/PraisonAI-SVC/issues
- Documentation: https://mervinpraison.github.io/PraisonAI-SVC
- Website: https://praison.ai
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff63827d9babe2858e7227665c12cca01c2a27009f6bdb8e6c68e8aae2746406
|
|
| MD5 |
33552cb9e803267f6d9b7203b11e404f
|
|
| BLAKE2b-256 |
d03122cc638a191c0ea8a46305c42260a62ae261167ce7e6ec6389de80a98e16
|
File details
Details for the file praisonai_svc-1.1.0-py3-none-any.whl.
File metadata
- Download URL: praisonai_svc-1.1.0-py3-none-any.whl
- Upload date:
- Size: 18.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.22
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54e9bec2267deb0dd7915a8ff9bfdb93957f4009c1dd10e4919a134c4f79e78d
|
|
| MD5 |
c719c45e7a0c3dc8fc15dd8a6f3d719f
|
|
| BLAKE2b-256 |
84d1d22033222473e7fcc542f533a100377ce267b493d9e17f7c5377f0e927f0
|