Skip to main content

StateSet Sandbox Python SDK

A Python client library for the StateSet Sandbox API. Execute code securely in isolated cloud environments with full API access to checkpoints, artifacts, webhooks, and audit logs.

Installation

pip install stateset-sandbox

Quick Start

from stateset_sandbox import StateSetSandbox

# Initialize the client
client = StateSetSandbox(
    base_url="https://api.sandbox.stateset.app",
    auth_token="sk_test_xxx",  # Your API key
    org_id="org_xxx"           # Your organization ID
)

# Create a sandbox
sandbox = client.create()
print(f"Created sandbox: {sandbox.sandbox_id}")

# Execute a command
result = client.execute(sandbox.sandbox_id, command=["echo", "Hello, World!"])
print(result.stdout)  # Output: Hello, World!

# Clean up
client.stop(sandbox.sandbox_id)

Features

  • Sandbox Management: Create, list, and manage isolated execution environments
  • Command Execution: Run commands with streaming output support
  • File Operations: Read and write files within sandboxes
  • Checkpoints: Save and restore sandbox state
  • Artifacts: Upload files to cloud storage (S3/GCS)
  • Webhooks: Receive notifications for sandbox events
  • Audit Logs: Track all operations for compliance
  • Secrets: Securely inject environment variables
  • Durable Agents: Start, steer, pause, resume, and reconnect to Temporal workflows
  • Multi-Agent Orchestration: Bound concurrency, retry workers, cancel tasks, and synthesize results

Durable long-running agents

Use DurableRunClient with the next-temporal-rs control plane. Workflow IDs are safe to persist: status calls and event streams can reconnect after the caller restarts.

from stateset_sandbox import (
    DurableRunClient,
    SandboxAgentLoopInput,
    SandboxSessionBudget,
    SandboxSessionSpec,
    StartSandboxAgentLoopInput,
)

durable = DurableRunClient(
    base_url="https://workflows.example.com",
    api_key="engine-key",
)
run = durable.start_sandbox_agent_loop(StartSandboxAgentLoopInput(
    brand_id="brand_123",
    request_id="request_123",
    loop=SandboxAgentLoopInput(
        session=SandboxSessionSpec(
            isolation="gvisor",
            budget=SandboxSessionBudget(iteration_limit=20),
        ),
        commands=[["python", "/workspace/agent.py"]],
    ),
))

for event in durable.iter_events(run.workflow_id, last_event_id=0):
    print(event.event, event.data)

AsyncDurableRunClient exposes the same lifecycle controls for asyncio applications.

Parallel agent orchestration

MultiAgentOrchestrator accepts any async runner implementing run_and_cleanup. Workers run in stable input order with bounded concurrency, isolated retries, optional fail-fast behavior, cancellation, lifecycle events, and an optional synthesis pass.

from stateset_sandbox import MultiAgentOrchestrator, MultiAgentWorker

orchestrator = MultiAgentOrchestrator(
    runner=my_agent_runner,
    max_concurrency=4,
    max_attempts=2,
)
result = await orchestrator.run(
    task="Review the service before release",
    workers=[
        MultiAgentWorker(id="security", role="security reviewer", prompt="Audit auth boundaries"),
        MultiAgentWorker(id="tests", role="test reviewer", prompt="Find coverage gaps"),
    ],
    synthesis=True,
)

API Reference

Client Initialization

from stateset_sandbox import StateSetSandbox

client = StateSetSandbox(
    base_url="https://api.sandbox.stateset.app",
    auth_token="sk_test_xxx",  # API key or JWT token
    org_id="org_xxx",          # Required for API key auth
    timeout=30000,             # Request timeout in ms (default: 30000)
    api_version="v1"           # API version (default: v1)
)

Context Manager Support

from stateset_sandbox import StateSetSandbox

with StateSetSandbox(
    base_url="https://api.sandbox.stateset.app",
    auth_token="sk_test_xxx",
    org_id="org_xxx"
) as client:
    sandbox = client.create()
    result = client.execute(sandbox.sandbox_id, command=["python", "--version"])
    print(result.stdout)
    client.stop(sandbox.sandbox_id)
# Client is automatically closed when exiting the context

Sandbox Operations

Create a Sandbox

from stateset_sandbox import CreateSandboxOptions

# Basic creation
sandbox = client.create()

