Dynamiq Sandboxes
Python SDK for Dynamiq Sandboxes — secure, isolated environments for code execution, browser automation, and virtual desktops.
Built for AI agents and automation pipelines. Part of the Dynamiq ecosystem.
Installation
pip install dynamiq-sandboxes
Quick Start
export DYNAMIQ_API_KEY="your-api-key"
from dynamiq_sandboxes import Sandbox
sandbox = Sandbox.create(template="python")
result = sandbox.execute_command("echo 'Hello from the sandbox!'")
print(result["stdout"]) # Hello from the sandbox!
sandbox.close()
Code Sandboxes
Isolated execution environments with Python, Node.js, and shell support.
from dynamiq_sandboxes import Sandbox
sandbox = Sandbox.create(template="python", timeout=3600)
# Execute shell commands (auto-wrapped in /bin/bash)
result = sandbox.execute_command("echo hello && ls /")
print(result["stdout"])
print(result["exit_code"]) # 0
# Run Python code directly
output = sandbox.run_code("print(2 + 2)", language="python")
print(output["stdout"]) # 4
# Explicit args mode (no shell wrapping)
result = sandbox.execute_command("python3", args=["-c", "print('direct')"])
# Per-command environment variables
result = sandbox.execute_command("echo $MY_VAR", env={"MY_VAR": "hello"})
print(result["stdout"]) # hello
# Background execution
result = sandbox.execute_command("sleep 60", background=True)
# File operations
sandbox.filesystem.write("/app/config.json", '{"key": "value"}')
content = sandbox.filesystem.read("/app/config.json")
print(content) # {"key": "value"}
files = sandbox.filesystem.list("/app")
for f in files:
print(f"{f.name} {f.size}B ({f.type})")
# Directory operations
sandbox.filesystem.mkdir("/app/data")
sandbox.filesystem.copy("/app/config.json", "/app/data/config.json")
sandbox.filesystem.move("/app/data/config.json", "/app/data/settings.json")
sandbox.filesystem.remove("/app/data", recursive=True)
# Upload / download files
sandbox.filesystem.upload("local_file.py", "/app/script.py")
sandbox.filesystem.download("/app/output.csv", "local_output.csv")
# Check file existence and metadata
if sandbox.filesystem.exists("/app/script.py"):
info = sandbox.filesystem.stat("/app/script.py")
print(f"{info.name}: {info.size} bytes")
# Resource metrics
metrics = sandbox.metrics()
print(f"CPU: {metrics['cpu']['usage_percent']}%")
# Extend session timeout
sandbox.extend_timeout(3600) # Add 1 hour
sandbox.set_timeout(3600) # Alias — same as extend_timeout
sandbox.close()
Reconnecting to Sandboxes
from dynamiq_sandboxes import Sandbox
# Connect to an existing sandbox (auto-resumes if paused)
sandbox = Sandbox.connect("sbx-abc123")
result = sandbox.execute_command("whoami")
print(result["stdout"])
Browser Automation
Headless Chromium with CDP access, screenshots, scraping, and live streaming.
from dynamiq_sandboxes import Browser
browser = Browser.create(
stealth=True, # Anti-detection mode
viewport_width=1920,
viewport_height=1080,
)
# Navigate to pages
browser.navigate("https://example.com")
# Take screenshots
result = browser.screenshot(full_page=True)
# result["image"] is a data URI: data:image/png;base64,...
# result["width"], result["height"]
# Scrape page content
scrape = browser.scrape(format="text")
print(scrape["content"])
# Execute JavaScript
title = browser.execute_script("() => document.title")
url = browser.execute_script("() => window.location.href")
# Navigation history
browser.go_back()
browser.go_forward()
browser.reload()
# Browser context (cookies, localStorage)
ctx = browser.get_context()
print(ctx)
# Console logs and network requests
logs = browser.get_logs()
requests = browser.get_network_requests()
har = browser.export_har()
# Live streaming info (for embedding in UI)
live = browser.get_live_view()
print(live["stream_url"]) # WebSocket stream URL
print(live["livekit_url"]) # LiveKit WebRTC URL
print(live["livekit_token"]) # JWT token for viewer
browser.close()
CDP Access (Playwright / Puppeteer)
Every browser session exposes a Chrome DevTools Protocol WebSocket that works with any CDP-compatible tool:
# Get the CDP URL from the sandbox
browser = Browser.create(stealth=True)
cdp_url = browser.data["cdp_websocket_url"]
# wss://api.sandboxes.getdynamiq.ai/v1/browser/sessions/{id}/cdp
Playwright (Python):
from playwright.async_api import async_playwright
async with async_playwright() as p:
b = await p.chromium.connect_over_cdp(
cdp_url,
headers={"X-API-Key": "your-api-key"},
)
page = b.contexts[0].pages[0]
await page.goto("https://example.com")
print(await page.title())
await page.screenshot(path="screenshot.png")
Puppeteer (Node.js):
const browser = await puppeteer.connect({
browserWSEndpoint: cdpUrl,
headers: { "X-API-Key": "your-api-key" },
});
const page = (await browser.pages())[0];
await page.goto("https://example.com");
await page.screenshot({ path: "screenshot.png" });
Virtual Desktops
Full Ubuntu desktop with XFCE, mouse/keyboard control, and VNC streaming.
from dynamiq_sandboxes import Desktop
desktop = Desktop.create(template="ubuntu-desktop")
# Take screenshots
result = desktop.screenshot()
# result["image"] is a data URI, result["width"], result["height"]
# Launch applications
desktop.launch(application="xfce4-terminal")
desktop.launch(application="firefox")
# Mouse control
desktop.mouse_click(x=500, y=300)
desktop.mouse_click(x=500, y=300, button="right") # Right click
desktop.mouse_click(x=500, y=300, double_click=True) # Double click
desktop.mouse_move(x=100, y=200)
desktop.mouse_scroll(x=500, y=300, delta_x=0, delta_y=-3)
desktop.mouse_drag(start_x=100, start_y=100, end_x=300, end_y=300)
# Keyboard input
desktop.keyboard_type(text="Hello, World!")
desktop.keyboard_press(keys=["Return"])
desktop.keyboard_press(keys=["ctrl", "c"]) # Hotkey combo
desktop.keyboard_press(keys=["ctrl", "l"]) # Clear terminal
# Open URLs
desktop.open(path="https://example.com")
# Get cursor position
cursor = desktop.cursor()
print(f"Cursor at ({cursor['x']}, {cursor['y']})")
# VNC streaming (for embedding in your UI)
stream = desktop.stream_start()
info = desktop.stream_info()
print(f"noVNC URL: {info.get('novnc_url')}")
print(f"WebSocket: {info.get('stream_url')}")
desktop.close()
Network Configuration
from dynamiq_sandboxes import Sandbox, NetworkConfig, ALL_TRAFFIC
# Deny all traffic except specific IPs
sandbox = Sandbox.create(
template="python",
network=NetworkConfig(
deny_out=[ALL_TRAFFIC],
allow_out=["1.1.1.1", "8.8.8.0/24"],
),
)
# Disable internet access entirely
sandbox = Sandbox.create(
template="python",
network=NetworkConfig(allow_internet_access=False),
)
Template Builder
from dynamiq_sandboxes import TemplateBuilder, Template
# Build a custom template
template = (
TemplateBuilder()
.from_base_image("python:3.11-slim")
.set_envs({"LANG": "C.UTF-8"})
.run_cmd("pip install numpy pandas")
.set_start_cmd("python -m http.server 8080")
.set_description("Data science sandbox")
)
info = template.build("my-data-science", api_key="your-key")
print(info.template_id)
# List and manage templates
templates = Template.list(api_key="your-key")
for t in templates:
print(f"{t.name}: {t.status}")
REST API
All SDK methods map to REST API calls:
# Create a sandbox
curl -X POST https://api.sandboxes.getdynamiq.ai/v1/sandboxes \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"template_id": "python", "timeout": 3600}'
# Execute a command
curl -X POST https://api.sandboxes.getdynamiq.ai/v1/sandboxes/{id}/commands \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"command": "echo hello"}'
# Create a browser session
curl -X POST https://api.sandboxes.getdynamiq.ai/v1/browser/sessions \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"stealth": true}'
# Create a desktop
curl -X POST https://api.sandboxes.getdynamiq.ai/v1/sandboxes \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"template_id": "ubuntu-desktop", "sandbox_type": "desktop"}'
Configuration
| Environment Variable | Description | Default |
|---|---|---|
DYNAMIQ_API_KEY |
API key for authentication | Required |
DYNAMIQ_API_URL |
API base URL | https://api.sandboxes.getdynamiq.ai/v1 |
# Or pass directly
sandbox = Sandbox.create(
template="python",
api_key="your-api-key",
base_url="https://api.sandboxes.getdynamiq.ai/v1",
)
API Reference
Sandbox
| Method | Description |
|---|---|
Sandbox.create(template, timeout, vcpu, memory_mb, ...) |
Create a new sandbox |
Sandbox.get(sandbox_id) |
Get existing sandbox by ID |
Sandbox.connect(sandbox_id, timeout) |
Connect to sandbox (auto-resumes if paused) |
Sandbox.list(state, tags, ...) |
List sandboxes with filtering |
sandbox.execute_command(command, args, env, working_dir, timeout, background) |
Execute a shell command |
sandbox.run_code(code, language, timeout) |
Run code in a language interpreter |
sandbox.filesystem.write(path, content) |
Write a file |
sandbox.filesystem.read(path) |
Read a file |
sandbox.filesystem.list(path) |
List directory contents |
sandbox.filesystem.mkdir(path) |
Create directory |
sandbox.filesystem.remove(path, recursive) |
Delete file or directory |
sandbox.filesystem.exists(path) |
Check if path exists |
sandbox.filesystem.stat(path) |
Get file metadata |
sandbox.filesystem.copy(src, dst) |
Copy file/directory |
sandbox.filesystem.move(src, dst) |
Move/rename file |
sandbox.filesystem.upload(local, remote) |
Upload local file |
sandbox.filesystem.download(remote, local) |
Download file |
sandbox.metrics() |
Get CPU/memory/disk metrics |
sandbox.extend_timeout(seconds) |
Extend session lifetime |
sandbox.set_timeout(seconds) |
Alias for extend_timeout |
sandbox.pause() |
Pause sandbox (preserves state) |
sandbox.resume(timeout) |
Resume paused sandbox |
sandbox.refresh() |
Refresh sandbox state |
sandbox.close() |
Terminate sandbox |
Browser
| Method | Description |
|---|---|
Browser.create(stealth, viewport_width, viewport_height, ...) |
Create browser session |
Browser.get(session_id) |
Connect to existing session |
browser.navigate(url, wait_until, timeout) |
Navigate to URL |
browser.screenshot(format, full_page, quality) |
Capture screenshot |
browser.scrape(format, wait_for, timeout) |
Extract page content |
browser.execute_script(script) |
Execute JavaScript |
browser.go_back() |
Navigate back |
browser.go_forward() |
Navigate forward |
browser.reload() |
Reload page |
browser.get_current_url() |
Get current URL |
browser.get_context() |
Get cookies/storage |
browser.get_logs() |
Get console logs |
browser.get_network_requests() |
Get captured requests |
browser.export_har() |
Export HAR archive |
browser.get_live_view() |
Get streaming info |
browser.send_input(type, x, y, text, ...) |
Send input events |
browser.close() |
Close session |
Desktop
| Method | Description |
|---|---|
Desktop.create(template, timeout, ...) |
Create virtual desktop |
Desktop.get(desktop_id) |
Connect to existing desktop |
desktop.screenshot(format, quality) |
Capture screenshot |
desktop.launch(application, args) |
Launch application |
desktop.mouse_click(x, y, button, double_click) |
Mouse click |
desktop.mouse_move(x, y) |
Move cursor |
desktop.mouse_scroll(x, y, delta_x, delta_y) |
Scroll |
desktop.mouse_drag(start_x, start_y, end_x, end_y) |
Drag |
desktop.keyboard_type(text) |
Type text |
desktop.keyboard_press(keys, duration_ms) |
Press keys |
desktop.cursor() |
Get cursor position |
desktop.open(path) |
Open file/URL |
desktop.stream_start() |
Start VNC stream |
desktop.stream_stop() |
Stop VNC stream |
desktop.stream_info() |
Get stream status |
desktop.list_windows() |
List windows |
desktop.close() |
Close desktop |
Error Handling
from dynamiq_sandboxes import (
Sandbox, APIError, AuthenticationError,
NotFoundError, RateLimitError, TimeoutError,
)
try:
sandbox = Sandbox.create(template="python")
result = sandbox.execute_command("echo hello")
except AuthenticationError:
print("Invalid API key")
except RateLimitError:
print("Rate limited, retry later")
except TimeoutError:
print("Request timed out")
except APIError as e:
print(f"API error: {e}")
Requirements
- Python 3.9+
- An active Dynamiq account
Links
- Dashboard: sandboxes.getdynamiq.ai
- Dynamiq Framework: github.com/dynamiq-ai/dynamiq
- Issues: GitHub Issues
License
Apache 2.0
Metadata
Release files for dynamiq-sandboxes 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dynamiq_sandboxes-0.3.1.tar.gz | 84.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dynamiq_sandboxes-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 160.4 kB
Release files / dynamiq_sandboxes-0.3.1.tar.gz
| Download URL | dynamiq_sandboxes-0.3.1.tar.gz |
|---|---|
| Size | 84.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
aedfa1b16402eb8b5081f78ff7d5216202528d14f917f9236505113e2b165bd6
|
|
BLAKE2b-256 checksum How to use checksums |
714349682398fd9b28f1f95c8c610089fa91b3caf4eaccf86eb02793de048bf1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.9
|
Release files / dynamiq_sandboxes-0.3.1-py3-none-any.whl
| Download URL | dynamiq_sandboxes-0.3.1-py3-none-any.whl |
|---|---|
| Size | 76.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bfd38191a8d0773241bc9990da3ce64ed689404f30fafd0d804cb483dcd7ab1c
|
|
BLAKE2b-256 checksum How to use checksums |
3cd804e08a62bc1a026bfbfe5a147d312089b18033be9345745435ed3daa0330
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.9
|