| title | Sandbox |
|---|---|
| description | Execute code in isolated, ephemeral sandbox environments |
The Sandbox API provides secure, isolated environments for executing shell commands. Each sandbox is a temporary container that runs independently, perfect for running untrusted code or testing scripts.
Give your agent the ability to execute commands, edit files, and export results with pre-built tools.If you'd like to know the details of Sandbox APIs, please read the following documentation.
In this quickstart, you'll learn how to:
- Create a sandbox environment
- Execute shell commands
- Capture output and exit codes
- Transfer files between disk and sandbox
- Clean up when finished
Before you begin, ensure you have:
- An Acontext API key from Acontext Dashboard, or local deployment
You can quickly set up a Cloudflare Sandbox Worker using the Acontext CLI:
# Start or create a sandbox project
acontext sandbox startThe CLI will:
- Scan for existing sandbox projects in
sandbox/directory - List available sandbox types to create (e.g., Cloudflare)
- Allow you to select an existing project to start or create a new one
- Automatically detect and use the appropriate package manager (pnpm, npm, yarn, bun)
- Start the development server automatically
Example workflow:
- Run
acontext sandbox start - Select from existing projects (e.g.,
cloudflare (Local)) or create new (cloudflare (Create)) - If creating, choose a package manager
- The project will be created in
sandbox/cloudflareand the dev server will start
For more details, see the CLI documentation.
First, create a client instance with your API key.
```python Python import os from acontext import AcontextClientclient = AcontextClient( api_key=os.getenv("ACONTEXT_API_KEY"), )
base_url="http://localhost:8029/api/v1",
```typescript TypeScript
import { AcontextClient } from '@acontext/acontext';
const client = new AcontextClient({
apiKey: process.env.ACONTEXT_API_KEY,
});
// If you're using self-hosted Acontext:
// const client = new AcontextClient({
// baseUrl: "http://localhost:8029/api/v1",
// apiKey: "sk-ac-your-root-api-bearer-token",
// });
print(f"Sandbox ID: {sandbox.sandbox_id}") print(f"Status: {sandbox.sandbox_status}") print(f"Expires at: {sandbox.sandbox_expires_at}")
```typescript TypeScript
// Create a new sandbox
const sandbox = await client.sandboxes.create();
console.log(`Sandbox ID: ${sandbox.sandbox_id}`);
console.log(`Status: ${sandbox.sandbox_status}`);
console.log(`Expires at: ${sandbox.sandbox_expires_at}`);
The sandbox object contains:
sandbox_id: Unique sandbox identifiersandbox_status: Current status (running, killed, paused, error)sandbox_created_at: ISO 8601 creation timestampsandbox_expires_at: ISO 8601 expiration timestamp
print(f"stdout: {result.stdout}") print(f"stderr: {result.stderr}") print(f"exit_code: {result.exit_code}")
```typescript TypeScript
// Execute a command
const result = await client.sandboxes.execCommand({
sandboxId: sandbox.sandbox_id,
command: "echo 'Hello from sandbox!' && pwd"
});
console.log(`stdout: ${result.stdout}`);
console.log(`stderr: ${result.stderr}`);
console.log(`exit_code: ${result.exit_code}`);
The response includes:
stdout: Standard output from the commandstderr: Standard error from the commandexit_code: Exit code (0 for success)
// Kill the sandbox
await client.sandboxes.kill(sandbox.sandbox_id);
console.log("Sandbox terminated");Here's a complete working example that demonstrates the full workflow:
```python Python import os from acontext import AcontextClientdef main(): # Initialize client client = AcontextClient( api_key=os.getenv("ACONTEXT_API_KEY"), )
try:
# Create sandbox
sandbox = client.sandboxes.create()
print(f"✓ Created sandbox: {sandbox.sandbox_id}")
# Execute commands
result = client.sandboxes.exec_command(
sandbox_id=sandbox.sandbox_id,
command="python3 --version"
)
print(f"✓ Python version: {result.stdout.strip()}")
# Run a Python script
result = client.sandboxes.exec_command(
sandbox_id=sandbox.sandbox_id,
command="python3 -c 'print(sum(range(10)))'"
)
print(f"✓ Script output: {result.stdout.strip()}")
# Clean up
client.sandboxes.kill(sandbox.sandbox_id)
print("✓ Sandbox terminated")
except Exception as e:
print(f"✗ Error: {e}")
if name == "main": main()
```typescript TypeScript
import { AcontextClient } from '@acontext/acontext';
async function main() {
// Initialize client
const client = new AcontextClient({
apiKey: process.env.ACONTEXT_API_KEY,
});
try {
// Create sandbox
const sandbox = await client.sandboxes.create();
console.log(`✓ Created sandbox: ${sandbox.sandbox_id}`);
// Execute commands
let result = await client.sandboxes.execCommand({
sandboxId: sandbox.sandbox_id,
command: "python3 --version"
});
console.log(`✓ Python version: ${result.stdout.trim()}`);
// Run a Python script
result = await client.sandboxes.execCommand({
sandboxId: sandbox.sandbox_id,
command: "python3 -c 'print(sum(range(10)))'"
});
console.log(`✓ Script output: ${result.stdout.trim()}`);
// Clean up
await client.sandboxes.kill(sandbox.sandbox_id);
console.log("✓ Sandbox terminated");
} catch (error) {
console.error(`✗ Error: ${error}`);
}
}
main();
Use the Disk API to persist files and transfer them to/from sandboxes. This enables workflows where you prepare files, process them in a sandbox, and save the results.
Set up both a disk for persistent storage and a sandbox for execution. ```python Python # Create a disk for file storage disk = client.disks.create() print(f"Disk ID: {disk.id}")sandbox = client.sandboxes.create() print(f"Sandbox ID: {sandbox.sandbox_id}")
```typescript TypeScript
// Create a disk for file storage
const disk = await client.disks.create();
console.log(`Disk ID: ${disk.id}`);
// Create a sandbox for execution
const sandbox = await client.sandboxes.create();
console.log(`Sandbox ID: ${sandbox.sandbox_id}`);
artifact = client.disks.artifacts.upsert( disk.id, file=FileUpload( filename="data.txt", content=b"Hello from disk!\nProcess this in sandbox." ), file_path="/input/" ) print(f"Uploaded: {artifact.path}{artifact.filename}")
```typescript TypeScript
import { FileUpload } from '@acontext/acontext';
// Upload a script to the disk
const artifact = await client.disks.artifacts.upsert(disk.id, {
file: new FileUpload({
filename: "data.txt",
content: Buffer.from("Hello from disk!\nProcess this in sandbox."),
contentType: "text/plain"
}),
filePath: "/input/"
});
console.log(`Uploaded: ${artifact.path}${artifact.filename}`);
result = client.sandboxes.exec_command( sandbox_id=sandbox.sandbox_id, command="cat /workspace/data.txt" ) print(f"File content: {result.stdout}")
```typescript TypeScript
// Download artifact to sandbox
const success = await client.disks.artifacts.downloadToSandbox(disk.id, {
filePath: "/input/",
filename: "data.txt",
sandboxId: sandbox.sandbox_id,
sandboxPath: "/workspace/"
});
console.log(`Download success: ${success}`);
// Verify the file exists in sandbox
const result = await client.sandboxes.execCommand({
sandboxId: sandbox.sandbox_id,
command: "cat /workspace/data.txt"
});
console.log(`File content: ${result.stdout}`);
result = client.sandboxes.exec_command( sandbox_id=sandbox.sandbox_id, command="cat /workspace/result.txt" ) print(f"Result: {result.stdout}")
```typescript TypeScript
// Process the file and create output
await client.sandboxes.execCommand({
sandboxId: sandbox.sandbox_id,
command: "wc -l /workspace/data.txt > /workspace/result.txt"
});
// Verify the output
const output = await client.sandboxes.execCommand({
sandboxId: sandbox.sandbox_id,
command: "cat /workspace/result.txt"
});
console.log(`Result: ${output.stdout}`);
artifact_info = client.disks.artifacts.get( disk.id, file_path="/output/", filename="result.txt", with_content=True ) print(f"Persisted content: {artifact_info.content.raw}")
```typescript TypeScript
// Upload the result from sandbox to disk
const uploaded = await client.disks.artifacts.uploadFromSandbox(disk.id, {
sandboxId: sandbox.sandbox_id,
sandboxPath: "/workspace/",
sandboxFilename: "result.txt",
filePath: "/output/"
});
console.log(`Saved: ${uploaded.path}${uploaded.filename}`);
// Verify by reading from disk
const artifactInfo = await client.disks.artifacts.get(disk.id, {
filePath: "/output/",
filename: "result.txt",
withContent: true
});
console.log(`Persisted content: ${artifactInfo.content?.raw}`);
// Kill the sandbox (disk persists)
await client.sandboxes.kill(sandbox.sandbox_id);
console.log("Sandbox terminated, files preserved on disk");Here's a complete working example that demonstrates the full disk-sandbox file transfer workflow:
```python Python import os from acontext import AcontextClient, FileUploaddef main(): client = AcontextClient( api_key=os.getenv("ACONTEXT_API_KEY"), )
try:
# Create disk and sandbox
disk = client.disks.create()
sandbox = client.sandboxes.create()
print(f"✓ Created disk: {disk.id}")
print(f"✓ Created sandbox: {sandbox.sandbox_id}")
# Upload input file to disk
client.disks.artifacts.upsert(
disk.id,
file=FileUpload(filename="input.txt", content=b"Line 1\nLine 2\nLine 3"),
file_path="/input/"
)
print("✓ Uploaded input file to disk")
# Download to sandbox
client.disks.artifacts.download_to_sandbox(
disk_id=disk.id,
file_path="/input/",
filename="input.txt",
sandbox_id=sandbox.sandbox_id,
sandbox_path="/workspace/"
)
print("✓ Downloaded file to sandbox")
# Process in sandbox
client.sandboxes.exec_command(
sandbox_id=sandbox.sandbox_id,
command="wc -l /workspace/input.txt > /workspace/output.txt"
)
print("✓ Processed file in sandbox")
# Upload result back to disk
client.disks.artifacts.upload_from_sandbox(
disk_id=disk.id,
sandbox_id=sandbox.sandbox_id,
sandbox_path="/workspace/",
sandbox_filename="output.txt",
file_path="/output/"
)
print("✓ Uploaded result to disk")
# Verify result
result = client.disks.artifacts.get(
disk.id,
file_path="/output/",
filename="output.txt",
with_content=True
)
print(f"✓ Result: {result.content.raw.strip()}")
# Cleanup
client.sandboxes.kill(sandbox.sandbox_id)
client.disks.delete(disk.id)
print("✓ Cleaned up resources")
except Exception as e:
print(f"✗ Error: {e}")
if name == "main": main()
```typescript TypeScript
import { AcontextClient, FileUpload } from '@acontext/acontext';
async function main() {
const client = new AcontextClient({
apiKey: process.env.ACONTEXT_API_KEY,
});
try {
// Create disk and sandbox
const disk = await client.disks.create();
const sandbox = await client.sandboxes.create();
console.log(`✓ Created disk: ${disk.id}`);
console.log(`✓ Created sandbox: ${sandbox.sandbox_id}`);
// Upload input file to disk
await client.disks.artifacts.upsert(disk.id, {
file: new FileUpload({
filename: "input.txt",
content: Buffer.from("Line 1\nLine 2\nLine 3"),
contentType: "text/plain"
}),
filePath: "/input/"
});
console.log("✓ Uploaded input file to disk");
// Download to sandbox
await client.disks.artifacts.downloadToSandbox(disk.id, {
filePath: "/input/",
filename: "input.txt",
sandboxId: sandbox.sandbox_id,
sandboxPath: "/workspace/"
});
console.log("✓ Downloaded file to sandbox");
// Process in sandbox
await client.sandboxes.execCommand({
sandboxId: sandbox.sandbox_id,
command: "wc -l /workspace/input.txt > /workspace/output.txt"
});
console.log("✓ Processed file in sandbox");
// Upload result back to disk
await client.disks.artifacts.uploadFromSandbox(disk.id, {
sandboxId: sandbox.sandbox_id,
sandboxPath: "/workspace/",
sandboxFilename: "output.txt",
filePath: "/output/"
});
console.log("✓ Uploaded result to disk");
// Verify result
const result = await client.disks.artifacts.get(disk.id, {
filePath: "/output/",
filename: "output.txt",
withContent: true
});
console.log(`✓ Result: ${result.content?.raw.trim()}`);
// Cleanup
await client.sandboxes.kill(sandbox.sandbox_id);
await client.disks.delete(disk.id);
console.log("✓ Cleaned up resources");
} catch (error) {
console.error(`✗ Error: ${error}`);
}
}
main();
Solution:
- Break long-running commands into smaller steps
- Check if the command is waiting for input (use non-interactive flags)
- Consider running background processes if needed
Solution:
- Verify the sandbox ID is correct
- Check if the sandbox has expired or been killed
- Create a new sandbox if the previous one is no longer available
Solution:
- Check
stderrfor error messages - Verify the command syntax is correct
- Ensure required tools are available in the sandbox environment