Python SDK
Integrate sandboxes into your Python web applications.
Getting Started with the StateSet Sandbox Python SDK
This guide walks you through integrating the StateSet Sandbox SDK into your Python web application to spin up isolated sandbox environments for code execution.
Prerequisites
- Python 3.9 or later
- A StateSet Sandbox API key (sign up here)
- pip or poetry package manager
Installation
bash
pip install stateset-sandboxOr with poetry:
bash
poetry add stateset-sandboxQuick Start
python
from stateset_sandbox import StateSetSandbox
import os
# Initialize the client
client = StateSetSandbox(
base_url="https://api.sandbox.stateset.app",
auth_token=os.environ["STATESET_API_KEY"],
)
# Create a sandbox and run code
sandbox = client.create(
cpus="1",
memory="1Gi",
timeout_seconds=300,
)
print(f"Sandbox created: {sandbox.sandbox_id}")
# Execute a command
result = client.execute(sandbox.sandbox_id, command='echo "Hello from the sandbox!"')
print("Output:", result.stdout)
print("Exit code:", result.exit_code)
# Clean up
client.stop(sandbox.sandbox_id)Configuration Options
python
client = StateSetSandbox(
# Required: API endpoint
base_url="https://api.sandbox.stateset.app",
# Required: API key or JWT token
auth_token="sk_live_...",
# Optional: request timeout in seconds (default: 30)
timeout=60,
)Creating Sandboxes
Basic Sandbox
python
sandbox = client.create()
print(sandbox.sandbox_id, sandbox.status, sandbox.expires_at)Customized Sandbox
python
sandbox = client.create(
cpus="2",
memory="2Gi",
timeout_seconds=600,
env={
"NODE_ENV": "production",
"API_URL": "https://api.example.com",
},
isolation="gvisor", # "container" | "gvisor" | "microvm"
)
if sandbox.startup_metrics:
print(f"Startup time: {sandbox.startup_metrics.total_ms}ms")Executing Commands
Simple Execution
python
result = client.execute(sandbox.sandbox_id, command="node --version")
print(result.stdout) # v20.x.x
print(result.exit_code) # 0With Working Directory and Environment
python
result = client.execute(
sandbox.sandbox_id,
command=["npm", "install"],
working_dir="/workspace/my-project",
env={"NPM_CONFIG_REGISTRY": "https://registry.npmjs.org"},
)Streaming Execution
For long-running commands, use streaming for real-time output:
python
def on_stdout(data: str):
print(data, end="")
def on_stderr(data: str):
print(data, end="", file=sys.stderr)
def on_exit(code: int):
print(f"\nProcess exited with code: {code}")
client.execute_stream(
sandbox.sandbox_id,
command="npm test",
on_stdout=on_stdout,
on_stderr=on_stderr,
on_exit=on_exit,
)File Operations
Writing Files
python
import base64
# Write a single file
client.write_file(sandbox.sandbox_id, "/workspace/main.py", """
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return {"message": "Hello World!"}
""")
# Write multiple files (content must be base64 encoded)
client.write_files(sandbox.sandbox_id, files=[
{
"path": "/workspace/requirements.txt",
"content": base64.b64encode(b"flask>=3.0\ngunicorn>=21.2").decode(),
},
{
"path": "/workspace/README.md",
"content": base64.b64encode(b"# My App").decode(),
},
])Reading Files
python
# Read and decode a file
content = client.read_file_content(sandbox.sandbox_id, "/workspace/main.py")
print(content)
# Read with metadata
file = client.read_file(sandbox.sandbox_id, "/workspace/main.py")
print(f"Size: {file.size} bytes")
decoded = base64.b64decode(file.content).decode("utf-8")Web Application Integration
FastAPI Example
python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from stateset_sandbox import StateSetSandbox
import os
app = FastAPI()
sandbox_client = StateSetSandbox(
base_url=os.environ["STATESET_API_URL"],
auth_token=os.environ["STATESET_API_KEY"],
)
class RunRequest(BaseModel):
code: str
language: str = "python"
@app.post("/api/run-code")
async def run_code(req: RunRequest):
sandbox_id = None
try:
sandbox = sandbox_client.create(
cpus="0.5",
memory="512Mi",
timeout_seconds=30,
isolation="gvisor",
)
sandbox_id = sandbox.sandbox_id
filename = "main.py" if req.language == "python" else "main.js"
sandbox_client.write_file(sandbox_id, f"/workspace/{filename}", req.code)
command = f"python3 /workspace/{filename}" if req.language == "python" \
else f"node /workspace/{filename}"
result = sandbox_client.execute(sandbox_id, command=command)
return {
"success": result.exit_code == 0,
"output": result.stdout,
"error": result.stderr,
"exit_code": result.exit_code,
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
finally:
if sandbox_id:
sandbox_client.stop(sandbox_id)Flask Example
python
from flask import Flask, request, jsonify
from stateset_sandbox import StateSetSandbox
import os
app = Flask(__name__)
sandbox_client = StateSetSandbox(
base_url=os.environ["STATESET_API_URL"],
auth_token=os.environ["STATESET_API_KEY"],
)
@app.post("/api/run-code")
def run_code():
data = request.get_json()
code = data["code"]
language = data.get("language", "python")
sandbox_id = None
try:
sandbox = sandbox_client.create(
cpus="0.5",
memory="512Mi",
timeout_seconds=30,
isolation="gvisor",
)
sandbox_id = sandbox.sandbox_id
filename = "main.py" if language == "python" else "main.js"
sandbox_client.write_file(sandbox_id, f"/workspace/{filename}", code)
command = f"python3 /workspace/{filename}" if language == "python" \
else f"node /workspace/{filename}"
result = sandbox_client.execute(sandbox_id, command=command)
return jsonify({
"success": result.exit_code == 0,
"output": result.stdout,
"error": result.stderr,
"exit_code": result.exit_code,
})
except Exception as e:
return jsonify({"success": False, "error": str(e)}), 500
finally:
if sandbox_id:
sandbox_client.stop(sandbox_id)Error Handling
python
from stateset_sandbox import (
StateSetSandbox,
SandboxApiError,
SandboxTimeoutError,
SandboxNetworkError,
)
try:
result = client.execute(sandbox_id, command="npm test")
except SandboxApiError as e:
print(f"API Error [{e.code}]: {e.message}")
print(f"Status: {e.status_code}")
print(f"Request ID: {e.request_id}")
except SandboxTimeoutError as e:
print(f"Timeout after {e.timeout}ms")
except SandboxNetworkError as e:
print(f"Network error: {e}")Checkpoints
Save and restore sandbox state. See the Checkpoints guide for full details.
python
# Create a checkpoint
checkpoint = client.create_checkpoint(
sandbox_id,
name="after-setup",
description="Dependencies installed",
include_paths=["/workspace"],
exclude_paths=["/workspace/node_modules"],
)
print(f"Checkpoint: {checkpoint.id}")
# Restore a checkpoint
client.restore_checkpoint(sandbox_id, checkpoint.id)Secrets
python
# Store a secret
client.create_secret(name="DATABASE_URL", value="postgresql://...")
# List secrets (values are never returned)
secrets = client.list_secrets()
for s in secrets:
print(f"{s.name} (created {s.created_at})")
# Inject secrets into a sandbox
client.inject_secrets(sandbox_id, secrets=["DATABASE_URL"], as_env_vars=True)Agent Sessions
Run long-lived AI agent loops. See the Agent Sessions guide for full details.
python
# Create and start a session
session = client.create_agent_session(
name="code-review",
budget={"cost_cap_cents": 500, "iteration_limit": 100},
sandbox={"cpus": "2", "memory": "4Gi", "timeout_seconds": 3600},
)
client.start_agent_session(session.id)
# Execute inside the session
result = client.execute_in_agent_session(session.id, command=["python3", "run.py"])
print(result.stdout)
# Stop when done
client.stop_agent_session(session.id)Best Practices
1. Always Clean Up Sandboxes
python
sandbox = client.create()
try:
result = client.execute(sandbox.sandbox_id, command="python3 main.py")
finally:
client.stop(sandbox.sandbox_id)2. Use Appropriate Timeouts
python
# Quick task
quick = client.create(timeout_seconds=30, cpus="0.5", memory="256Mi")
# Long-running task
long = client.create(timeout_seconds=3600, cpus="2", memory="4Gi")3. Use gVisor for Untrusted Code
python
sandbox = client.create(isolation="gvisor", cpus="1", memory="1Gi")Complete Example: Code Playground API
python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from stateset_sandbox import StateSetSandbox
import os
app = FastAPI()
sandbox_client = StateSetSandbox(
base_url=os.environ["STATESET_API_URL"],
auth_token=os.environ["STATESET_API_KEY"],
)
class PlaygroundRequest(BaseModel):
code: str
language: str = "python" # "python" | "javascript" | "typescript"
dependencies: list[str] = []
@app.post("/api/playground/run")
async def run_playground(req: PlaygroundRequest):
sandbox_id = None
try:
sandbox = sandbox_client.create(
cpus="1",
memory="1Gi",
timeout_seconds=120,
isolation="gvisor",
)
sandbox_id = sandbox.sandbox_id
# Install dependencies
if req.dependencies:
if req.language == "python":
install_cmd = f"pip install {' '.join(req.dependencies)}"
else:
install_cmd = f"npm install {' '.join(req.dependencies)}"
sandbox_client.execute(sandbox_id, command=install_cmd, working_dir="/workspace")
# Write and run the code
filenames = {"python": "main.py", "javascript": "main.js", "typescript": "main.ts"}
commands = {
"python": "python3 /workspace/main.py",
"javascript": "node /workspace/main.js",
"typescript": "npx tsx /workspace/main.ts",
}
filename = filenames[req.language]
sandbox_client.write_file(sandbox_id, f"/workspace/{filename}", req.code)
result = sandbox_client.execute(
sandbox_id,
command=commands[req.language],
working_dir="/workspace",
)
return {
"success": result.exit_code == 0,
"output": result.stdout,
"error": result.stderr,
"exit_code": result.exit_code,
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
finally:
if sandbox_id:
sandbox_client.stop(sandbox_id)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=3000)Support
- GitHub Issues: github.com/stateset/stateset-sandbox/issues
- Documentation: docs.sandbox.stateset.app
- Email: support@stateset.com