airflow.providers.common.ai.sandbox.sbx¶
Docker Sandboxes (sbx) microVM backend for the SandboxToolset.
Attributes¶
Classes¶
Sandbox backend that runs agent commands in a Docker Sandboxes ( |
Module Contents¶
- class airflow.providers.common.ai.sandbox.sbx.SbxSandboxBackend(*, image='python:3.12-slim', memory='2g', cpus=None, sbx_path='sbx', create_timeout=600.0, host_network_policy='unknown')[source]¶
Bases:
airflow.providers.common.ai.sandbox.base.SandboxBackendSandbox backend that runs agent commands in a Docker Sandboxes (
sbx) microVM.Note
Experimental: this can change or be removed in a minor release of this provider. See Stable and experimental features.
Drives the
sbxCLI:createprovisions a per-session microVM,execruns commands in it, andrmtears it down. Each sandbox is a microVM with its own kernel, so agent code is isolated by a hardware boundary rather than a shared kernel. Effective isolation still depends on the image, host policy, and resource limits.Use this for local development, not production. Docker Sandboxes is built for running coding agents against a checkout on your own machine, so driving it from an Airflow worker is off-label use. A production worker would need the
sbxbinary on the host, an authenticated Docker account (sbx login), a one-timesbx policy init, and on Linux, KVM or nested virtualization – which an unprivileged container cannot provide. If you need Kubernetes, use a remote backend –ModalSandboxBackendfor a managed service orOpenSandboxBackendfor a self-hosted one – or add your own behindSandboxBackend.Network policy is layered on a host-level setting, not independent of one.
sbxgoverns egress through a host-levelsbx policy.createappliesallow_egress_toas a per-sandbox rule on top of that policy, but the rule can only narrow a host policy that is alreadydeny-alland never widen one.block_networkhas no per-sandbox enforcement at all: nosbxcall implements it. Rather than let a Dag author believe aSandboxSpecrestriction is in force when it is not,createraises instead of silently ignoring a spec that asks for either – and sinceblock_networkdefaults toTrue, a bareSandboxSpec()with no arguments already asks for it. It lets the spec through only when the Deployment Manager has already declared the host policy asdeny-allthroughhost_network_policy.Orphans are not reclaimed automatically. There is no server-side TTL to fall back on: if the worker is killed outright, the microVM and its workspace directory survive. Sandboxes are named
airflow-sandbox-*so an operator can find and remove them; budget for that sweep before running this at scale.The template image must provide GNU coreutils
timeout,base64,stat,head,find,mkdiranddirname, which the command and file tools use. Any Debian or Ubuntu based image, includingpython:*-slim, does.- Parameters:
image (str) – Container image for the sandbox (
sbx --template). Default"python:3.12-slim".memory (str) – Memory limit in binary units (e.g.
"2g").sbxenforces a 1 GiB minimum. Default"2g".cpus (int | None) – Number of CPUs to allocate.
None(default) uses thesbxdefault, which is all host CPUs.sbx_path (str) – Path to the
sbxbinary. Default"sbx".create_timeout (float) – Seconds to allow for provisioning; first-run microVM boot plus an image pull can be slow. Default
600.host_network_policy (HostNetworkPolicy) – What
sbx policyis set to on this host."unknown"(default) makescreaterefuse any spec that asks for a network guarantee. Set"deny-all"after runningsbx policy init deny-all, or"allow-all"to state that egress is open and have specs requesting isolation refused.
- create(*, spec=None)[source]¶
Provision one sandbox and return its handle (name or id).
specofNonemeans “no requirements stated”: the backend applies its own defaults and makes no guarantee. It is not the same as a defaultSandboxSpec, which is an explicit request for an isolated sandbox. The toolset always sends a concrete spec, soNoneonly reaches a backend a caller drives directly.Raise
SandboxTerminalErrorifspecasks for something this backend cannot enforce, rather than provisioning something weaker than was asked for. It is terminal rather than recoverable because it states a configuration fact the model cannot see and cannot fix by retrying.Every failure raised here is terminal, whichever class carries it. The model has no input into provisioning, so a
SandboxErrorfromcreateis not something it can work around; the toolset re-raises one asSandboxTerminalErrorand fails the task, so Airflow’s retry attempts the provisioning again.
- run_command(sandbox, command, *, timeout, max_output_bytes)[source]¶
Run
commandthrough a shell in the sandbox, bounded bytimeoutseconds.max_output_bytesbounds what the backend retains per stream while reading, so unbounded command output cannot exhaust worker memory before the toolset gets a chance to format it.
- write_file(sandbox, path, content)[source]¶
Override: send the payload on stdin instead of in the command.
The base implementation embeds the content in the command itself, which the guest’s command-line length caps.
sbx execaccepts stdin, so a large file needs no such ceiling here.
- export_file(sandbox, path, dest, *, max_bytes)[source]¶
Override: stream the file out of one
sbx execstraight intodest.sbx execcarries the guest’s stdout byte for byte, so the default’s base64 round trip per slice buys nothing here. The guest reports the size it is about to send on stderr, which is how a file still being written is caught.