Python SDK for the Sail sandbox platform
Project description
sail-sdk
Python SDK for Sail sailboxes.
Install
pip install sail-sdk
uv add sail-sdk
Configure
The SDK reads configuration from environment variables:
export SAIL_API_KEY=sk_...
By default the SDK talks to production:
- API:
https://api.sailresearch.com - Sailbox scheduler:
sailbox-scheduler.sailresearch.com:443
For dev, set:
export SAIL_MODE=dev
You can also override endpoints directly:
export SAIL_API_URL=https://dev.sailresearch.com
export SAIL_SCHEDULER_URL=sailbox-scheduler.dev.sailresearch.com:443
Create A Sailbox
import sail
app = sail.App.find(name="example-app", mint_if_missing=True)
sb = sail.Sailbox.create(
app=app,
image=sail.Image.debian_arm64,
name="sandbox-1",
cpu=1,
memory=512,
)
print(sb.sailbox_id)
print(sb.status)
print(sb.worker_address)
Sailbox.create returns after the VM is running. Supported create arguments are:
app: asail.AppfromApp.findimage: asail.Imagevalue or a built custom imagename: sailbox namecpu: vCPU count, default1memory: memory in MiB, default512ingress_ports: optional list of guest ports to expose
AMD64 image values still exist in the SDK for compatibility, but new sailboxes currently must use arm64 images. The scheduler rejects AMD64 sailbox create and image build requests.
Exec
result = sb.exec("echo hi", timeout=5).wait()
print(result.stdout)
print(result.stderr)
print(result.returncode)
timeout is the command runtime budget in seconds. Omit it to let the command run without an SDK-provided runtime limit.
Background exec starts a detached process and waits only for the launcher shell:
sb.exec("python3 -m http.server 3000", background=True).wait()
Only one exec request may run at a time for a sailbox. If another exec is already active, the SDK raises sail.SailboxExecAlreadyRunningError.
Networking
Expose guest ports when creating the sailbox:
sb = sail.Sailbox.create(
app=app,
image=sail.Image.debian_arm64,
name="sandbox-net",
ingress_ports=[3000],
)
sb.exec("python3 -m http.server 3000", background=True).wait()
listener = sb.listener(3000)
print(listener.url)
print(listener.route_status)
Use listeners() to list every exposed port:
for listener in sb.listeners():
print(listener.port, listener.url, listener.route_status)
Use request() to ask the worker proxy to make an outbound HTTP request on behalf of the sailbox:
req = sb.request(
"POST",
"https://example.com/api",
json={"hello": "world"},
idempotency_key="example-1",
)
completed = req.wait()
print(completed.status)
if completed.response:
print(completed.response.status_code)
print(completed.response.text)
idempotency_key is required for request(). data and json are mutually exclusive.
Lifecycle
sb.checkpoint() # durably checkpoint while keeping the sailbox running
sb.stop() # checkpoint and stop
sb.start() # resume a stopped sailbox
sb.terminate() # permanently terminate
After stop(), exec() raises SailboxExecutionError until start() succeeds.
Custom Images
Start from the arm64 Debian base image, add build steps, then call build():
image = (
sail.Image.debian_arm64.apt_install("git", "curl")
.pip_install("requests")
.run_commands("python3 -m pip show requests >/tmp/requests.txt")
.env({"APP_ENV": "demo"})
)
built_image = image.build(timeout=1800)
sb = sail.Sailbox.create(
app=app,
image=built_image,
name="custom-image-demo",
)
Supported image build helpers:
apt_install(*packages)pip_install(*packages)run_commands(*commands)env(dict[str, str])build(timeout=1800)
Images
Current image properties:
arm64_image = sail.Image.debian_arm64
arm_image = sail.Image.debian_arm
Compatibility aliases still present but currently rejected by the scheduler for sailbox create and image build:
amd64_image = sail.Image.debian_amd64
amd_image = sail.Image.debian_amd
Errors
Common SDK exceptions:
sail.SailboxCreationErrorsail.SailboxExecutionErrorsail.SailboxExecAlreadyRunningErrorsail.SailboxExecRequestNotFoundErrorsail.SailboxTerminatedErrorsail.ImageBuildError
Examples
examples/sailbox_smoke.py: start an arm64 Debian sailbox and run exec commands.examples/sailbox_custom_image.py: build an arm64 custom image withapt_install,pip_install,run_commands, andenv, then launch a sailbox from it.
Publishing
Build a distributable package locally from the repo root:
just python-sdk-build
Publish from a developer machine with a PyPI token:
export UV_PUBLISH_TOKEN=pypi-...
just python-sdk-publish
The repository also includes a GitHub Actions release workflow at .github/workflows/python-sdk-publish.yml.
It publishes when you push a tag like python-sdk-v0.1.0, after verifying that the tag version matches sail.__version__.
Recommended setup:
- Create the
sail-sdkproject on PyPI. - Configure PyPI Trusted Publishing for this GitHub repository and the
python-sdk-publish.ymlworkflow. - Bump
sdk/python/src/sail/__about__.py. - Push a matching tag:
git tag python-sdk-v0.1.0 && git push origin python-sdk-v0.1.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sail_sdk-0.1.2.tar.gz.
File metadata
- Download URL: sail_sdk-0.1.2.tar.gz
- Upload date:
- Size: 29.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7eb69a1ae2df68a34d0b6ca922fb705d1b9fb390450c7d4718d3f1466edee4a
|
|
| MD5 |
096b70b9c22c57f1f9bf0433a8cc1b4d
|
|
| BLAKE2b-256 |
2663c70d1ea8c1bd6d6e67774880476f79cdce2d7a311cf50ac66927b4cecb4e
|
File details
Details for the file sail_sdk-0.1.2-py3-none-any.whl.
File metadata
- Download URL: sail_sdk-0.1.2-py3-none-any.whl
- Upload date:
- Size: 28.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
adfbfb0b139223b1a8a5626dfd27d8268d234fbb7750dbf7e71e02229776a54b
|
|
| MD5 |
636f18a9165d148f40da62c89b3fcaa7
|
|
| BLAKE2b-256 |
855e7d487bd9e1e538a25742709a7955c6f2f236a9e2872f9075b848adaca2db
|