Python SDK for Dynamiq Sandboxes - Secure code execution, browser automation, and virtual desktops
Project description
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')"])
# 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.close()
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()
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) |
Connect to existing sandbox |
sandbox.execute_command(command, args, working_dir, timeout) |
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.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
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dynamiq_sandboxes-0.2.2.tar.gz.
File metadata
- Download URL: dynamiq_sandboxes-0.2.2.tar.gz
- Upload date:
- Size: 80.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
106af8bc0e61700a36ae6519ca4d2135e507ffbdb9d73f6896ed4b71d3d27ac0
|
|
| MD5 |
12d70eb9d981847a3731dcad0eb446d2
|
|
| BLAKE2b-256 |
fd46401dc9d347be3ac0c410e136a89a0e404e4bf2ca78a7b3535f5a46e7ca58
|
File details
Details for the file dynamiq_sandboxes-0.2.2-py3-none-any.whl.
File metadata
- Download URL: dynamiq_sandboxes-0.2.2-py3-none-any.whl
- Upload date:
- Size: 72.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1bf9cbeb67fe52c844e02c7aa17ffaf32e4201359ec1098dbfe91aee7c5bc0ed
|
|
| MD5 |
d347a374ef894e5cf5d7c34c7a86f9ad
|
|
| BLAKE2b-256 |
d282575cef5fb3c9319dab1506f4bfcdbe66065822d24090ffa38cd9b71093ce
|