Skip to main content

Python SDK for Adobe Runtime Sandboxes

Project description

App Builder Sandbox SDK (Python)

PyPI Downloads/week Python CI License Codecov Coverage Status

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.

[!WARNING] Alpha. This SDK is in active alpha development. The API surface and authentication model may change without notice. Pin exact versions; install only with --pre.

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 --pre 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

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

aio_lib_sandbox-0.1.0a9.tar.gz (31.8 kB view details)

Uploaded Source

Built Distribution

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

aio_lib_sandbox-0.1.0a9-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

File details

Details for the file aio_lib_sandbox-0.1.0a9.tar.gz.

File metadata

  • Download URL: aio_lib_sandbox-0.1.0a9.tar.gz
  • Upload date:
  • Size: 31.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aio_lib_sandbox-0.1.0a9.tar.gz
Algorithm Hash digest
SHA256 5d3be49801bf48ee0875ad2f92ed2b072febb0a0fd0c70430eb17e18a37140d7
MD5 6e33fdcd22d6be305eb038b750b81614
BLAKE2b-256 a13704f5e97281f5e66c1ac05aeec530075a356877ea1ca9dfa5b409595cadeb

See more details on using hashes here.

File details

Details for the file aio_lib_sandbox-0.1.0a9-py3-none-any.whl.

File metadata

File hashes

Hashes for aio_lib_sandbox-0.1.0a9-py3-none-any.whl
Algorithm Hash digest
SHA256 d802246c1bbbfb116a34c27a44b67bdf00d89eb28dab37e08f287405f0d28ce7
MD5 c65fcb6058891e31085f79bb80f181a8
BLAKE2b-256 3d625d41c14d28eb300842eb3a013834b8eb4ba1c7059ab365b77c621aa96bbb

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