Sailbox.create. @sail.function
additionally lets Python ship a local function into a Sailbox and run it as if
it were local. See the Images guide for a task-oriented
walkthrough.
Base images
devbox images are the Debian base plus a baked development layer: Node
LTS with npm, build-essential compilers, the OS libraries editor remote
servers need, the claude and codex CLIs, and common developer tools
(jq, gh, fd, fzf, uv, mise, tmux, git-lfs, and more). They
boot fast because the whole layer ships prebuilt, and uv/mise
lazy-install further language toolchains on demand. The trade-off is that
they are prebuilt only: builder methods such as apt_install and
pip_install are rejected on a devbox base. Use a debian base when you
need custom build steps.
In Python, sail.Image.debian_arm64 and debian_amd64 (aliases
debian_arm / debian_amd) pin the image to your local Python version so
@sail.function can deserialize local bytecode.
The image builder
An image definition is an immutable value. Builder methods return a new definition, so you chain them and either pass the result straight toSailbox.create (which builds it for you) or call build() to build
eagerly.
apt_install
apt. Requires at least one
non-empty package name.
pip_install
pip. Requires at least one
non-empty package name.
run_commands
add_local_file
remote_path. Only
the file’s content hash, target path, and mode identify the image, so a
one-byte change forces a rebuild.
| Parameter | Default | Description |
|---|---|---|
local_path | required | Path to the local file. |
remote_path | required | Absolute POSIX destination. A trailing slash appends the local basename. |
mode | None | POSIX permission bits (low 9 bits, max 0o777). Defaults to 0o644. |
add_local_dir
remote_path. Each regular file is
hashed and uploaded; per-file modes come from the local stat. Symlinks are
skipped. ignore takes gitignore-style patterns, or point at an existing
ignore file (such as .gitignore) instead. remote_path must be absolute.
env
build
timeout bounds the whole pipeline (local
file uploads and the build) and must be > 0.
Raises an image-build error if the build fails and a timeout error 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
Python only.Sailbox.exec. The decorator returns a
SailFunction; calling it locally still invokes the original
function unchanged.
SailFunction to exec, the call blocks and returns the
function’s return value directly (not a ExecProcess). The SDK
serializes the function plus its arguments, runs it with the image’s
python3, and returns the deserialized result.
Constraints:
- Function execution is synchronous;
background=Trueis not supported. - The sailbox’s
python3must match your local Python major.minor, because the serialized bytecode is version-sensitive. This is why thedebianbases pin 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.
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.
| Member | Description |
|---|---|
func | The wrapped callable. |
__call__(*args, **kwargs) | Invokes the wrapped function locally. |