airflow.providers.common.ai.sandbox.boat¶
Boat backend for SandboxToolset.
Attributes¶
Classes¶
Sandbox backend that runs agent commands in a Boat sandbox. |
Module Contents¶
- class airflow.providers.common.ai.sandbox.boat.BoatSandboxBackend(*, boat_conn_id=None, org='personal', machine_type='default', ttl_seconds=3600, ready_timeout=300.0, request_timeout=30.0)[source]¶
Bases:
airflow.providers.common.ai.sandbox.base.SandboxBackendSandbox backend that runs agent commands in a Boat sandbox.
Note
Experimental: this can change or be removed in a minor release of this provider. See Stable and experimental features.
Boat (formerly Ascii Box) is a hosted cloud-computer API: the Airflow worker needs only network access and an API key, with no local daemon or host virtualization.
Credentials come from a generic Airflow connection, resolved on first use: its
passwordis the Boat API key, and itshost, when set, the API base URL. Without a connection, the backend readsBOAT_API_KEY(required) and optionalBOAT_BASE_URL(the full API base URL with its scheme) from the worker environment on first use.Every sandbox is created with Boat’s
noEnvflag, so it gets none of the account’s stored environment variables, secret files or credentials, and cannot act on the account or its other sandboxes.SandboxSpec.envis the only environment it receives.Boat cannot enforce a deny-all, per-domain, or CIDR egress policy.
createtherefore refuses aSandboxSpecthat asks forblock_network=True,allow_egress_to, orallow_egress_to_cidrs, preserving the fail-closed contract. PassSandboxSpec(block_network=False)(and set that onSandboxToolset) when open egress is acceptable.Writes use Boat’s native file API, which accepts only paths that resolve under
/home/user(where relative paths land) or/tmp. The parent directory is created first withmkdir -pin the guest, so a write anywhere else reaches the model as a recoverable error:mkdir’s own when the guest user cannot create the parent directory, and one carrying Boat’sinvalid_pathcode when that directory exists or could be created. Reads use the inherited shell implementation, because the native read API takes no size parameter and would land a whole file in worker memory beforemax_bytescould reject it.- Parameters:
boat_conn_id (str | None) – Generic Airflow connection ID. Its
passwordis the Boat API key and is required; itshost, when set, is the full API base URL with its scheme, such ashttps://boat.dev/api/v1.None(default) readsBOAT_API_KEYand optionalBOAT_BASE_URLfrom the worker environment instead.org (str) – Boat wallet the sandbox is billed to, by organization id or name, or
"personal"for the account’s own. Boat lets every member of an organization open, run commands in, and read and write files in anoEnvsandbox billed to it, so naming one puts them all inside the sandbox’s trust boundary. Default"personal", which also overrides the account’s active wallet.machine_type (str) – Boat machine size:
small,default, orlarge. Default"default".ttl_seconds (int) – Server-side TTL in seconds after which Boat stops the sandbox even if the worker never destroyed it: a whole number from 1 to 2592000 (30 days). The sandbox is created without snapshots, so stopping it erases its disk. Default
3600.ready_timeout (float) – Seconds allowed for provisioning, from the create request until the sandbox is ready. A create request that times out, fails in transport, or gets a server error is sent again with the same idempotency key, and again two seconds after each 409
idempotency_in_progressanswer untilready_timeoutruns out. Each resend gets what is left ofready_timeoutplusrequest_timeout, so provisioning takes at most their sum. Default300.request_timeout (float) – HTTP timeout in seconds for a Boat API call that answers at once, such as the create request, a status check or a delete, and the time added to the operation’s own for a call that waits on one: a command’s deadline, or 120 seconds for a file write. Default
30.
- 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.
- read_file(sandbox, path, *, max_bytes)[source]¶
Read a file from the sandbox.
Raise
SandboxFileTooLargeErrorinstead of transferring a file larger thanmax_bytes.