Skip to main content

Python SDK

The official Python SDK for the Caged platform. Requires Python 3.9+.

Installation

pip install caged

Quick Start

from caged import Caged

caged = Caged(api_key="caged_sk_...")

sandbox = caged.sandboxes.create(template="python-312", memory_mb=1024)
print(f"Sandbox {sandbox.id} is {sandbox.status}")

Context Manager

The client can be used as a context manager to ensure connections are closed:
with Caged(api_key="caged_sk_...") as caged:
    sandbox = caged.sandboxes.create(template="node-20")
    # ... use sandbox ...
    caged.sandboxes.destroy(sandbox.id)

Sandboxes

# Create with options
sandbox = caged.sandboxes.create(
    template="node-20",
    cpus=2,
    memory_mb=1024,
    repo="https://github.com/user/repo",
    env={"NODE_ENV": "development"},
)

# Create with an AI agent and a budget cap
agent_box = caged.sandboxes.create(
    template="python-312",
    agents=["claude"],
    budget=5.00,  # USD
    env={"ANTHROPIC_API_KEY": os.environ["ANTHROPIC_API_KEY"]},
)

# List all
sandboxes = caged.sandboxes.list()

# Get by ID
sb = caged.sandboxes.get("cage_abc123")

# Lifecycle
caged.sandboxes.pause("cage_abc123")
caged.sandboxes.resume("cage_abc123")
caged.sandboxes.destroy("cage_abc123")

Executing Commands

Run shell commands inside a sandbox — including prompting installed AI agents:
# Run a command
result = caged.sandboxes.exec(sandbox.id, "pytest -x")
print(result.output)
if not result.ok:
    print(f"Tests failed with exit code {result.exit_code}")

# Prompt Claude Code (requires agents=["claude"] at creation)
answer = caged.sandboxes.exec(
    sandbox.id,
    'cd /workspace && claude -p "Find and fix the failing test"',
)
print(answer.output)
A non-zero exit_code does not raise — it means the command ran and failed. Only infrastructure failures (sandbox unreachable) set result.error. Exec calls default to a 5-minute timeout; pass timeout=600 to override.

Files

# List directory
files = caged.files.list(sandbox.id, "/workspace")

# Read file
content = caged.files.read(sandbox.id, "/workspace/main.py")

# Write file
caged.files.write(sandbox.id, "/workspace/main.py", "print('hello')")

# Git diff
diff = caged.files.git_diff(sandbox.id)

Snapshots

import time

# Create
snapshot = caged.snapshots.create(sandbox.id, name="checkpoint-1")

# Wait for completion
while snapshot.status == "pending":
    time.sleep(1)
    snapshot = caged.snapshots.get(snapshot.id)

# Restore
caged.snapshots.restore(snapshot.id)

# Download URL
url = caged.snapshots.download_url(snapshot.id)

Error Handling

from caged import Caged, CagedAPIError, CagedTimeoutError

caged = Caged(api_key="caged_sk_...")

try:
    caged.sandboxes.get("nonexistent")
except CagedAPIError as e:
    print(f"API error {e.status}: {e}")
except CagedTimeoutError as e:
    print(f"Timeout: {e}")

Type Safety

The SDK uses dataclasses with full type annotations. All return types are typed:
from caged import Sandbox, FileEntry, Snapshot

sandbox: Sandbox = caged.sandboxes.get("cage_abc123")
files: list[FileEntry] = caged.files.list(sandbox.id)