Skip to main content
sail.Image provides the base images you start a Sailbox from and a chainable builder for customizing them. @sail.function lets you ship a local Python function into a Sailbox and run it as if it were local. See the Images guide for a task-oriented walkthrough.

sail.Image

sail.Image is a namespace of base-image properties. Each returns an ImageDefinition you can either pass directly to Sailbox.create or extend with builder methods.
PropertyArchitecturePython pinning
sail.Image.debian_arm64arm64Pins the image to your local Python version.
sail.Image.debian_armarm64Alias of debian_arm64.
sail.Image.builtin_debian_arm64arm64Stable builtin rootfs, no Python-versioned base.
sail.Image.debian_amd64amd64No Python-versioned variant.
sail.Image.debian_amdamd64Alias of debian_amd64.
Prefer debian_arm64 / debian_arm for most workloads: they pin the base image to your local interpreter, so functions shipped with @sail.function (serialized with cloudpickle) run against a matching Python inside the Sailbox. Reach for builtin_debian_arm64 only when you specifically need a base image that does not vary with your local Python version.

ImageDefinition

An ImageDefinition is an immutable image spec. Builder methods return a new ImageDefinition, so you chain them and finish with .build() (or pass the unbuilt definition straight to Sailbox.create, which builds it for you).
image = (
    sail.Image.debian_arm64
    .apt_install("git", "curl")
    .pip_install("httpx")
    .env({"LOG_LEVEL": "info"})
    .build()
)

apt_install

def apt_install(*packages: str) -> ImageDefinition
Adds a step that installs Debian packages with apt. Requires at least one non-empty package name.

pip_install

def pip_install(*packages: str) -> ImageDefinition
Adds a step that installs Python packages with pip. Requires at least one non-empty package name.

run_commands

def run_commands(*cmd: str) -> ImageDefinition
Adds one build step per shell command, in order. Each command must be non-empty.

add_local_file

def add_local_file(
    local_path: str | Path,
    remote_path: str,
    *,
    mode: int | None = None,
) -> ImageDefinition
Bakes the contents of one local file into the image at remote_path. The file is hashed (sha256) and uploaded to the content-addressed asset store; only the hash, target path, and mode flow into the spec, so a one-byte change forces a rebuild.
ParameterDefaultDescription
local_pathrequiredPath to the local file.
remote_pathrequiredAbsolute POSIX destination. A trailing slash appends the local basename.
modeNonePOSIX permission bits (low 9 bits, max 0o777). Defaults to 0o644.
Raises ValueError if the source is missing, the path is invalid, or the file exceeds the 5 GiB single-file limit.

add_local_dir

def add_local_dir(
    local_path: str | Path,
    remote_path: str,
    *,
    ignore: Sequence[str] | Path | str | None = None,
) -> ImageDefinition
Bakes a local directory into the image at remote_path. Each regular file is hashed and uploaded; per-file modes come from the local stat. Symlinks are skipped. ignore accepts gitignore-style patterns (a list) or a path to a file of patterns (e.g. .dockerignore). remote_path must be absolute.

env

def env(env: dict[str, str]) -> ImageDefinition
Sets environment variables baked into the image. Requires at least one non-empty key.

build

def build(*, timeout: int = 1800) -> ImageDefinition
Builds the image and blocks until it is ready, returning a built ImageDefinition (one carrying a resolved image id). timeout must be > 0. Raises sail.ImageBuildError if the build fails, TimeoutError if it does not finish within timeout.
You rarely need to call build() yourself: passing an unbuilt definition to Sailbox.create builds it first (bounded by image_build_timeout).

@sail.function

@sail.function
def fn(...): ...
# or
@sail.function()
def fn(...): ...
Decorates a Python function so it can run inside a Sailbox via Sailbox.exec. The decorator returns a SailFunction; calling it locally still invokes the original function unchanged.
@sail.function
def add(x: int, y: int) -> int:
    return x + y

value = sb.exec(add, 2, 3, timeout=30)
print(value)  # 5
When you pass a SailFunction to exec, the call blocks and returns the function’s return value directly (not a SailboxExecRequest). The SDK serializes the function and its arguments with cloudpickle, runs them with the image’s python3, and returns the deserialized result. Constraints:
  • Function execution is synchronous; background=True is not supported.
  • Currently supported only for sailboxes running custom images.
  • The sailbox’s python3 must match your local Python major.minor (cloudpickle bytecode is version-sensitive), which is why debian_arm64 pins the local version.
  • Imported third-party packages are referenced by name, so they must exist in the sailbox environment.
  • Keep arguments and return values small; write large artifacts from inside the sailbox and return a small reference instead.
Raises sail.SailboxFunctionError (with the remote error_type, traceback, stdout, stderr attached) when the function raises remotely, and sail.SailboxFunctionSerializationError if the payload or result cannot be serialized or the runtime cannot be prepared. See Errors.

SailFunction

The wrapper returned by @sail.function. You normally don’t construct it directly. Calling a SailFunction locally is identical to calling the wrapped function. Async functions, async generators, and generator functions are rejected at decoration time with TypeError.
MemberDescription
funcThe wrapped callable.
__call__(*args, **kwargs)Invokes the wrapped function locally.