Skip to main content

A3S Box Python SDK

a3s-box is a local-first Python SDK with familiar E2B-style Sandbox, commands, and files APIs. It controls the A3S Box runtime installed on the same machine. It does not depend on, wrap, import, or contact the official E2B SDK.

Local use

Install the A3S Box runtime and the Python package:

brew install a3s-lab/tap/a3s-box
python -m pip install a3s-box

No endpoint or API key is required:

from a3s_box import Sandbox

with Sandbox.create("python:3.12-alpine") as sandbox:
    result = sandbox.commands.run("python -c 'print(6 * 7)'")
    print(result.stdout)

    sandbox.files.write("/workspace/note.txt", "hello")
    print(sandbox.files.read("/workspace/note.txt"))

Sandbox.create() defaults to alpine:3.20 and MicroVM isolation. The first argument is an OCI image reference in local mode. Select the shared-kernel Sandbox backend explicitly on a certified Linux host:

sandbox = Sandbox.create(
    "python:3.12-alpine",
    isolation="sandbox",
    cpus=2,
    memory_mb=1024,
)

Async applications use the same local runtime:

import asyncio

from a3s_box import AsyncSandbox


async def main() -> None:
    async with await AsyncSandbox.create("python:3.12-alpine") as sandbox:
        result = await sandbox.commands.run(["python", "-c", "print(6 * 7)"])
        print(result.stdout)


asyncio.run(main())

Lifecycle and inspection

Local Sandbox lifecycle calls are generation-fenced. stop() preserves the durable Sandbox, restart() advances its generation under a caller-supplied idempotency identity, remove() deletes a terminal Sandbox, and kill() performs stop plus removal. Reuse the same operation_id when retrying a restart whose outcome is not yet known.

from a3s_box import A3SBoxClient, Sandbox

client = A3SBoxClient()
sandbox = Sandbox.create("alpine:3.20")

try:
    logs = sandbox.logs(tail=100)
    stats = sandbox.stats()
    print(len(logs), stats.memory_percent if stats else None)

    sandbox.stop()
    sandbox.restart(operation_id="ci-restart-1", stop_timeout=10)
    print(client.get_sandbox(sandbox.id))
finally:
    sandbox.kill()

Log snapshots contain structured stream, message, and timestamp values, and accept tails from 1 through 10,000 entries. The runtime client also exposes list_sandboxes(), get_sandbox(), runtime_diagnostics(), runtime_disk_usage(), list_filesystem_snapshots(), and get_filesystem_snapshot(). A3SAsyncBoxClient and AsyncSandbox provide the same operations with async methods.

Builder-style programmable CI/CD

The E2B-style API remains available for direct execution. For build and CI tooling, A3SBoxClient adds fluent builders over the same local runtime and bridge:

from a3s_box import A3SBoxClient

client = A3SBoxClient()

image = (
    client.image("./ci")
    .dockerfile("Dockerfile")
    .tag("local/ci-base:latest")
    .build_arg("NODE_VERSION", "24")
    .build()
)
cache = (
    client.volume("npm-cache")
    .label("purpose", "ci-cache")
    .size_limit(10 * 1024 * 1024 * 1024)
    .create()
)
network = client.network("ci-net").subnet("10.89.40.0/24").create()

with (
    client.sandbox(image.reference)
    .cpus(4)
    .memory_mb(4096)
    .mount_named(cache.name, "/root/.npm")
    .network(network.name)
    .publish_tcp(8080, 8080)
    .workdir("/workspace")
    .start()
) as box:
    result = (
        box.script("npm ci\nnpm test\n")
        .interpreter("/bin/sh", "-se")
        .env("CI", "true")
        .run()
    )
    if result.exit_code != 0:
        raise RuntimeError(result.stderr)

A3SAsyncBoxClient provides the same builders with asynchronous terminal operations. Named volumes and networks must be created explicitly before they are mounted or selected. Builder scripts are sent through standard input to the selected interpreter, so their contents are not interpolated into a host shell command.

Named bridge networks and published ports are currently MicroVM-only. A shared-kernel Sandbox request that selects either fails before runtime mutation; use .disable_network() or the default TSI-compatible configuration for supported Sandbox workloads.

The package invokes the versioned machine bridge built into the installed a3s-box executable. It does not parse human CLI output. Set A3S_BOX_BINARY only when the executable is not on PATH.

Host resources use the same typed client:

import os

from a3s_box import A3SBoxClient, RegistryCredentials, SignaturePolicy

client = A3SBoxClient()
credentials = RegistryCredentials("builder", os.environ["REGISTRY_PASSWORD"])
image = client.pull_image(
    "registry.example/ci/base:latest",
    credentials=credentials,
    signature_policy=SignaturePolicy.cosign_key("/keys/cosign.pub"),
)
metadata = client.inspect_image(image.reference)
history = client.image_history(image.reference)
tagged = client.tag_image(image.reference, "local/ci-base:tested")
client.push_image(
    tagged.reference,
    "registry.example/ci/base:tested",
    credentials=credentials,
)
client.prune_volumes()
client.prune_networks()

client.capabilities() returns the bridge protocol version and exact supported operation names. Passwords are passed only to the local runtime process and are not read from the remote-only endpoint/API-key environment variables.

Remote and self-hosted deployments

A3S_BOX_ENDPOINT, A3S_BOX_API_KEY, A3S_BOX_DOMAIN, and A3S_BOX_SANDBOX_URL are remote-only settings. Local Sandbox.create() never reads them.

The native package exposes A3SRemoteConnection as a typed configuration helper for applications that deliberately install an unchanged official E2B client and point it at a remote A3S Box compatibility service:

from a3s_box import A3SRemoteConnection
from e2b import Sandbox as RemoteSandbox

connection = A3SRemoteConnection.from_environment()
remote = RemoteSandbox.create(
    "code-interpreter-v1",
    **connection.official_python_options(),
)
remote.kill()

This explicit migration path is separate from the native local SDK. The official client is not a dependency of a3s-box.

See the repository README for complete self-hosted endpoint, wildcard DNS, TLS, and API-key setup.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

a3s_box-3.1.0.tar.gz (28.5 kB view details)

Uploaded Source

Built Distribution

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

a3s_box-3.1.0-py3-none-any.whl (24.0 kB view details)

Uploaded Python 3

File details

Details for the file a3s_box-3.1.0.tar.gz.

File metadata

  • Download URL: a3s_box-3.1.0.tar.gz
  • Upload date:
  • Size: 28.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for a3s_box-3.1.0.tar.gz
Algorithm Hash digest
SHA256 458ce58a2badde4bcbf7fa62b2f16bc03df02ce0541a8546fd815882ec3ac569
MD5 0a91b4e8d83e525689a83ae19a9eb27a
BLAKE2b-256 e97e4d57639cb4423019c69da6cc7975b658028aeb12525510660b0538b871e1

See more details on using hashes here.

File details

Details for the file a3s_box-3.1.0-py3-none-any.whl.

File metadata

  • Download URL: a3s_box-3.1.0-py3-none-any.whl
  • Upload date:
  • Size: 24.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for a3s_box-3.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 468822a2023b9e7c28f3cfba0c07996659655684f1de8e5b41d87e01be3b0f46
MD5 4e5c28a87e0fe5bf606b89483cf3f92e
BLAKE2b-256 2c8f9bbf740baf96b2c4e82e99dddb71eb64a02e05695ee0b59a578b8e7af323

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