Python SDK for Specora Runtime Authority enforcement
Project description
Specora Runtime SDK (Python)
Thin Python client SDK for Specora Runtime Authority enforcement. Wrap your AI agent tool calls with deterministic runtime governance.
Installation
pip install specora-runtime
Quickstart
from specora_runtime import SpecoraClient, CompletionStatus
client = SpecoraClient(
base_url="https://api.specora.ai",
api_key="sk_...",
org_id="your-org-uuid",
)
# Wrap tool execution with enforcement
with client.enforced(
action_type="db_write",
scope={"table": "users"},
args={"where": {"id": 1}, "set": {"name": "Alice"}},
estimated_cost=0.02,
is_write_op=True,
) as ctx:
# Your tool execution here
result = execute_database_write()
ctx.complete(status=CompletionStatus.SUCCESS)
Features
enforce()- Request enforcement decision before executionenforced()- Context manager with auto-completion reportingsimulate()- Dry-run enforcement check (no reservations)- Fail-closed by default - Network errors block execution
- Idempotency -
request_idensures exactly-once processing - Typed exceptions -
SpecoraBlockedError,SpecoraSuspendedError
Usage
enforce() - Direct Enforcement
result = client.enforce(
action_type="api_call",
scope={"service": "stripe"},
args={"method": "charge"},
estimated_cost=0.50,
estimated_volume=1,
is_write_op=True,
)
if result.is_allowed:
# Execute the action
pass
enforced() - Context Manager
The context manager handles completion reporting automatically:
from specora_runtime import CompletionStatus
with client.enforced(
action_type="file_mutation",
scope={"repo": "infra", "path": "prod.tf"},
args={"op": "write"},
estimated_cost=0.01,
is_write_op=True,
) as ctx:
# Execute your tool
write_file()
# Explicit completion (optional - auto-completes on exit)
ctx.complete(status=CompletionStatus.SUCCESS, cost_actual=0.008)
Behavior:
- Raises
SpecoraBlockedErrorif action is blocked - Raises
SpecoraSuspendedErrorif approval is required - Auto-completes with
SUCCESSon normal exit - Auto-completes with
FAILUREif exception occurs
simulate() - Dry-Run
sim = client.simulate(
action_type="schema_migration",
scope={"db": "prod"},
args={"migration": "2026_03_add_idx"},
estimated_cost=5.0,
is_write_op=True,
)
print(f"Would be: {sim.decision}") # allow, block, or suspend
print(f"Blocked reason: {sim.blocked_reason}")
Simulation mode:
- Returns decision without making reservations
- Does NOT require completion reporting
- Does NOT raise on block/suspend
Fail Mode
from specora_runtime import FailMode
# Default: CLOSED - errors raise FailClosedError
client = SpecoraClient(
base_url="https://api.specora.ai",
api_key="sk_...",
org_id="...",
fail_mode=FailMode.CLOSED,
)
# Alternative: OPEN - errors return allow (with warning)
client = SpecoraClient(
base_url="https://api.specora.ai",
api_key="sk_...",
org_id="...",
fail_mode=FailMode.OPEN,
)
CLOSED (default):
- Network timeouts raise
FailClosedError - Server errors (5xx) raise
FailClosedError - Action is NOT executed
OPEN:
- Network/server errors return
EnforcementResult(decision=ALLOW, source="fail_open") - Action MAY proceed (caller decides)
Note: 4xx client errors (400, 401, 403) always raise regardless of fail_mode.
Idempotency
All requests support idempotency via request_id:
from uuid import uuid4
request_id = uuid4()
# First call
result1 = client.enforce(
action_type="payment",
scope={"account": "123"},
args={"amount": 100},
request_id=request_id,
)
# Duplicate call with same request_id returns same journal entry
result2 = client.enforce(
action_type="payment",
scope={"account": "123"},
args={"amount": 100},
request_id=request_id,
)
assert result1.journal_id == result2.journal_id
If request_id is omitted, a UUID is auto-generated.
Error Handling
from specora_runtime import (
SpecoraBlockedError,
SpecoraSuspendedError,
FailClosedError,
)
try:
with client.enforced(...) as ctx:
do_something()
except SpecoraBlockedError as e:
print(f"Blocked: {e.reason}")
print(f"Journal ID: {e.journal_id}")
except SpecoraSuspendedError as e:
print(f"Approval required: {e.approval_source}")
except FailClosedError as e:
print(f"Service unavailable: {e}")
Callbacks
Register callbacks for observability:
def on_decision(result):
print(f"Decision: {result.decision}")
metrics.record_enforcement(result)
def on_error(exc):
logging.error(f"Specora error: {exc}")
client = SpecoraClient(
base_url="https://api.specora.ai",
api_key="sk_...",
org_id="...",
on_decision=on_decision,
on_error=on_error,
)
Configuration
| Parameter | Default | Description |
|---|---|---|
base_url |
- | Specora API URL |
api_key |
- | API key (Bearer token) |
org_id |
- | Organization UUID |
project_id |
None |
Project scope (optional) |
agent_id |
None |
Agent identifier (optional) |
fail_mode |
CLOSED |
CLOSED or OPEN |
timeout_seconds |
10 |
Request timeout |
retries |
2 |
Retry attempts for transient errors |
Security Notes
- Scope must be explicit - Always specify meaningful scope for audit trail
- request_id is idempotent - Use for exactly-once semantics
- API key is Bearer token - Store securely, never log
Versioning
This SDK follows Semantic Versioning:
- MAJOR: Breaking changes to public API
- MINOR: New features, backward compatible
- PATCH: Bug fixes, backward compatible
API contract: The SDK is compatible with Specora Runtime Authority v1.x.
License
Apache 2.0 - See LICENSE for details.
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 specora_runtime-0.2.0.tar.gz.
File metadata
- Download URL: specora_runtime-0.2.0.tar.gz
- Upload date:
- Size: 6.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c357a453ce3fe788daf2a9abb29ede456778f0dd8150f9210cc2f1aa805987d7
|
|
| MD5 |
31ff17e8a084c8c1b881b32595baac9a
|
|
| BLAKE2b-256 |
b8385359325a117c7cdabb0d83fd1c4621d149a7e7ccbd2f7866432779319ee5
|
File details
Details for the file specora_runtime-0.2.0-py3-none-any.whl.
File metadata
- Download URL: specora_runtime-0.2.0-py3-none-any.whl
- Upload date:
- Size: 34.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3aa97a1e8db65ee48039f4f2466241401d7cb6069af285707c015c7e6e6fae1
|
|
| MD5 |
da7b692dfbd3fab295c866c6d5f3ee4c
|
|
| BLAKE2b-256 |
c515b5e8fcfec8e88ac1e56b2a41aee976d48de07d86e58d3bbb6197e910c981
|