sandbox

Sandbox

Represents a Daytona Sandbox.

Attributes:

env: dict[str, str] | None

env = None

network_block_all: bool | None

network_block_all = None

kvm: bool | None

kvm = None

Sandbox.init

def __init__(sandbox_dto: SandboxDto | SandboxListItem,
             toolbox_api: ApiClient,
             sandbox_api: SandboxApi,
             language: str,
             subscription_manager: SyncEventSubscriptionManager,
             http_client: httpx.Client,
             analytics_api_url_provider: Callable[[], str | None]
             | None = None)

Initialize a new Sandbox instance.

Arguments:

Sandbox.refresh_data

@intercept_errors(message_prefix="Failed to refresh sandbox data: ")
@with_instrumentation()
def refresh_data(request_timeout: float | None = None) -> None

Refreshes the Sandbox data from the API.

Arguments:

Example:

sandbox.refresh_data()

print(f"Sandbox {sandbox.id}:")

print(f"State: {sandbox.state}")

print(f"Resources: {sandbox.cpu} CPU, {sandbox.memory} GiB RAM")

Sandbox.get_user_home_dir

@intercept_errors(message_prefix="Failed to get user home directory: ")
@with_instrumentation()
def get_user_home_dir() -> str

Gets the user’s home directory path inside the Sandbox.

Returns:

Example:

user_home_dir = sandbox.get_user_home_dir()

print(f"Sandbox user home: {user_home_dir}")

Sandbox.get_work_dir

@intercept_errors(message_prefix="Failed to get working directory path: ")
@with_instrumentation()
def get_work_dir() -> str

Gets the working directory path inside the Sandbox.

Returns:

Example:

work_dir = sandbox.get_work_dir()

print(f"Sandbox working directory: {work_dir}")

Sandbox.get_metrics_latest

@intercept_errors(message_prefix="Failed to get sandbox metrics: ")
@with_instrumentation()
def get_metrics_latest() -> SandboxMetrics

Gets the most recent resource usage sample directly from the Sandbox daemon.

Unlike :meth:get_metrics, which returns aggregated historical samples, this returns the single current reading without going through the telemetry backend.

Returns:

Sandbox.get_metrics

@intercept_errors(message_prefix="Failed to get sandbox metrics: ")
@with_instrumentation()
def get_metrics(start: datetime | None = None,
                end: datetime | None = None) -> list[SandboxMetrics]

Gets historical time-series resource usage metrics for the Sandbox.

When the deployment runs a dedicated Analytics API, metrics are fetched from it directly; otherwise they are fetched through the control-plane telemetry proxy.

Arguments:

Returns:

Sandbox.create_lsp_server

@with_instrumentation()
def create_lsp_server(language_id: LspLanguageId | LspLanguageIdLiteral,
                      path_to_project: str) -> LspServer

Creates a new Language Server Protocol (LSP) server instance.

The LSP server provides language-specific features like code completion, diagnostics, and more.

Arguments:

Returns:

Example:

lsp = sandbox.create_lsp_server("python", "workspace/project")

Sandbox.set_labels

@intercept_errors(message_prefix="Failed to set labels: ")
@with_instrumentation()
def set_labels(labels: dict[str, str],
               request_timeout: float | None = None) -> dict[str, str]

Sets labels for the Sandbox.

Labels are key-value pairs that can be used to organize and identify Sandboxes.

Arguments:

Returns: dict[str, str]: Dictionary containing the updated Sandbox labels.

Example:

new_labels = sandbox.set_labels({
    "project": "my-project",
    "environment": "development",
    "team": "backend"
})

print(f"Updated labels: {new_labels}")

Sandbox.download_url

@intercept_errors(message_prefix="Failed to create download URL: ")
@with_instrumentation()
def download_url(path: str, ttl_seconds: int | None = None) -> str

Creates a pre-signed URL for downloading a file from the Sandbox.

