This release is a pre-release and may not be stable for production use.
App Builder Sandbox SDK (Python)
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
/workspacedirectory 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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| aio_lib_sandbox-0.1.0a10.tar.gz | 31.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.