Python SDK
Pythonic access to your agents
Build Python applications that interact with MUXI formations. Full support for chat, streaming, async operations, sessions, and all Formation API operations.
GitHub: muxi-ai/muxi-python
Installation
pip install muxi-client
Quick Start
from muxi import FormationClient
formation = FormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
client_key="your_client_key",
)
# Check health
print(formation.health())
Formation Client
Initialize
from muxi import FormationClient
# Production (via server proxy)
formation = FormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
client_key="your_client_key",
admin_key="your_admin_key", # Optional, for admin operations
)
# Local development (with muxi up)
formation = FormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
mode="draft", # Uses /draft/ prefix instead of /api/
client_key="your_client_key",
)
# Direct connection (bypasses server proxy)
formation = FormationClient(
url="http://localhost:8001", # Direct to formation port
client_key="your_client_key",
)
Local dev workflow: Use mode="draft" during development with muxi up, then remove it when deploying to production.
Chat (Streaming)
# Streaming chat (recommended)
for event in formation.chat_stream({"message": "Hello!"}, user_id="user_123"):
if event.get("type") == "text":
print(event.get("text"), end="", flush=True)
elif event.get("type") == "done":
break
Agents
# List agents (requires admin key)
agents = formation.get_agents()
for agent in agents:
print(agent["id"], agent["name"])
Sessions
# List sessions
sessions = formation.get_sessions(user_id="user_123")
for session in sessions["sessions"]:
print(session["session_id"])
# Get session messages
messages = formation.get_session_messages(session_id="sess_abc123", user_id="user_123")
Memory
# Get memory config
config = formation.get_memory_config()
# Get memories for user
memories = formation.get_memories(user_id="user_123")
# Add a memory (user_id, mem_type, detail)
formation.add_memory(
user_id="user_123",
mem_type="preference",
detail="User prefers Python"
)
# Delete a memory
formation.delete_memory(user_id="user_123", memory_id="mem_abc123")
# Clear user buffer
formation.clear_user_buffer(user_id="user_123")
Triggers
# Fire a trigger (name, data, async_mode, user_id)
response = formation.fire_trigger(
name="github-issue",
data={
"repository": "muxi/runtime",
"issue": {"number": 123, "title": "Bug report"}
},
async_mode=False,
user_id="user_123"
)
# Fire async trigger
formation.fire_trigger("daily-report", {"date": "2024-01-15"}, async_mode=True, user_id="user_123")
Scheduler
# List scheduled jobs
jobs = formation.get_scheduler_jobs(user_id="user_123")
# Create a job (job_type, schedule, message, user_id)
job = formation.create_scheduler_job(
job_type="prompt",
schedule="0 9 * * *", # 9am daily (cron)
message="Generate daily summary",
user_id="user_123"
)
# Delete a job
formation.delete_scheduler_job(job_id="job_abc123")
Server Client
For managing formations (deploy, start, stop):
from muxi import ServerClient
server = ServerClient(
url="http://localhost:7890",
key_id="muxi_pk_...",
secret_key="muxi_sk_...",
)
# Check server status
status = server.status()
print(status)
# List formations
formations = server.list_formations()
# Deploy a formation
result = server.deploy_formation(bundle_path="my-bot.tar.gz")
print(f"Deployed: {result['formation_id']}")
# Stop/start/restart
server.stop_formation(formation_id="my-bot")
server.start_formation(formation_id="my-bot")
server.restart_formation(formation_id="my-bot")
Async Client
For async/await usage:
import asyncio
from muxi import AsyncFormationClient
async def main():
formation = AsyncFormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
client_key="your_client_key",
)
# Async streaming
async for event in await formation.chat_stream({"message": "Hello!"}, user_id="user_123"):
if event.get("type") == "text":
print(event.get("text"), end="", flush=True)
elif event.get("type") == "done":
break
asyncio.run(main())
Error Handling
from muxi import (
MuxiError,
AuthenticationError,
AuthorizationError,
NotFoundError,
ValidationError,
RateLimitError,
ServerError,
ConnectionError,
)
try:
response = formation.chat_stream({"message": "Hello!"}, user_id="user_123")
except AuthenticationError as e:
print(f"Auth failed: {e.message}")
except RateLimitError as e:
print(f"Rate limited, retry after: {e.retry_after}s")
except MuxiError as e:
print(f"Error: {e.code} - {e.message}")
All errors include:
code- Error code stringmessage- Human-readable messagestatus_code- HTTP status coderetry_after- Seconds to wait (for rate limits)
Webhook Handlers
Handle incoming async/trigger webhook callbacks with signature verification:
from muxi import webhook
@app.post("/webhooks/muxi")
async def handle_webhook(request: Request):
payload = await request.body()
signature = request.headers.get("X-Muxi-Signature")
# Verify signature (prevents spoofing and replay attacks)
if not webhook.verify_signature(payload, signature, WEBHOOK_SECRET):
raise HTTPException(401, "Invalid signature")
# Parse into typed WebhookEvent
event = webhook.parse(payload)
if event.status == "completed":
for item in event.content:
if item.type == "text":
print(item.text)
elif event.status == "failed":
print(f"Error: {event.error.message}")
elif event.status == "awaiting_clarification":
print(f"Question: {event.clarification.question}")
WebhookEvent fields:
request_id,status,timestampcontent- List ofContentItem(type, text, file)error-ErrorDetails(code, message, trace)clarification-Clarification(question, clarificationrequestid)formation_id,user_id,processing_time,raw
Configuration
formation = FormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
client_key="your_client_key",
timeout=30, # Request timeout (seconds)
max_retries=3, # Retry count for 429/5xx
debug=True, # Enable debug logging
)
Environment variable MUXI_DEBUG=1 also enables debug logging.
Examples
Chat Bot
from muxi import FormationClient
formation = FormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
client_key="your_client_key",
)
while True:
user_input = input("You: ")
if user_input.lower() == "quit":
break
print("Assistant: ", end="")
for event in formation.chat_stream({"message": user_input}, user_id="user_123"):
if event.get("type") == "text":
print(event.get("text"), end="", flush=True)
print()
With Session Persistence
from muxi import FormationClient
formation = FormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
client_key="your_client_key",
)
session_id = None
while True:
user_input = input("You: ")
if user_input.lower() == "quit":
break
print("Assistant: ", end="")
for event in formation.chat_stream(
{"message": user_input, "session_id": session_id},
user_id="user_123"
):
if event.get("type") == "text":
print(event.get("text"), end="", flush=True)
elif event.get("session_id"):
session_id = event.get("session_id")
print()