import asyncio
import os
from datetime import timedelta
from opensandbox import Sandbox
from opensandbox.config import ConnectionConfig
async def main() -> None:
# Configuration
domain = os.getenv("SANDBOX_DOMAIN", "localhost:8080")
api_key = os.getenv("SANDBOX_API_KEY")
claude_auth_token = os.getenv("ANTHROPIC_AUTH_TOKEN")
claude_model_name = os.getenv("ANTHROPIC_MODEL", "claude_sonnet4")
image = os.getenv(
"SANDBOX_IMAGE",
"sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/code-interpreter:v1.0.1",
)
config = ConnectionConfig(
domain=domain,
api_key=api_key,
request_timeout=timedelta(seconds=60),
)
# Inject Claude settings into container environment
env = {
"ANTHROPIC_AUTH_TOKEN": claude_auth_token,
"ANTHROPIC_BASE_URL": os.getenv("ANTHROPIC_BASE_URL"),
"ANTHROPIC_MODEL": claude_model_name,
"IS_SANDBOX": "1",
}
# Drop None values
env = {k: v for k, v in env.items() if v is not None}
# Create sandbox with environment variables
sandbox = await Sandbox.create(
image,
connection_config=config,
env=env,
)
async with sandbox:
# Install Claude CLI
install_exec = await sandbox.commands.run(
"npm i -g @anthropic-ai/claude-code@latest"
)
# Print installation logs
for msg in install_exec.logs.stdout:
print(f"[stdout] {msg.text}")
# Use Claude CLI to send a message
run_exec = await sandbox.commands.run(
'claude "Compute 1+1=?."'
)
# Print Claude's response
for msg in run_exec.logs.stdout:
print(f"[stdout] {msg.text}")
if run_exec.error:
print(f"[error] {run_exec.error.name}: {run_exec.error.value}")
await sandbox.kill()
if __name__ == "__main__":
asyncio.run(main())