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.0a8.tar.gz (31.2 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.0a8-py3-none-any.whl (23.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: aio_lib_sandbox-0.1.0a8.tar.gz
  • Upload date:
  • Size: 31.2 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.0a8.tar.gz
Algorithm Hash digest
SHA256 c4c573607618fe59862085b04aa0eebde1715ff3eb3bb4be28cfb593f87ce360
MD5 f2217fa88b70ede99c0d7183e7f33135
BLAKE2b-256 e507262e90c629a91ee4aac07feddc0ea7dda2eea183ae7d2789f932f09c7354

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aio_lib_sandbox-0.1.0a8-py3-none-any.whl
Algorithm Hash digest
SHA256 9574e1be7fc9be11fbbac38704ae974e905cd7e5952fb03760725c9c099c6905
MD5 b282ef1f3d98cf7627bb691c3faa5c35
BLAKE2b-256 5b3d875bbfb8cee4d3b3b60a128398bfe4b66985a4e5717f86d6b0d3568b54cb

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