Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

App Builder Sandbox SDK (Python)

PyPI Downloads/week Python CI License Codecov Coverage

Python SDK for Adobe Runtime Sandboxes.

A sandbox is an ephemeral, isolated compute environment. You create one, run commands and read/write files inside it over a WebSocket session, then destroy it.

Pre-requisites

To use this library, you must have Sandboxes enabled for your Runtime namespace. Please contact Michael Goberling (mgoberling@adobe.com) or Cosmin Stanciu (stanciu@adobe.com) to request this.

Install

pip install aio-lib-sandbox

Quickstart

Inside a Runtime action, no configuration is needed to use the SDK as credentials are read automatically from the environment.

from aio_lib_sandbox import Sandbox


async def main(params):
    sandbox = await Sandbox.create(name="my-sandbox")

    result = await sandbox.exec("python --version", timeout=10_000)

    await sandbox.destroy()
    return {"stdout": result.stdout.strip()}

Configuration

When running inside a Runtime action, the SDK reads credentials from the environment automatically:

Variable Description
__OW_API_HOST Runtime API host
__OW_NAMESPACE Runtime namespace
__OW_API_KEY Runtime API key (basic auth)

You can override any of these by passing them explicitly to Sandbox.create() or Sandbox.get():

sandbox = await Sandbox.create(
    api_host="https://adobeioruntime.net",
    namespace="my-namespace",
    auth="my-api-key",
    name="my-sandbox",
)

Usage

Create Sandbox

from aio_lib_sandbox import Sandbox

sandbox = await Sandbox.create(
    name="my-sandbox",
    type="cpu:default",
    idle_timeout=900,
    max_lifetime=3600,
    ports=[3000, 8080],
    envs={"API_KEY": "your-api-key"},
)

Sandbox lifetime model

A sandbox is always deleted when max_lifetime has elapsed. It will also be deleted after the idle_timeout has elapsed, if there has been no activity.

To keep a sandbox alive, send at least one command or check the status every idle_timeout seconds.

Get Status

sandbox = await Sandbox.get(sandbox.id)
print("status:", sandbox.status)

Exec

result = await sandbox.exec("ls -al", timeout=10_000)
print("stdout:", result.stdout.strip())
print("exit code:", result.exit_code)

Note: Commands run in the /workspace directory by default, this is not configurable

Detached Commands

Pass detached=True to run a long-lived background process.

# Start a background server
handle = await sandbox.exec("python server.py", detached=True)

# Wait for it to exit (e.g. after you stop it)
result = await handle.wait()
print("exit code:", result.exit_code)

# Send a signal to stop it
await handle.kill()

If the process is still running and you need a handle to it from a different context, use get_command() to re-attach by exec_id:

handle = await sandbox.get_command(exec_id, on_output=lambda data, stream: print(data, end=""))
await handle.wait()

Note: Only 5 background processes are allowed to run at once currently.

File Management

script = "console.log('hello from sandbox script', process.version)\n"
await sandbox.write_file("hello.js", script)

content = await sandbox.read_file("hello.js")
print("read_file content:", content.strip())

entries = await sandbox.list_files(".")
print("list_files entries:", entries)

Exec a File

result = await sandbox.exec("node hello.js", timeout=10_000)
print("stdout:", result.stdout.strip())
print("stderr:", result.stderr.strip())
print("exit code:", result.exit_code)

Write to Stdin

Command start

result = await sandbox.exec(
    "python process_csv.py",
    stdin="col1,col2\nval1,val2\n",
    timeout=10_000,
)
print("stdout:", result.stdout.strip())

Running command

task = sandbox.exec("cat -n", timeout=10_000)

await sandbox.write_stdin(task.exec_id, "line 1\n")
await sandbox.write_stdin(task.exec_id, "line 2\n")
await sandbox.close_stdin(task.exec_id)

result = await task
print("stdout:", result.stdout.strip())

Destroy

await sandbox.destroy()

Preview URLs

Ports that should be publicly accessible must be declared at creation time via the ports list.

sandbox = await Sandbox.create(
    name="web-sandbox",
    ports=[3000, 8080],
)

# Start a server inside the sandbox on the declared port
await sandbox.exec("python -m http.server 3000 &", timeout=5_000)

# Retrieve the pre-provisioned preview URL — synchronous, no network call
url = sandbox.get_url(3000)
print("preview:", url)
# https://sb-abc123-va6-0-xK3mPq2nAeB-3000.sandbox-adobeioruntime.net

Network Policies

Sandboxes are default-deny. All outbound traffic is blocked unless explicitly allowed.

Pass a policy.network.egress array at creation time to allowlist outbound endpoints, paths, or HTTP verbs.

sandbox = await Sandbox.create(
    name="policy-sandbox",
    max_lifetime=300,
    policy={
        "network": {
            "egress": [
                {"host": "httpbin.org", "port": 443},
                {
                    "host": "api.github.com",
                    "port": 443,
                    "rules": [
                        {"methods": ["GET"], "pathPattern": "/repos/**"},
                    ],
                },
            ]
        }
    },
)

Development

Install development dependencies:

pip install -e ".[dev]"

To run the same checks used by CI:

hatch run test

Linting is powered by Ruff:

hatch run lint
hatch run lint-fix

Metadata

Release files for aio-lib-sandbox 0.1.0a10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aio-lib-sandbox 0.1.0a10
File Size Uploaded Provenance
aio_lib_sandbox-0.1.0a10.tar.gz 31.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for aio-lib-sandbox 0.1.0a10
File Interpreter ABI Platform
aio_lib_sandbox-0.1.0a10-py3-none-any.whl Python 3 none any Details

Total release size: 55.2 kB

Release files / aio_lib_sandbox-0.1.0a10.tar.gz

Download URL aio_lib_sandbox-0.1.0a10.tar.gz
Size 31.5 kB
Tags Source
SHA-256 checksum
How to use checksums
b6968c4ea638931d952890d2c9bd1bb65efc71da15e4787642ac1a104cc2518e
BLAKE2b-256 checksum
How to use checksums
3c803cc61f5152c28454da6a152138a4e0eb72cbd4a4d3676f26c9b20c802e3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / aio_lib_sandbox-0.1.0a10-py3-none-any.whl

Download URL aio_lib_sandbox-0.1.0a10-py3-none-any.whl
Size 23.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dca9854c632a11fb701e29067c26b30d4834ad583393dbc5359fcb323f98d528
BLAKE2b-256 checksum
How to use checksums
76c53265bde34bcecd202698335eae73294a26373feb416543b452f4c367bb2e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for aio-lib-sandbox 0.1.0a10

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page