The URL works with any HTTP client without auth headers and stays valid across sandbox restarts (downloads succeed only while the sandbox is running). The signing key is cached locally for up to 15 seconds; if the key was rotated from another client, URLs may be rejected until the cache refreshes.

Arguments:

Returns:

Example:

url = sandbox.download_url("/home/user/report.pdf")

Sandbox.upload_url

@intercept_errors(message_prefix="Failed to create upload URL: ")
@with_instrumentation()
def upload_url(path: str, ttl_seconds: int | None = None) -> str

Creates a pre-signed URL for uploading a file to the Sandbox.

Send a POST request with the file as multipart/form-data. The URL works with any HTTP client without auth headers. The signing key is cached locally for up to 15 seconds; if the key was rotated from another client, URLs may be rejected until the cache refreshes.

Arguments:

Returns:

Example:

url = sandbox.upload_url("/home/user/data.bin")

Sandbox.rotate_signing_key

@intercept_errors(message_prefix="Failed to rotate signing key: ")
@with_instrumentation()
def rotate_signing_key() -> None

Rotates the sandbox signing key, invalidating all previously signed URLs.

Example:

sandbox.rotate_signing_key()

# all URLs created before this call now return 401

Sandbox.start

@intercept_errors(message_prefix="Failed to start sandbox: ")
@with_timeout()
@with_instrumentation()
def start(timeout: float | None = 60)

Starts the Sandbox and waits for it to be ready.

Arguments:

Raises:

Example:

sandbox = daytona.get("my-sandbox-id")

sandbox.start(timeout=40)  # Wait up to 40 seconds

print("Sandbox started successfully")

Sandbox.recover

@intercept_errors(message_prefix="Failed to recover sandbox: ")
@with_timeout()
def recover(timeout: float | None = 60)

Recovers the Sandbox from a recoverable error and waits for it to be ready.

Arguments:

Raises:

Example:

sandbox = daytona.get("my-sandbox-id")

sandbox.recover(timeout=40)  # Wait up to 40 seconds

print("Sandbox recovered successfully")

Sandbox.stop

@intercept_errors(message_prefix="Failed to stop sandbox: ")
@with_timeout()
@with_instrumentation()
def stop(timeout: float | None = 60, force: bool = False)

Stops the Sandbox and waits for it to be fully stopped.

Arguments:

Raises:

Example:

sandbox = daytona.get("my-sandbox-id")

sandbox.stop()

print("Sandbox stopped successfully")

Sandbox.delete

@intercept_errors(message_prefix="Failed to remove sandbox: ")
@with_timeout()
@with_instrumentation()
def delete(timeout: float | None = 60, wait: bool = False) -> None

Deletes the Sandbox.

By default returns as soon as the deletion request is accepted (fire-and-forget). Pass wait=True to block until the Sandbox reaches the ‘destroyed’ state.

Arguments:

Sandbox.wait_for_sandbox_start

@intercept_errors(
    message_prefix="Failure during waiting for sandbox to start: ")
@with_timeout()
@with_instrumentation()
def wait_for_sandbox_start(timeout: float | None = 60) -> None

Waits for the Sandbox to reach the ‘started’ state.

Arguments:

Raises:

Sandbox.wait_for_sandbox_stop

@intercept_errors(
    message_prefix="Failure during waiting for sandbox to stop: ")
@with_timeout()
@with_instrumentation()
def wait_for_sandbox_stop(timeout: float | None = 60) -> None

Waits for the Sandbox to reach the ‘stopped’ state. Treats destroyed as stopped to cover ephemeral sandboxes that are automatically deleted after stopping.

Arguments:

Raises:

Sandbox.set_autostop_interval

@intercept_errors(message_prefix="Failed to set auto-stop interval: ")
@with_instrumentation()
def set_autostop_interval(interval: int,
                          request_timeout: float | None = None) -> None

Sets the auto-stop interval for the Sandbox.

The Sandbox will automatically stop after being idle (no new events) for the specified interval. Events include any state changes or interactions with the Sandbox through the SDK. Interactions using Sandbox Previews are not included.

Arguments:

