Python SDK
First-party Python SDK for server-side agents, scheduled workers, and async services.
Status
First-party Python SDK
Status: Beta
Package: haltstate-sdk
Published: 0.7.0
Replay-safe source candidate: 0.8.0.dev0 (not yet published). Install the reviewed repository source for the candidate contract.
Client
from haltstate import HaltStateClient
client = HaltStateClient(
tenant_id=os.environ["HALTSTATE_TENANT_ID"],
api_key=os.environ["HALTSTATE_API_KEY"],
)Context manager guard
operator_epoch = "11111111-2222-4333-8444-555555555555"
destination_key = "refund:lge_123"
guard_key = f"hsr1:{operator_epoch}:{destination_key}"
report_id = "40000000-0000-4000-8000-000000000501"
with client.guard(
"refund.create",
params={"amount": 89, "currency": "USD"},
idempotency_key=guard_key,
report_id=report_id,
) as permit:
permit.validate_for_execution()
ledger.execute_refund(idempotency_key=destination_key)Service pattern
The context manager reports both success and error with the caller-stable report_id. Long-running workers should persist the exact permit and report envelope before an uncertain retry, then call the public report_guard_outcome recovery API without rerunning the destination action. If HaltState is unavailable for a high-risk action, the worker should fail closed.
Sync check and report
from haltstate import HaltStateClient
client = HaltStateClient(
tenant_id='your_tenant_id',
api_key='hs_xyz',
base_url='https://haltstate.ai',
fail_open=False,
)
decision = client.check(
action='refund.create',
params={'amount': 126, 'currency': 'USD'},
agent_id='retail-refund-agent',
)
if decision.allowed:
result = execute_refund_once()
client.report(decision, status='success', result=result, action='refund.create', agent_id='retail-refund-agent')
elif decision.requires_approval:
mark_pending()
else:
mark_denied(decision.reason)Async check pattern
from haltstate import AsyncHaltStateClient
async def process_payment(invoice_id: str, amount: int):
async with AsyncHaltStateClient(tenant_id='acme', api_key='hs_xxx', base_url='https://haltstate.ai') as client:
decision = await client.check(
action='payment.process',
params={'invoice_id': invoice_id, 'amount': amount},
agent_id='payment-bot',
)
if decision.allowed:
result = await execute_payment(amount)
await client.report(decision, status='success', result={'ok': True}, action='payment.process', agent_id='payment-bot')
return result
if decision.requires_approval:
return {'status': 'pending'}
return {'status': 'denied', 'reason': decision.reason}Decorators
from haltstate import HaltStateClient, haltstate_guard
client = HaltStateClient(tenant_id='acme', api_key='hs_xxx', base_url='https://haltstate.ai')
@haltstate_guard(client, action='email.send', agent_id='email-bot')
def send_email(to, subject, body):
return mailer.send(to, subject, body)Use decorators for small service methods where the action name and idempotency key are obvious. Use explicit guard blocks for workers that need ledger transitions, Proof Packs, and multi-step reporting.
Exception imports
from haltstate import (
HaltStateError,
HaltStateAuthError,
HaltStateConnectionError,
HaltStateRateLimitError,
ApprovalPending,
ActionDenied,
ActionExpired,
)Compatibility namespace
Existing code using the earlier import namespace can continue to work, but new integrations should use from haltstate import .... The compatibility path is for migration, not for new public examples.
Replay-safe source candidate contract
The stable retry identity binds the exact agent, action or tool, resource, normalized parameters, risk class, and immutable policy version. With an operator-issued activation epoch, the SDK may create epoch-qualified generated keys only when the caller omitted a key; explicit keys are never changed. Approval expiry blocks a stale permit, while already_started and completed remain terminal. After the side effect, receipt validation requires the durable event ID, receipt hash, received flag, and duplicate marker; retry the same report identity without rerunning the action.
This is a source candidate contract, not evidence that the candidate package is registry-published or production-deployed. Published package baselines and language-specific executable verification status are listed separately above.
Implementation notes
Keep the HaltState call as close as possible to the side effect. The agent may plan and draft freely, but the wrapper around the actual action should be the place where authority is checked. That wrapper should send only the context required for policy evaluation: safe identifiers, normalized amounts, action names, risk flags, schedule windows, and redaction status. Raw customer payloads and secrets should stay in the business system or protected operator tooling.
Operational evidence
For each action, preserve the decision, the worker outcome, the idempotency key, safe resource references, latency, proof status, and redaction status. This evidence supports incident response and control narratives because it shows what the system did at runtime rather than only describing what the policy document intended. HaltState supports alignment work; it is not a substitute for legal advice or a compliance certification.