Skip to main content

Docker sandbox tools for Axio

Project description

axio-tools-docker

PyPI Python License: MIT

Docker sandbox tools for axio.

DockerSandbox is an async context manager that spins up an isolated Docker container on entry and removes it on exit. Inside the context it exposes six axio tools — the same shell, write_file, read_file, list_files, run_python, and patch_file as axio-tools-local, but every operation runs inside the container, never on the host.

Requirements

Docker must be installed and running:

docker info   # should succeed

The package talks to the Docker Engine API directly via aiodocker — the docker CLI is not required.

Installation

pip install axio-tools-docker

Quick start

import asyncio
from axio.agent import Agent
from axio.context import MemoryContextStore
from axio.testing import StubTransport, make_text_response
from axio_tools_docker import DockerSandbox

async def main() -> None:
    transport = StubTransport([make_text_response("Done.")])
    async with DockerSandbox(image="python:3.12-alpine") as sandbox:
        agent = Agent(
            system="You are a coding assistant. Use the sandbox tools to run code safely.",
            tools=sandbox.tools,
            transport=transport,
        )
        ctx = MemoryContextStore()
        result = await agent.run("Print hello from Python.", ctx)
        print(result)

asyncio.run(main())

Sandbox tools

These mirror axio-tools-local exactly — same names and field schemas:

Tool Description
shell Run a shell command; returns stdout + stderr. Supports timeout, cwd, stdin.
write_file Create or overwrite a file. Parent directories are created automatically.
read_file Read a file with optional start_line/end_line, line_numbers, max_chars.
list_files List a directory; directories first with a trailing /.
run_python Execute a Python snippet in a subprocess. Supports timeout, cwd, stdin.
patch_file Replace lines from_line..to_line (1-indexed, inclusive). to_line = from_line - 1 inserts.

Container lifecycle

The container is created on __aenter__ and removed on __aexit__ (docker rm -f). Cleanup runs even when the body raises an exception:

async def run(ctx):
    async with DockerSandbox(image="alpine:latest") as sandbox:
        await agent.run("...", ctx)
    # container removed here (unless remove=False)

The image is pulled automatically if not present locally. If the Docker daemon is unreachable, __aenter__ raises immediately:

RuntimeError: Docker daemon not available at 'unix:///var/run/docker.sock': ...

The running container's ID is available as sandbox.container_id inside the async with block.

Named containers and reuse

Pass name= to give the container a fixed name. If a running container with that name already exists, the sandbox attaches to it instead of creating a new one, and never removes it on exit — regardless of remove:

import asyncio
from axio_tools_docker import DockerSandbox

async def first_session() -> None:
    async with DockerSandbox(image="python:3.12-slim", name="my-sandbox", remove=False) as sb:
        await sb.exec("pip install requests")

async def second_session() -> None:
    async with DockerSandbox(name="my-sandbox") as sb:
        result = await sb.exec("python3 -c 'import requests; print(requests.__version__)'")

asyncio.run(first_session())
asyncio.run(second_session())

Configuration

from axio_tools_docker import DockerSandbox

sandbox = DockerSandbox(
    "unix:///var/run/docker.sock",   # Docker daemon URL (positional)
    image="python:3.12-slim",
    memory="512m",                   # memory limit: "256m", "1g", …
    cpus="2.0",                      # CPU limit
    network=False,                   # False=none, True=default, str=explicit mode
    workdir="/workspace",
    volumes={"/workspace": "/tmp/host-dir"},   # {container_path: host_path}
    env={"PYTHONPATH": "/app"},
    user="nobody",
    name="my-agent-sandbox",
    remove=False,
    read_only=True,                  # read-only root filesystem
    shm_size="64m",                  # /dev/shm size
    cap_add=["NET_ADMIN"],           # add Linux capabilities
    cap_drop=["ALL"],                # drop Linux capabilities
    privileged=False,
    ulimits={"nofile": (1024, 65536), "nproc": 512},
    tmpfs={"/tmp": "size=128m,mode=1777"},
    ports={8080: 8080},              # {container_port: host_port}
    platform="linux/amd64",
    extra_hosts={"host.docker.internal": "host-gateway"},
    devices=["/dev/net/tun", "/dev/sda:/dev/xvda:r"],
    dns=["8.8.8.8", "1.1.1.1"],
)
Parameter Type Default Description
url str "unix:///var/run/docker.sock" Docker daemon URL (unix socket or TCP). Positional.
image str "python:latest" Container image. Pulled automatically if not present.
memory str "256m" Memory limit. Accepts k/m/g suffixes.
cpus str "1.0" CPU limit as a decimal string.
network bool | str False Network mode. Falsenone. True → Docker default. String → explicit NetworkMode (e.g. "host", "bridge", "my-net").
workdir str "/workspace" Working directory inside the container.
volumes dict[str, str] {} Bind mounts as {container_path: host_path}.
env dict[str, str] {} Environment variables passed to all commands.
user str "" User to run as (e.g. "nobody", "1000").
name str "" Container name. Attaches to existing container if found; creates new one otherwise.
remove bool True Remove container on exit. No effect when attached to an existing container.
read_only bool False Read-only root filesystem. Combine with tmpfs for writable scratch paths.
shm_size str "" /dev/shm size (e.g. "64m"). Useful for PyTorch / shared-memory IPC.
cap_add list[str] [] Linux capabilities to add (e.g. ["NET_ADMIN", "SYS_PTRACE"]).
cap_drop list[str] [] Linux capabilities to drop (e.g. ["ALL"]).
privileged bool False Extended privileges — full capability set and device access. Use with care.
ulimits dict[str, int | tuple[int, int]] {} Resource limits. {"nofile": 1024} → soft=hard=1024. {"nofile": (1024, 65536)} → soft/hard split.
tmpfs dict[str, str] {} Tmpfs mounts as {path: options} (e.g. {"/tmp": "size=128m,mode=1777"}).
ports dict[int, int] {} Port bindings as {container_port: host_port}. Only meaningful when network != False.
platform str "" Platform override (e.g. "linux/amd64", "linux/arm64").
extra_hosts dict[str, str] {} Extra /etc/hosts entries as {hostname: ip}.
devices list[str] [] Host devices to expose. Format: "/dev/sda", "/dev/sda:/dev/xvda", "/dev/sda:/dev/xvda:r".
dns list[str] [] DNS servers (e.g. ["8.8.8.8"]). Only meaningful when network != False.

Part of the axio ecosystem

axio · axio-tools-local · axio-tools-mcp · axio-tui

License

MIT

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

axio_tools_docker-0.8.0.tar.gz (48.4 kB view details)

Uploaded Source

Built Distribution

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

axio_tools_docker-0.8.0-py3-none-any.whl (12.5 kB view details)

Uploaded Python 3

File details

Details for the file axio_tools_docker-0.8.0.tar.gz.

File metadata

  • Download URL: axio_tools_docker-0.8.0.tar.gz
  • Upload date:
  • Size: 48.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for axio_tools_docker-0.8.0.tar.gz
Algorithm Hash digest
SHA256 6faff7b872feb39de38a2f8c12b18127d0b0add394c30e65899c8978d347b280
MD5 ca01a7fa52527ed0e69aa44e68f2bc45
BLAKE2b-256 738892e1ebed1f502c97169241ccf3460553c4fb038c9fbe331064bbc2b44c58

See more details on using hashes here.

Provenance

The following attestation bundles were made for axio_tools_docker-0.8.0.tar.gz:

Publisher: publish.yml on mosquito/axio-agent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file axio_tools_docker-0.8.0-py3-none-any.whl.

File metadata

File hashes

Hashes for axio_tools_docker-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a75d07cccb919a5abfbbd5825decde2371136b3911287bdd7f0e967656f0bce4
MD5 59d06680623ad34b16cbb61a571f4f3d
BLAKE2b-256 81bf07be0e5f2dfc68147d1dd3f02078de1adc5a6cb53541f9f5ddccbb3b55dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for axio_tools_docker-0.8.0-py3-none-any.whl:

Publisher: publish.yml on mosquito/axio-agent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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