Raises:

Example:

# Auto-stop after 1 hour

sandbox.set_autostop_interval(60)

# Or disable auto-stop

sandbox.set_autostop_interval(0)

Sandbox.set_public

@intercept_errors(message_prefix="Failed to set public status: ")
@with_instrumentation()
def set_public(public: bool, request_timeout: float | None = None) -> None

Sets whether the Sandbox’s preview URLs are publicly accessible.

When public, preview URLs (see get_preview_link) can be opened without a preview token or API key. When private, every preview request must authenticate.

Arguments:

Example:

sandbox.set_public(True)

preview = sandbox.get_preview_link(3000)

# preview.url can now be opened without credentials

Sandbox.set_auto_pause_interval

@intercept_errors(message_prefix="Failed to set auto-pause interval: ")
@with_instrumentation()
def set_auto_pause_interval(interval: int) -> None

Sets the auto-pause interval for the Sandbox.

The Sandbox will automatically pause after being idle (no new events) for the specified interval. Only supported for sandbox classes that support pausing.

Arguments:

Raises:

Example:

# Auto-pause after 1 hour

sandbox.set_auto_pause_interval(60)

# Or disable auto-pause

sandbox.set_auto_pause_interval(0)

Sandbox.set_ttl

@intercept_errors(message_prefix="Failed to set TTL: ")
@with_instrumentation()
def set_ttl(ttl_minutes: int, request_timeout: float | None = None) -> None

Sets the TTL (time to live) for the Sandbox.

The Sandbox will be destroyed after the specified number of minutes, counted as wall-clock time from the current moment, regardless of its state (started, stopped, paused, or archived). Setting to 0 disables the TTL.

Arguments:

Raises:

Example:

# Set TTL to 1 hour

sandbox.set_ttl(60)

# Or disable TTL

sandbox.set_ttl(0)

Sandbox.set_auto_archive_interval

@intercept_errors(message_prefix="Failed to set auto-archive interval: ")
@with_instrumentation()
def set_auto_archive_interval(interval: int,
                              request_timeout: float | None = None) -> None

Sets the auto-archive interval for the Sandbox.

The Sandbox will automatically archive after being continuously stopped for the specified interval.

Arguments:

Raises:

Example:

# Auto-archive after 1 hour

sandbox.set_auto_archive_interval(60)

# Or use the maximum interval

sandbox.set_auto_archive_interval(0)

Sandbox.set_auto_delete_interval

@intercept_errors(message_prefix="Failed to set auto-delete interval: ")
@with_instrumentation()
def set_auto_delete_interval(interval: int,
                             request_timeout: float | None = None) -> None

Sets the auto-delete interval for the Sandbox.

The Sandbox will automatically delete after being continuously stopped for the specified interval.

Arguments:

Example:

# Auto-delete after 1 hour

sandbox.set_auto_delete_interval(60)

# Or delete immediately upon stopping

sandbox.set_auto_delete_interval(0)

# Or disable auto-delete

sandbox.set_auto_delete_interval(-1)

Sandbox.update_network_settings

@intercept_errors(message_prefix="Failed to update network settings: ")
@with_instrumentation()
def update_network_settings(*,
                            network_block_all: bool | None = None,
                            network_allow_list: str | None = None,
                            domain_allow_list: str | None = None,
                            request_timeout: float | None = None) -> None

Updates outbound network policy on the runner (block all, restore access, or CIDR allow list).

Arguments:

Raises:

Example:

sandbox.update_network_settings(network_block_all=True)

sandbox.update_network_settings(network_block_all=False)

Sandbox.update_secrets

@intercept_errors(message_prefix="Failed to update secrets: ")
@with_instrumentation()
def update_secrets(secrets: dict[str, str]) -> None

Updates the set of vault secrets mounted in the Sandbox, replacing the previously mounted set.

Attached, detached and rotated secrets take effect for outbound requests within seconds. New environment variables only become visible to processes spawned after the update, and a Sandbox created without any secrets must be restarted for newly attached secrets to work.

