Endpoints - Python Usage
This guide covers how to interact with recipe endpoints programmatically using Python and other languages.Python SDK
Basic Usage
Copy
from praisonai import recipe
# List available recipes
recipes = recipe.list_recipes()
for r in recipes:
print(f"{r.name} ({r.version}): {r.description}")
# Get recipe details
info = recipe.describe("my-recipe")
print(f"Name: {info.name}")
print(f"Schema: {info.config_schema}")
# Run a recipe
result = recipe.run(
"my-recipe",
input={"query": "Hello, world!"},
options={"timeout_sec": 60}
)
if result.ok:
print(f"Output: {result.output}")
else:
print(f"Error: {result.error}")
Streaming Results
Copy
from praisonai import recipe
for event in recipe.run_stream(
"my-recipe",
input={"query": "Generate a story"}
):
if event.event_type == "started":
print(f"Started: {event.data['run_id']}")
elif event.event_type == "progress":
print(f"Progress: {event.data['message']}")
elif event.event_type == "completed":
print(f"Done: {event.data['status']}")
Error Handling
Copy
from praisonai import recipe
from praisonai.recipe.exceptions import (
RecipeError,
RecipeNotFoundError,
RecipeTimeoutError,
RecipePolicyError
)
try:
result = recipe.run("my-recipe", input={"query": "test"})
except RecipeNotFoundError as e:
print(f"Recipe not found: {e.recipe}")
except RecipeTimeoutError as e:
print(f"Timeout after {e.timeout_sec}s")
except RecipePolicyError as e:
print(f"Policy denied: {e.policy}")
except RecipeError as e:
print(f"Recipe error: {e}")
Configuration Options
Copy
from praisonai import recipe
from praisonai.recipe.models import RecipeConfig
# Create config
config = RecipeConfig(
timeout_sec=120,
policy_mode="strict",
trace_enabled=True
)
# Run with config
result = recipe.run(
"my-recipe",
input={"query": "test"},
config={"model": "gpt-4o"},
options={
"dry_run": False,
"timeout_sec": config.timeout_sec
}
)
HTTP Client (Any Language)
Python with requests
Copy
import requests
BASE_URL = "http://localhost:8765"
API_KEY = "your-api-key" # Optional, if auth enabled
headers = {
"Content-Type": "application/json",
"X-API-Key": API_KEY
}
# Health check
response = requests.get(f"{BASE_URL}/health")
print(response.json())
# List recipes
response = requests.get(f"{BASE_URL}/v1/recipes", headers=headers)
recipes = response.json()["recipes"]
# Describe recipe
response = requests.get(
f"{BASE_URL}/v1/recipes/my-recipe",
headers=headers
)
info = response.json()
# Run recipe
response = requests.post(
f"{BASE_URL}/v1/recipes/run",
headers=headers,
json={
"recipe": "my-recipe",
"input": {"query": "Hello"},
"config": {},
"options": {"dry_run": False}
}
)
result = response.json()
print(f"Run ID: {result['run_id']}")
print(f"Output: {result['output']}")
JavaScript/TypeScript
Copy
const BASE_URL = "http://localhost:8765";
const API_KEY = "your-api-key";
// Health check
const health = await fetch(`${BASE_URL}/health`);
console.log(await health.json());
// List recipes
const recipesRes = await fetch(`${BASE_URL}/v1/recipes`, {
headers: { "X-API-Key": API_KEY }
});
const { recipes } = await recipesRes.json();
// Run recipe
const runRes = await fetch(`${BASE_URL}/v1/recipes/run`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": API_KEY
},
body: JSON.stringify({
recipe: "my-recipe",
input: { query: "Hello" }
})
});
const result = await runRes.json();
console.log(`Output: ${result.output}`);
Streaming with JavaScript
Copy
const response = await fetch(`${BASE_URL}/v1/recipes/stream`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": API_KEY
},
body: JSON.stringify({
recipe: "my-recipe",
input: { query: "Generate a story" }
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split("\n");
for (const line of lines) {
if (line.startsWith("data:")) {
const data = JSON.parse(line.slice(5));
console.log(`Event: ${data}`);
}
}
}
curl
Copy
# Health check
curl http://localhost:8765/health
# List recipes
curl -H "X-API-Key: your-key" http://localhost:8765/v1/recipes
# Run recipe
curl -X POST http://localhost:8765/v1/recipes/run \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d '{
"recipe": "my-recipe",
"input": {"query": "Hello"}
}'
# Stream recipe
curl -X POST http://localhost:8765/v1/recipes/stream \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d '{
"recipe": "my-recipe",
"input": {"query": "Hello"}
}'
Response Models
RecipeResult
Copy
@dataclass
class RecipeResult:
ok: bool # Success status
run_id: str # Unique run identifier
recipe: str # Recipe name
version: str # Recipe version
status: str # Status: success, error, dry_run, etc.
output: Any # Recipe output
metrics: Dict[str, Any] # Execution metrics
error: Optional[str] # Error message if failed
trace: Dict[str, str] # Tracing info (run_id, session_id, trace_id)
RecipeEvent (Streaming)
Copy
@dataclass
class RecipeEvent:
event_type: str # started, progress, completed, error
data: Dict[str, Any] # Event-specific data
timestamp: str # ISO timestamp
Best Practices
1. Use Timeouts
Copy
result = recipe.run(
"my-recipe",
input=data,
options={"timeout_sec": 30} # Always set timeout
)
2. Handle Errors Gracefully
Copy
result = recipe.run("my-recipe", input=data)
if not result.ok:
if result.status == "timeout":
# Retry or fallback
pass
elif result.status == "policy_denied":
# Log and alert
pass
else:
# General error handling
pass
3. Use Session IDs for Stateful Workflows
Copy
session_id = "user-123-session"
# First call
result1 = recipe.run(
"conversation",
input={"message": "Hello"},
session_id=session_id
)
# Subsequent calls share state
result2 = recipe.run(
"conversation",
input={"message": "What did I say?"},
session_id=session_id
)
4. Monitor with Trace IDs
Copy
result = recipe.run("my-recipe", input=data)
print(f"Trace ID: {result.trace['trace_id']}")
# Use trace_id for debugging and observability
Next Steps
- See CLI Usage for command-line access
- Review Integration Models
- Explore Use Cases

