Skip to content

Instantly share code, notes, and snippets.

@CypherpunkSamurai
Last active May 31, 2026 05:06
Show Gist options
  • Select an option

  • Save CypherpunkSamurai/777851347e3aef822e801551d5d6ed1d to your computer and use it in GitHub Desktop.

Select an option

Save CypherpunkSamurai/777851347e3aef822e801551d5d6ed1d to your computer and use it in GitHub Desktop.
OpenSandBox QuickStart
"""
OpenSandbox Python SDK - Comprehensive Feature Example
=======================================================
Covers every major feature of the opensandbox SDK:
- Sandbox lifecycle (async + sync APIs)
- Connection configuration
- Command execution (foreground + background)
- File operations (read, write, create directories, read bytes)
- Endpoint access (port mapping)
- Volume mounts (Host, PVC/Docker named volume, OSSFS)
- Network policies (egress allow/deny)
- Metadata and environment variables
- Entrypoint overrides
- Resource limits (CPU, memory, disk)
- Platform specification
- Pool references (extensions)
- Health checks
- Error handling (SandboxException)
- Code Interpreter integration (multi-language)
- Sandbox manager (list/connect to existing sandboxes)
Prerequisites:
pip install opensandbox opensandbox-code-interpreter
RunServer:
$env:OPENSANDBOX_INSECURE_SERVER = "YES"; Start-Process -FilePath "C:\ProgramData\miniforge3\python.exe" -ArgumentList "-m opensandbox_server.main"
Environment variables:
SANDBOX_DOMAIN - OpenSandbox server address (default: localhost:8080)
SANDBOX_API_KEY - API key for authentication (optional)
SANDBOX_IMAGE - Container image (default: ubuntu)
"""
import asyncio
import os
from datetime import timedelta
from pathlib import Path
from opensandbox import Sandbox, SandboxSync
from opensandbox.config import ConnectionConfig, ConnectionConfigSync
from opensandbox.exceptions import SandboxException
from opensandbox.models.execd import RunCommandOpts
# ── Volume models (optional, require SDK with volume support) ────────────────
try:
from opensandbox.models.sandboxes import Host, OSSFS, PVC, Volume
HAS_VOLUMES = True
except ImportError:
HAS_VOLUMES = False
# ── Network policy models ────────────────────────────────────────────────────
try:
from opensandbox.models.sandboxes import NetworkPolicy, NetworkRule
HAS_NETWORK = True
except ImportError:
HAS_NETWORK = False
# ── Platform spec ────────────────────────────────────────────────────────────
try:
from opensandbox.models.sandboxes import PlatformSpec
HAS_PLATFORM = True
except ImportError:
HAS_PLATFORM = False
# ── Code Interpreter (optional) ──────────────────────────────────────────────
try:
from code_interpreter import CodeInterpreter, SupportedLanguage
HAS_CODE_INTERPRETER = True
except ImportError:
HAS_CODE_INTERPRETER = False
# =============================================================================
# Helpers
# =============================================================================
def _env(name: str, default: str = "") -> str:
return os.getenv(name, default)
DEFAULT_RESOURCE = {"cpu": "1", "memory": "1G"}
def _print_logs(label: str, execution) -> None:
"""Pretty-print stdout/stderr/error from a command execution."""
for msg in execution.logs.stdout:
print(f" [{label}] {msg.text}")
for msg in execution.logs.stderr:
print(f" [{label}:err] {msg.text}")
if execution.error:
print(f" [{label}:error] {execution.error.name}: {execution.error.value}")
async def _run(sandbox: Sandbox, command: str, label: str = "cmd") -> str:
"""Run a command and return combined stdout text."""
result = await sandbox.commands.run(command)
_print_logs(label, result)
return "\n".join(msg.text for msg in result.logs.stdout)
# =============================================================================
# 1. BASIC SANDBOX LIFECYCLE (async)
# =============================================================================
async def demo_basic_lifecycle() -> None:
"""Create a sandbox, run a command, and tear it down."""
print("\n" + "=" * 60)
print("1. Basic Sandbox Lifecycle (async)")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
request_timeout=timedelta(seconds=60),
)
# Create with image, timeout, and metadata
sandbox = await Sandbox.create(
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=5),
resource=DEFAULT_RESOURCE,
metadata={"example": "basic-lifecycle", "team": "demo"},
)
async with sandbox:
print(f" Sandbox ID: {sandbox.id}")
# Run a simple command
result = await sandbox.commands.run("echo 'Hello from OpenSandbox!'")
for msg in result.logs.stdout:
print(f" Output: {msg.text}")
# Get the execd daemon endpoint
endpoint = await sandbox.get_endpoint(44772)
print(f" execd endpoint: {endpoint.endpoint}")
# sandbox is automatically killed after exiting `async with`
print(" Sandbox cleaned up.")
# =============================================================================
# 2. SYNC API
# =============================================================================
def demo_sync_api() -> None:
"""Use the synchronous SandboxSync API."""
print("\n" + "=" * 60)
print("2. Sync Sandbox API")
print("=" * 60)
config = ConnectionConfigSync(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
request_timeout=timedelta(seconds=60),
)
sandbox = SandboxSync.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=5),
)
try:
print(f" Sandbox ID: {sandbox.id}")
result = sandbox.commands.run("uname -a")
for msg in result.logs.stdout:
print(f" {msg.text}")
finally:
sandbox.kill()
sandbox.close()
print(" Sync sandbox cleaned up.")
# =============================================================================
# 3. COMMAND EXECUTION (foreground + background)
# =============================================================================
async def demo_command_execution() -> None:
"""Run foreground and background commands."""
print("\n" + "=" * 60)
print("3. Command Execution (foreground + background)")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
sandbox = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=3),
)
async with sandbox:
# Foreground command
print("\n [foreground] Running 'echo hello':")
result = await sandbox.commands.run("echo hello")
for msg in result.logs.stdout:
print(f" {msg.text}")
# Background command (fire-and-forget)
print("\n [background] Starting 'sleep 60' in background:")
bg = await sandbox.commands.run(
"sleep 60",
opts=RunCommandOpts(background=True),
)
print(f" Background PID tracked: {bg.logs is not None}")
# Command with stderr
print("\n [stderr] Running command that writes to stderr:")
result = await sandbox.commands.run("echo 'error msg' >&2")
for msg in result.logs.stderr:
print(f" stderr: {msg.text}")
# Command that fails
print("\n [error] Running command that exits non-zero:")
result = await sandbox.commands.run("exit 42")
if result.error:
print(f" Error: {result.error.name}: {result.error.value}")
await sandbox.kill()
# =============================================================================
# 4. FILE OPERATIONS
# =============================================================================
async def demo_file_operations() -> None:
"""Read, write, and list files in the sandbox."""
print("\n" + "=" * 60)
print("4. File Operations")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
sandbox = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=3),
)
async with sandbox:
# Write a file
print("\n [write] Writing /tmp/hello.txt:")
await sandbox.files.write_file("/tmp/hello.txt", "Hello, World!\nLine 2\n")
# Create directories
print(" [mkdir] Creating /tmp/subdir/nested:")
try:
from opensandbox.models.filesystem import WriteEntry
await sandbox.files.create_directories([
WriteEntry(path="/tmp/subdir/nested", mode=755),
])
except Exception:
# Fallback: use command
await sandbox.commands.run("mkdir -p /tmp/subdir/nested")
# Read file back
print(" [read] Reading /tmp/hello.txt:")
content = await sandbox.files.read_file("/tmp/hello.txt")
print(f" Content: {content.strip()}")
# Read as bytes (useful for binary files)
print(" [read_bytes] Reading /tmp/hello.txt as bytes:")
data = await sandbox.files.read_bytes("/tmp/hello.txt")
print(f" Bytes: {len(data)} bytes, starts with: {data[:20]}")
# Write with mode
print(" [write+mode] Writing /tmp/script.sh with mode 755:")
await sandbox.files.write_file(
"/tmp/script.sh",
"#!/bin/sh\necho 'executable script'\n",
mode=755,
)
# List files
print(" [ls] Listing /tmp via command:")
await _run(sandbox, "ls -la /tmp/", "ls")
await sandbox.kill()
# =============================================================================
# 5. VOLUME MOUNTS
# =============================================================================
async def demo_volume_mounts() -> None:
"""Mount Docker named volumes into sandboxes."""
if not HAS_VOLUMES:
print("\n[SKIP] Volume models not available. Install SDK from source.")
return
print("\n" + "=" * 60)
print("5. Volume Mounts (Docker Named Volumes)")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
# ── 5a. PVC (Docker named volume) read-write ─────────────────────────
volume_name = "osb-demo-volume"
print(f"\n [5a] PVC volume (r/w): {volume_name} -> /mnt/data")
sandbox = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
volumes=[
Volume(
name="demo-data",
pvc=PVC(claimName=volume_name),
mountPath="/mnt/data",
readOnly=False,
),
],
)
async with sandbox:
await _run(sandbox, "echo 'hello from sandbox' > /mnt/data/test.txt", "pvc-write")
await _run(sandbox, "cat /mnt/data/test.txt", "pvc-read")
await sandbox.kill()
# ── 5b. PVC read-only ────────────────────────────────────────────────
print(f"\n [5b] PVC volume (r/o): {volume_name} -> /mnt/readonly")
sandbox = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
volumes=[
Volume(
name="demo-ro",
pvc=PVC(claimName=volume_name),
mountPath="/mnt/readonly",
readOnly=True,
),
],
)
async with sandbox:
await _run(sandbox, "cat /mnt/readonly/test.txt", "ro-read")
await _run(
sandbox,
"touch /mnt/readonly/should-fail.txt 2>&1 || echo 'Write denied (expected)'",
"ro-write-attempt",
)
await sandbox.kill()
# ── 5c. SubPath mount ────────────────────────────────────────────────
print(f"\n [5c] SubPath: datasets/train -> /mnt/training")
# First create the subpath structure
setup = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
volumes=[
Volume(
name="setup-vol",
pvc=PVC(claimName=volume_name),
mountPath="/mnt/vol",
readOnly=False,
),
],
)
async with setup:
await _run(setup, "mkdir -p /mnt/vol/datasets/train && echo 'id,value' > /mnt/vol/datasets/train/data.csv", "setup")
await setup.kill()
sandbox = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
volumes=[
Volume(
name="train-data",
pvc=PVC(claimName=volume_name),
mountPath="/mnt/training",
subPath="datasets/train",
readOnly=True,
),
],
)
async with sandbox:
await _run(sandbox, "cat /mnt/training/data.csv", "subpath")
await sandbox.kill()
print("\n Volume mount demos completed.")
# =============================================================================
# 6. NETWORK POLICIES
# =============================================================================
async def demo_network_policies() -> None:
"""Restrict sandbox egress with network policies."""
if not HAS_NETWORK:
print("\n[SKIP] NetworkPolicy models not available.")
return
print("\n" + "=" * 60)
print("6. Network Policies (egress control)")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
# Deny all egress except specific domains
policy = NetworkPolicy(
defaultAction="deny",
egress=[
NetworkRule(action="allow", target="pypi.org"),
NetworkRule(action="allow", target="github.com"),
],
)
print(" Policy: deny-all except pypi.org and github.com")
sandbox = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
network_policy=policy,
)
async with sandbox:
# Try allowed domain (may fail if sandbox has no internet at all)
print("\n [allowed] curl pypi.org:")
await _run(sandbox, "curl -sI --connect-timeout 5 https://pypi.org 2>&1 | head -3 || echo '(network unavailable in sandbox)'", "pypi")
# Try denied domain (should be blocked)
print("\n [blocked] curl google.com (should fail):")
await _run(sandbox, "curl -sI --connect-timeout 5 https://google.com 2>&1 | head -3 || echo '(blocked as expected)'", "google")
await sandbox.kill()
# =============================================================================
# 7. ENVIRONMENT VARIABLES & METADATA
# =============================================================================
async def demo_env_and_metadata() -> None:
"""Pass environment variables and metadata to the sandbox."""
print("\n" + "=" * 60)
print("7. Environment Variables & Metadata")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
sandbox = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
env={
"MY_VAR": "hello",
"ANOTHER_VAR": "42",
},
metadata={
"project": "demo",
"environment": "staging",
},
)
async with sandbox:
print(" [env] Environment variables:")
await _run(sandbox, "echo MY_VAR=$MY_VAR ANOTHER=$ANOTHER_VAR", "env")
# Metadata is set on the server side (visible via API/CLI)
print(" [metadata] Set: project=demo, environment=staging")
await sandbox.kill()
# =============================================================================
# 8. ENTRYPOINT OVERRIDE
# =============================================================================
async def demo_entrypoint() -> None:
"""Override the container entrypoint."""
print("\n" + "=" * 60)
print("8. Entrypoint Override")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
# Custom entrypoint: a simple long-running process
sandbox = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
entrypoint=["sleep", "3600"],
)
async with sandbox:
print(" [entrypoint] Custom entrypoint: sleep 3600")
result = await sandbox.commands.run("ps aux | grep 'sleep 3600'")
for msg in result.logs.stdout:
if "sleep" in msg.text:
print(f" Process found: {msg.text.strip()[:80]}")
break
await sandbox.kill()
# =============================================================================
# 9. RESOURCE LIMITS
# =============================================================================
async def demo_resource_limits() -> None:
"""Set CPU, memory, and disk limits on the sandbox."""
print("\n" + "=" * 60)
print("9. Resource Limits")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
sandbox = await Sandbox.create(
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
resource={
"cpu": "2",
"memory": "4G",
"disk": "20G",
},
)
async with sandbox:
print(" [resources] Set: cpu=2, memory=4G, disk=20G")
await _run(sandbox, "free -h | head -2", "mem")
await sandbox.kill()
# =============================================================================
# 10. PLATFORM SPECIFICATION
# =============================================================================
async def demo_platform_spec() -> None:
"""Specify OS and architecture for the sandbox."""
if not HAS_PLATFORM:
print("\n[SKIP] PlatformSpec model not available.")
return
print("\n" + "=" * 60)
print("10. Platform Specification")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
sandbox = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
platform=PlatformSpec(os="linux", arch="amd64"),
)
async with sandbox:
print(" [platform] os=linux, arch=amd64")
await _run(sandbox, "uname -m", "arch")
await sandbox.kill()
# =============================================================================
# 11. HEALTH CHECKS
# =============================================================================
async def demo_health_check() -> None:
"""Custom health check function for sandbox readiness."""
import time
print("\n" + "=" * 60)
print("11. Health Check")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
def my_health_check(sbx: SandboxSync) -> bool:
"""Poll /ping on execd until the sandbox is ready."""
try:
endpoint = sbx.get_endpoint(44772)
start = time.perf_counter()
import requests
for _ in range(50):
try:
resp = requests.get(
f"http://{endpoint.endpoint}/ping",
timeout=1,
)
if resp.status_code == 200:
elapsed = time.perf_counter() - start
print(f" Ready after {elapsed:.1f}s")
return True
except Exception:
pass
time.sleep(0.2)
except Exception as exc:
print(f" Health check failed: {exc}")
return False
sandbox = SandboxSync.create(
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=ConnectionConfigSync(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
),
timeout=timedelta(minutes=2),
resource=DEFAULT_RESOURCE,
health_check=my_health_check,
)
try:
print(f" Sandbox ID: {sandbox.id}")
print(" Health check passed.")
finally:
sandbox.kill()
sandbox.close()
# =============================================================================
# 12. ERROR HANDLING
# =============================================================================
async def demo_error_handling() -> None:
"""Handle SandboxException and other errors."""
print("\n" + "=" * 60)
print("12. Error Handling")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
try:
sandbox = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image="this-image-does-not-exist:latest", # intentionally bad
connection_config=config,
timeout=timedelta(seconds=30),
)
async with sandbox:
pass
except SandboxException as e:
print(f" Caught SandboxException:")
print(f" Code: {e.error.code}")
print(f" Message: {e.error.message}")
except Exception as e:
print(f" Caught generic exception: {type(e).__name__}: {e}")
# Command-level error
print("\n [cmd-error] Running a command that fails:")
sandbox = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
)
async with sandbox:
result = await sandbox.commands.run("false")
if result.error:
print(f" Error name: {result.error.name}")
print(f" Error value: {result.error.value}")
await sandbox.kill()
# =============================================================================
# 13. SANDBOX MANAGER (list & connect to existing sandboxes)
# =============================================================================
async def demo_sandbox_manager() -> None:
"""Use SandboxManager to list and connect to sandboxes."""
print("\n" + "=" * 60)
print("13. Sandbox Manager (list & connect)")
print("=" * 60)
from opensandbox.manager import SandboxManager
from opensandbox.models.sandboxes import SandboxFilter
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
manager = await SandboxManager.create(config)
try:
# List existing sandboxes
result = await manager.list_sandbox_infos(SandboxFilter(page_size=10))
print(f" Found {len(result.sandboxes)} sandbox(es).")
for sbx in result.sandboxes[:5]:
print(f" - {sbx.id} (state={sbx.state})")
except Exception as e:
print(f" List failed (expected if no sandboxes): {e}")
finally:
manager.close()
# =============================================================================
# 14. CODE INTERPRETER (multi-language)
# =============================================================================
async def demo_code_interpreter() -> None:
"""Run code in multiple languages via CodeInterpreter."""
if not HAS_CODE_INTERPRETER:
print("\n[SKIP] code_interpreter not installed. pip install opensandbox-code-interpreter")
return
print("\n" + "=" * 60)
print("14. Code Interpreter (Python, Java, Go, TypeScript)")
print("=" * 60)
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
image = _env(
"SANDBOX_IMAGE",
"sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/code-interpreter:v1.0.2",
)
sandbox = await Sandbox.create(
image,
connection_config=config,
resource=DEFAULT_RESOURCE,
entrypoint=["/opt/opensandbox/code-interpreter.sh"],
)
async with sandbox:
interpreter = await CodeInterpreter.create(sandbox=sandbox)
# Python
print("\n [Python]")
py = await interpreter.codes.run(
"import platform\n"
"print(f'Python {platform.python_version()}')\n"
"result = sum(range(10))\n"
"result",
language=SupportedLanguage.PYTHON,
)
for msg in py.logs.stdout:
print(f" {msg.text}")
if py.result:
for r in py.result:
print(f" => {r.text}")
# Java
print("\n [Java]")
java = await interpreter.codes.run(
'System.out.println("Hello from Java!");\n'
"int result = 2 * 21;\n"
"System.out.println(\"2 * 21 = \" + result);\n"
"result",
language=SupportedLanguage.JAVA,
)
for msg in java.logs.stdout:
print(f" {msg.text}")
if java.result:
for r in java.result:
print(f" => {r.text}")
# Go
print("\n [Go]")
go = await interpreter.codes.run(
'package main\n'
'import "fmt"\n'
"func main() {\n"
' fmt.Println("Hello from Go!")\n'
" fmt.Println(\"3 + 4 =\", 3+4)\n"
"}",
language=SupportedLanguage.GO,
)
for msg in go.logs.stdout:
print(f" {msg.text}")
# TypeScript
print("\n [TypeScript]")
ts = await interpreter.codes.run(
"const nums: number[] = [1, 2, 3, 4, 5];\n"
"console.log('Sum:', nums.reduce((a, b) => a + b, 0));",
language=SupportedLanguage.TYPESCRIPT,
)
for msg in ts.logs.stdout:
print(f" {msg.text}")
await sandbox.kill()
# =============================================================================
# 15. CROSS-SANDBOX DATA SHARING (via named volume)
# =============================================================================
async def demo_cross_sandbox_sharing() -> None:
"""Two sandboxes share data through the same volume."""
if not HAS_VOLUMES:
print("\n[SKIP] Volume models not available.")
return
print("\n" + "=" * 60)
print("15. Cross-Sandbox Data Sharing (via PVC)")
print("=" * 60)
volume_name = "opensandbox-share-demo"
config = ConnectionConfig(
domain=_env("SANDBOX_DOMAIN", "localhost:8080"),
api_key=_env("SANDBOX_API_KEY") or None,
)
volume_spec = Volume(
name="shared-vol",
pvc=PVC(claimName=volume_name),
mountPath="/mnt/shared",
readOnly=False,
)
# Sandbox A writes
print("\n [Sandbox A] Writing data...")
sandbox_a = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
volumes=[volume_spec],
)
async with sandbox_a:
await _run(sandbox_a, "echo 'hello from A' > /mnt/shared/msg.txt", "A")
await sandbox_a.kill()
# Sandbox B reads
print(" [Sandbox B] Reading data...")
sandbox_b = await Sandbox.create(
resource=DEFAULT_RESOURCE,
image=_env("SANDBOX_IMAGE", "ubuntu"),
connection_config=config,
timeout=timedelta(minutes=2),
volumes=[volume_spec],
)
async with sandbox_b:
await _run(sandbox_b, "cat /mnt/shared/msg.txt", "B")
await sandbox_b.kill()
print(" Cross-sandbox sharing verified.")
# =============================================================================
# MAIN
# =============================================================================
async def main() -> None:
"""Run all feature demos."""
print("OpenSandbox Python SDK - Comprehensive Feature Demo")
print("=" * 60)
demos = [
("1. Basic Lifecycle", demo_basic_lifecycle),
("2. Sync API", demo_sync_api),
("3. Command Execution", demo_command_execution),
("4. File Operations", demo_file_operations),
("5. Volume Mounts", demo_volume_mounts),
("6. Network Policies", demo_network_policies),
("7. Env & Metadata", demo_env_and_metadata),
("8. Entrypoint Override", demo_entrypoint),
("9. Resource Limits", demo_resource_limits),
("10. Platform Specification", demo_platform_spec),
("11. Health Checks", demo_health_check),
("12. Error Handling", demo_error_handling),
("13. Sandbox Manager", demo_sandbox_manager),
("14. Code Interpreter", demo_code_interpreter),
("15. Cross-Sandbox Sharing", demo_cross_sandbox_sharing),
]
for label, demo_fn in demos:
try:
if asyncio.iscoroutinefunction(demo_fn):
await demo_fn()
else:
demo_fn()
except Exception as e:
print(f"\n [SKIP/ERROR] {label}: {type(e).__name__}: {e}")
print("\n" + "=" * 60)
print("All demos completed!")
print("=" * 60)
if __name__ == "__main__":
asyncio.run(main())

pip install opensandbox-code-interpreter opensandbox-server

$env:OPENSANDBOX_URL="http://localhost:8081"

Step 1: Initialize the Configuration Correctly

Specify the target config file path (~/.sandbox.toml) and replace -f with --force: [1, 2]

opensandbox-server.exe init-config ~/.sandbox.toml --example docker --force

Step 2: Fire Up the Sandbox Server Backend [3]

Now that the .sandbox.toml config profile has been created with the Docker configuration rules, execute the server binary: [1, 2]

opensandbox-server.exe

Leave this window completely open in the background to handle upcoming execution commands.

Step 3: Test Sandbox Creation

Open a new, separate PowerShell terminal window and run your original workspace deployment command:

osb sandbox create --image python:3.8 --timeout 30m -o json

Let me know what the server terminal outputs once you initialize it!

[1] https://github.com [2] https://github.com [3] https://github.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment