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.1.tar.gz (84.4 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.1-py3-none-any.whl (76.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: dynamiq_sandboxes-0.3.1.tar.gz
  • Upload date:
  • Size: 84.4 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.1.tar.gz
Algorithm Hash digest
SHA256 aedfa1b16402eb8b5081f78ff7d5216202528d14f917f9236505113e2b165bd6
MD5 993a06f41f7cb7157873bea0f8f0a03a
BLAKE2b-256 714349682398fd9b28f1f95c8c610089fa91b3caf4eaccf86eb02793de048bf1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dynamiq_sandboxes-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 bfd38191a8d0773241bc9990da3ce64ed689404f30fafd0d804cb483dcd7ab1c
MD5 acdb6dcafe6a88b38d8b132b4faceaee
BLAKE2b-256 3cd804e08a62bc1a026bfbfe5a147d312089b18033be9345745435ed3daa0330

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