Python SDK
Python SDK
Section titled “Python SDK”The official Python SDK is published as onceonly-sdk on PyPI.
Install
Section titled “Install”pip install onceonly-sdkCreate a client
Section titled “Create a client”import osfrom onceonly import OnceOnly
client = OnceOnly(api_key=os.environ["ONCEONLY_API_KEY"])If you self-host, pass a custom base_url (must include /v1):
client = OnceOnly( api_key=os.environ["ONCEONLY_API_KEY"], base_url="http://localhost:8080/v1",)Idempotency (check-lock)
Section titled “Idempotency (check-lock)”lock = client.check_lock( key="payment:invoice:INV-123", ttl=3600, meta={"invoice_id": "INV-123", "amount_usd": 99.99},)
if lock.duplicate: # Already executed within TTL window. # Return the cached result from your own storage. raise RuntimeError(f"Duplicate (first_seen_at={lock.first_seen_at})")
# Safe to run the real side-effect here.charge_customer()Policies (agent governance)
Section titled “Policies (agent governance)”policy = client.gov.upsert_policy({ "agent_id": "support_bot", "allowed_tools": ["send_email", "create_ticket"], "blocked_tools": ["delete_user"], "max_actions_per_hour": 100, "max_spend_usd_per_day": 50.0,})print(policy.agent_id, policy.max_actions_per_hour)See also: Policy Templates
Tools registry
Section titled “Tools registry”import os
tool = client.gov.create_tool({ "name": "send_email", "scope_id": "global", "url": "https://your-domain.com/tools/send-email", "auth": {"type": "hmac_sha256", "secret": os.environ["TOOL_SECRET"]}, "timeout_ms": 15000, "max_retries": 2, "enabled": True, "description": "Send transactional email",})print(tool["name"], tool["enabled"])See also: Implementing Tool Backends
AI leases & governed tool execution
Section titled “AI leases & governed tool execution”Run a governed tool call (agent + tool)
Section titled “Run a governed tool call (agent + tool)”res = client.ai.run_tool( agent_id="support_bot", tool="send_email", args={"to": "user@example.com", "subject": "Hello"}, spend_usd=0.001,)
if res.allowed: print("Executed:", res.result)else: print("Blocked:", res.decision, res.policy_reason)Start a long-running run (keyed) and wait
Section titled “Start a long-running run (keyed) and wait”final = client.ai.run_and_wait( key="support_chat:abc123", ttl=1800, metadata={"customer_id": "cus_123"}, timeout=120,)print(final.status, final.error_code, final.result)