Skip to main content

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 execution
  • enforced() - Context manager with auto-completion reporting
  • simulate() - Dry-run enforcement check (no reservations)
  • Fail-closed by default - Network errors block execution
  • Idempotency - request_id ensures 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 SpecoraBlockedError if action is blocked
  • Raises SpecoraSuspendedError if approval is required
  • Auto-completes with SUCCESS on normal exit
  • Auto-completes with FAILURE if 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

specora_runtime-0.2.0.tar.gz (6.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

specora_runtime-0.2.0-py3-none-any.whl (34.0 kB view details)

Uploaded Python 3

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

Hashes for specora_runtime-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c357a453ce3fe788daf2a9abb29ede456778f0dd8150f9210cc2f1aa805987d7
MD5 31ff17e8a084c8c1b881b32595baac9a
BLAKE2b-256 b8385359325a117c7cdabb0d83fd1c4621d149a7e7ccbd2f7866432779319ee5

See more details on using hashes here.

File details

Details for the file specora_runtime-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for specora_runtime-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b3aa97a1e8db65ee48039f4f2466241401d7cb6069af285707c015c7e6e6fae1
MD5 da7b692dfbd3fab295c866c6d5f3ee4c
BLAKE2b-256 c515b5e8fcfec8e88ac1e56b2a41aee976d48de07d86e58d3bbb6197e910c981

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page