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')"])

# 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

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.3.0.tar.gz (84.0 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.3.0-py3-none-any.whl (75.6 kB view details)

Uploaded Python 3

File details

Details for the file dynamiq_sandboxes-0.3.0.tar.gz.

File metadata

  • Download URL: dynamiq_sandboxes-0.3.0.tar.gz
  • Upload date:
  • Size: 84.0 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.3.0.tar.gz
Algorithm Hash digest
SHA256 a2e02d7ac9f545e8eae95d6b7a854c1f9a2eaafffa3326657b19fd58bf652ba9
MD5 9631e92de4f942d2f58691ee1c014b1e
BLAKE2b-256 b9074d8d2e9a021d0f2f87ac3228182eb4d33995224da185abeaefd20514d209

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dynamiq_sandboxes-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 352ab05ed3ff71847ec3acfb12b12401d36467c6a3b413fecefc45b7574930ac
MD5 32f0f5d0d251f467d76a373d640dc442
BLAKE2b-256 f80898bb40c36c0ca401e932d72637fa65cf7076ffa76bc0caf3cfff92cb869b

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