Arguments:

Example:

sandbox.update_secrets({"ANTHROPIC_API_KEY": "anthropic-prod"})

sandbox.update_secrets({})  # detach all

Sandbox.update_env

@intercept_errors(message_prefix="Failed to update environment: ")
@with_instrumentation()
def update_env(env: dict[str, str], *, unset: list[str] | None = None) -> None

Updates the Sandbox daemon’s process environment.

Newly spawned processes, sessions and PTYs inherit the change; already-running processes keep their environment.

Arguments:

Example:

sandbox.update_env({"MY_VAR": "value"}, unset=["OLD_VAR"])

Sandbox.get_preview_link

@intercept_errors(message_prefix="Failed to get preview link: ")
@with_instrumentation()
def get_preview_link(port: int,
                     request_timeout: float | None = None) -> PortPreviewUrl

Retrieves the preview link for the sandbox at the specified port. If the port is closed, it will be opened automatically. For private sandboxes, a token is included to grant access to the URL.

For a private sandbox, requests to url must authenticate, otherwise they are answered with 401 Unauthorized. Send the returned token in the X-Daytona-Preview-Token header, or send your Daytona API key as Authorization: Bearer <api key>. To get a URL that works without extra headers (for example to open it in a browser or share it), use create_signed_preview_url instead. Public sandboxes need no credentials.

Arguments:

Returns:

Example:

import httpx

preview_link = sandbox.get_preview_link(3000)

print(f"Preview URL: {preview_link.url}")

print(f"Token: {preview_link.token}")

# Fetch the private preview from outside the sandbox

response = httpx.get(
    preview_link.url,
    headers={"X-Daytona-Preview-Token": preview_link.token},
)

Sandbox.create_signed_preview_url

@intercept_errors(message_prefix="Failed to create signed preview url: ")
def create_signed_preview_url(
        port: int,
        expires_in_seconds: int | None = None,
        request_timeout: float | None = None) -> SignedPortPreviewUrl

Creates a signed preview URL for the sandbox at the specified port.

The access token is embedded in the returned URL, so it can be used without any headers, for example in a browser or by another service. The URL stops working when it expires (after 60 seconds unless expires_in_seconds is set) or when it is expired with expire_signed_preview_url.

Arguments:

Returns:

Example:

signed = sandbox.create_signed_preview_url(3000, expires_in_seconds=3600)

print(f"Preview URL (valid for one hour): {signed.url}")

Sandbox.expire_signed_preview_url

@intercept_errors(message_prefix="Failed to expire signed preview url: ")
def expire_signed_preview_url(port: int,
                              token: str,
                              request_timeout: float | None = None) -> None

Expires a signed preview URL for the sandbox at the specified port.

Arguments:

Sandbox.archive

@intercept_errors(message_prefix="Failed to archive sandbox: ")
@with_instrumentation()
def archive(request_timeout: float | None = None) -> None

Archives the sandbox, making it inactive and preserving its state. When sandboxes are archived, the entire filesystem state is moved to cost-effective object storage, making it possible to keep sandboxes available for an extended period. The tradeoff between archived and stopped states is that starting an archived sandbox takes more time, depending on its size. Sandbox must be stopped before archiving.

Arguments:

Sandbox.resize

@intercept_errors(message_prefix="Failed to resize sandbox: ")
@with_timeout()
@with_instrumentation()
def resize(resources: Resources, timeout: float | None = 60) -> None

Resizes the Sandbox resources.

Changes the CPU, memory, or disk allocation. Hot resize (on a running Sandbox) accepts only CPU and memory increases. Disk resize requires a stopped Sandbox; disk can only grow. GPU is not resizable — to change GPU, create a new Sandbox.

Arguments:

Raises:

Example:

sandbox.resize(Resources(cpu=4, memory=8))

sandbox.stop()

sandbox.resize(Resources(cpu=2, memory=4, disk=30))

Sandbox.wait_for_resize_complete

@intercept_errors(
    message_prefix="Failure during waiting for resize to complete: ")