# With options
sandbox = client.create(CreateSandboxOptions(
    cpus="500m",           # CPU limit
    memory="512Mi",        # Memory limit
    timeout_seconds=3600,  # Sandbox lifetime
    env={"DEBUG": "true"}, # Environment variables
    template="python-basic"
))

Execute Commands

# Simple command
result = client.execute(sandbox.sandbox_id, command="echo hello")

# Command with options
result = client.execute(
    sandbox.sandbox_id,
    command=["python", "-c", "print('Hello')"],
    timeout=60000,  # Command timeout in ms
    env={"PYTHONPATH": "/app"},
    cwd="/workspace"
)

print(result.exit_code)  # 0
print(result.stdout)     # Hello
print(result.stderr)     #

Streaming Execution

client.execute_stream(
    sandbox.sandbox_id,
    command=["python", "long_running_script.py"],
    on_stdout=lambda data: print(f"OUT: {data}"),
    on_stderr=lambda data: print(f"ERR: {data}"),
    on_exit=lambda code: print(f"Exit code: {code}"),
    on_error=lambda err: print(f"Error: {err}")
)

File Operations

# Write a single file
client.write_file(sandbox.sandbox_id, "/app/main.py", "print('Hello')")

# Write multiple files
client.write_files(sandbox.sandbox_id, [
    {"path": "/app/main.py", "content": "print('Hello')"},
    {"path": "/app/utils.py", "content": "def helper(): pass"}
])

# Read a file
content = client.read_file(sandbox.sandbox_id, "/app/main.py")
print(content)  # print('Hello')

Checkpoints

Save and restore sandbox state:

from stateset_sandbox import CreateCheckpointOptions

# Create a checkpoint
checkpoint = client.create_checkpoint(
    sandbox.sandbox_id,
    CreateCheckpointOptions(
        name="after-setup",
        description="Initial environment setup complete",
        include_paths=["/app", "/data"],
        exclude_paths=["/app/node_modules"],
        include_env=True
    )
)

# List checkpoints
checkpoints = client.list_checkpoints(sandbox_id=sandbox.sandbox_id)

# Restore a checkpoint to a new sandbox
new_sandbox = client.create()
client.restore_checkpoint(
    new_sandbox.sandbox_id,
    checkpoint.id,
    restore_files=True,
    restore_env=True
)

# Clone a checkpoint
cloned = client.clone_checkpoint(checkpoint.id, name="checkpoint-copy")

# Delete a checkpoint
client.delete_checkpoint(checkpoint.id)

Artifacts

Upload and manage files in cloud storage:

from stateset_sandbox import UploadArtifactOptions

# Upload an artifact
artifact = client.upload_artifact(
    sandbox.sandbox_id,
    UploadArtifactOptions(
        path="/app/output/report.pdf",
        content_type="application/pdf",
        expires_in=86400,  # 24 hours
        metadata={"version": "1.0"}
    )
)

# Get download URL
url = client.get_artifact_url(artifact.id, expires_in=3600)

# List artifacts
artifacts = client.list_artifacts(sandbox_id=sandbox.sandbox_id)

# Delete artifact
client.delete_artifact(artifact.id)

Webhooks

Receive notifications for sandbox events:

from stateset_sandbox import CreateWebhookOptions, WebhookEvent

# Create a webhook
webhook = client.create_webhook(CreateWebhookOptions(
    url="https://your-server.com/webhook",
    events=[WebhookEvent.SANDBOX_CREATED, WebhookEvent.SANDBOX_STOPPED],
    secret="your-signing-secret",
    headers={"X-Custom-Header": "value"}
))

# List webhooks
webhooks = client.list_webhooks()

# Test a webhook
result = client.test_webhook(webhook.id)

# View delivery history
deliveries = client.get_webhook_deliveries(webhook.id, limit=50)

# Delete webhook
client.delete_webhook(webhook.id)

Audit Logs

Track all operations for compliance:

# List audit events
result = client.list_audit_events(
    sandbox_id=sandbox.sandbox_id,
    action="command.execute",
    outcome="success",
    limit=100
)

for event in result["events"]:
    print(f"{event.timestamp}: {event.action} - {event.outcome}")

# Get sandbox audit summary
summary = client.get_sandbox_audit_summary(sandbox.sandbox_id)
print(f"Commands executed: {summary.commands_executed}")
print(f"Files written: {summary.files_written}")

Secrets

Securely manage and inject secrets:

from stateset_sandbox import CreateSecretOptions

# Create a secret
secret = client.create_secret(CreateSecretOptions(
    name="DATABASE_URL",
    value="postgres://user:pass@host/db",
    scope="sandbox"
))

# List secrets (values not included)
secrets = client.list_secrets()

# Inject secrets into a sandbox
injected = client.inject_secrets(
    sandbox.sandbox_id,
    secrets=["DATABASE_URL", "API_KEY"]
)
# Or inject all secrets
injected = client.inject_secrets(sandbox.sandbox_id, all_secrets=True)

# Update a secret
client.update_secret("DATABASE_URL", "postgres://new-url")

# Delete a secret
client.delete_secret("DATABASE_URL")

API Keys

Manage API keys programmatically:

from stateset_sandbox import CreateApiKeyOptions

# Create an API key
response = client.create_api_key(CreateApiKeyOptions(
    name="production-key",
    expires_in_days=365,
    scopes=["sandbox:create", "sandbox:execute"]
))
print(f"New API key: {response.key}")  # Only shown once!

# List API keys
keys = client.list_api_keys()

# Revoke an API key
client.revoke_api_key(key_id)

Usage & Billing

# Get current usage
usage = client.get_current_usage()
print(f"CPU hours: {usage.cpu_hours}")
print(f"Estimated cost: ${usage.estimated_cost_cents / 100:.2f}")

# Get usage history
history = client.get_usage_history(
    granularity="daily",
    start_date="2025-01-01",
    end_date="2025-01-15"
)

# Get subscription info
subscription = client.get_subscription()
print(f"Plan: {subscription.plan}")

# Get Stripe billing portal URL
portal_url = client.get_billing_portal(return_url="https://your-app.com/billing")

# List invoices
invoices = client.list_invoices(limit=10)

Registration

Register a new organization (no authentication required):

from stateset_sandbox import register, RegistrationRequest

response = register(
    base_url="https://api.sandbox.stateset.app",
    request=RegistrationRequest(
        email="user@example.com",
        organization_name="My Company",
        first_name="John",
        last_name="Doe",
        use_case="AI agent development"
    )
)

print(f"Organization ID: {response.organization.id}")
print(f"API Key: {response.api_key.key}")

Error Handling

from stateset_sandbox import (
    SandboxError,
    SandboxApiError,
    SandboxTimeoutError,
    SandboxNetworkError,
    SandboxNotFoundError,
    SandboxAuthenticationError,
    SandboxRateLimitError,
)

try:
    result = client.execute(sandbox_id, command=["python", "script.py"])
except SandboxNotFoundError as e:
    print(f"Sandbox not found: {e.sandbox_id}")
except SandboxAuthenticationError:
    print("Invalid API key or token")
except SandboxRateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after} seconds")
except SandboxTimeoutError as e:
    print(f"Request timed out after {e.timeout_ms}ms")
except SandboxNetworkError as e:
    print(f"Network error: {e.original_error}")
except SandboxApiError as e:
    print(f"API error [{e.code}]: {e.message}")
    print(f"Request ID: {e.request_id}")

Requirements

  • Python 3.10–3.13
  • httpx >= 0.27.0
  • pydantic >= 2.7.0

License

MIT

Metadata

Release files for stateset-sandbox 2.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stateset-sandbox 2.1.0
File Size Uploaded
stateset_sandbox-2.1.0.tar.gz 61.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for stateset-sandbox 2.1.0
File Interpreter ABI Platform
stateset_sandbox-2.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 113.3 kB

Release files / stateset_sandbox-2.1.0.tar.gz

Download URL stateset_sandbox-2.1.0.tar.gz
Size 61.0 kB
Tags Source
SHA-256 checksum
How to use checksums
38b3ce05d2529493b17421722476d4f8e84447668803e7e66dcbce474d95db90
BLAKE2b-256 checksum
How to use checksums
87d061179bac3d8f00daaa08de06538e6f0d1be600315caf3868b9f86f6da0e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release files / stateset_sandbox-2.1.0-py3-none-any.whl

Download URL stateset_sandbox-2.1.0-py3-none-any.whl
Size 52.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
65566bc573a98a8703fa720cd83d71f8bc759bff4033298da4e250eb2ec1d625
BLAKE2b-256 checksum
How to use checksums
03298804372169b9256c63bfd7ed93d8d2e86b71f92835be5c3d11b5c600bfe7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release history Release notifications | RSS feed

This release

2.1.0 This release

2 release files

1.1.0

2 release files

1.0.4

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page