Skip to main content

Python SDK for Dynamiq Sandboxes - Secure code execution, browser automation, and virtual desktops

Project description

Dynamiq Sandboxes

PyPI version Python 3.9+ License: Apache 2.0

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

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

dynamiq_sandboxes-0.2.2.tar.gz (80.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dynamiq_sandboxes-0.2.2-py3-none-any.whl (72.4 kB view details)

Uploaded Python 3

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

Hashes for dynamiq_sandboxes-0.2.2.tar.gz
Algorithm Hash digest
SHA256 106af8bc0e61700a36ae6519ca4d2135e507ffbdb9d73f6896ed4b71d3d27ac0
MD5 12d70eb9d981847a3731dcad0eb446d2
BLAKE2b-256 fd46401dc9d347be3ac0c410e136a89a0e404e4bf2ca78a7b3535f5a46e7ca58

See more details on using hashes here.

File details

Details for the file dynamiq_sandboxes-0.2.2-py3-none-any.whl.

File metadata

File hashes

Hashes for dynamiq_sandboxes-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1bf9cbeb67fe52c844e02c7aa17ffaf32e4201359ec1098dbfe91aee7c5bc0ed
MD5 d347a374ef894e5cf5d7c34c7a86f9ad
BLAKE2b-256 d282575cef5fb3c9319dab1506f4bfcdbe66065822d24090ffa38cd9b71093ce

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page