@with_timeout()
@with_instrumentation()
def wait_for_resize_complete(timeout: float | None = 60) -> None

Waits for the Sandbox resize operation to complete.

Arguments:

Raises:

Sandbox.create_ssh_access

@intercept_errors(message_prefix="Failed to create SSH access: ")
@with_instrumentation()
def create_ssh_access(expires_in_minutes: int | None = None,
                      request_timeout: float | None = None) -> SshAccessDto

Creates an SSH access token for the sandbox.

Arguments:

Sandbox.revoke_ssh_access

@intercept_errors(message_prefix="Failed to revoke SSH access: ")
@with_instrumentation()
def revoke_ssh_access(token: str,
                      request_timeout: float | None = None) -> None

Revokes an SSH access token for the sandbox.

Arguments:

Sandbox.validate_ssh_access

@intercept_errors(message_prefix="Failed to validate SSH access: ")
@with_instrumentation()
def validate_ssh_access(
        token: str,
        request_timeout: float | None = None) -> SshAccessValidationDto

Validates an SSH access token for the sandbox.

Arguments:

Sandbox.refresh_activity

@intercept_errors(message_prefix="Failed to refresh sandbox activity: ")
def refresh_activity(request_timeout: float | None = None) -> None

Refreshes the sandbox activity to reset the timer for automated lifecycle management actions. This method updates the sandbox’s last activity timestamp without changing its state. It is useful for keeping long-running sessions alive while there is still user activity.

Arguments:

Example:

sandbox.refresh_activity()

Sandbox.fork

@intercept_errors(message_prefix="Failed to fork sandbox: ")
@with_timeout()
@with_instrumentation()
def fork(name: str | None = None, timeout: float | None = 60) -> "Sandbox"

Forks the Sandbox, creating a new Sandbox with an identical filesystem.

The forked Sandbox is a copy-on-write clone of the original. It starts with the same disk contents but operates independently from that point on.

Arguments:

Returns:

Raises:

Example:

sandbox = daytona.get("my-sandbox")

forked = sandbox.fork(name="my-fork")

print(f"Forked sandbox: {forked.id}")

Sandbox.create_snapshot

@intercept_errors(message_prefix="Failed to create snapshot: ")
@with_timeout()
@with_instrumentation()
def create_snapshot(name: str, timeout: float | None = 60) -> None

Creates a snapshot from the current state of the Sandbox.

This captures the Sandbox’s filesystem into a reusable snapshot that can be used to create new Sandboxes. The Sandbox will temporarily enter a ‘snapshotting’ state and return to its previous state when complete.

Arguments:

Raises:

Example:

sandbox = daytona.get("my-sandbox")

sandbox.create_snapshot("my-snapshot")

print("Snapshot created successfully")

Sandbox.pause

@intercept_errors(message_prefix="Failed to pause sandbox")
@with_timeout()
@with_instrumentation()
def pause(timeout: float = 60) -> None

Pauses the Sandbox, freezing all running processes.

The Sandbox will enter a ‘pausing’ state and transition to ‘paused’ when complete. While paused, the Sandbox retains its state in memory but does not consume CPU cycles.

Arguments:

Raises:

Resources

Resources configuration for Sandbox.

Attributes:

Example:

resources = Resources(
    cpu=2,
    memory=4,  # 4GiB RAM
    disk=20,   # 20GiB disk
    gpu=1,
    gpu_type=GpuType.H100,
)
params = CreateSandboxFromImageParams(
    image=Image.debian_slim("3.12"),
    language="python",
    resources=resources
)

ListSandboxesQuery

Query parameters for filtering and sorting when listing Sandboxes.

Attributes:

SandboxMetrics

A single point-in-time sample of historical Sandbox resource usage.

Each instance corresponds to one aggregation bucket returned by the telemetry backend. Use :meth:Sandbox.get_metrics to fetch a time-ordered list of these, or :meth:Sandbox.get_metrics_latest for the current sample.

Attributes: