This release is a pre-release and may not be stable for production use.
snowflake-sandbox-python
Python SDK and CLI for Snowflake sandboxes running on Snowflake's container substrate.
Spin up gVisor-isolated Linux containers from Python: parallel fan-out, streaming exec, stage I/O, fire-and-forget async jobs, and keep-alive sessions.
Status: alpha. The public surface is feature-flagged behind the
SANDBOX_PUBLIC_API_ENABLEDaccount parameter (default off). APIs may change in0.xminors until the first GA cut.
Install
Python 3.11+. Three ways in, depending on whether you want the CLI alongside your project's dependencies or isolated from them.
uv, in your project:
uv add snowflake-sandbox-python # core SDK
uv add 'snowflake-sandbox-python[cli]' # + the `snow sandbox` CLI plugin
uv run snow plugin enable snow-sandbox # once — see below
uv run snow sandbox --help
pip, in your project:
pip install snowflake-sandbox-python # core SDK
pip install 'snowflake-sandbox-python[cli]' # + the `snow sandbox` CLI plugin
snow plugin enable snow-sandbox # once — see below
snow sandbox --help
CLI only, isolated from your project's dependencies:
uv tool install snowflake-cli --with snowflake-sandbox-python
snow plugin enable snow-sandbox
snow sandbox --help
Note the shape of that last one: snow is the tool and this package is injected into it.
uv tool install 'snowflake-sandbox-python[cli]' fails — this package ships no
executable of its own, so uv reports "No executables are provided by package". pipx is
the same shape: pipx install snowflake-cli, then
pipx inject snowflake-cli snowflake-sandbox-python.
Two things catch people out:
snow plugin enable snow-sandboxis required. Plugins install disabled, so until you run itsnow sandboxis an unknown command. It writes to~/.snowflake/config.toml, which makes it once per machine, not once per project.- The plugin must live in the same environment as the
snowbinary. Enabling it inconfig.tomlwhile the package sits in a different venv still leavessnow sandboxunknown.
snowflake-connector-python is a core dependency, so password / OAuth / PAT connections
work out of the box.
Preview release, gated on the Snowflake side. The SDK is published as PEP 440 pre-releases on two tracks:
.devN(e.g.0.2.1.dev9) on Snowflake's internal index only, andaN/bN/rcN(e.g.0.2.1a1) on public PyPI. Either way a plainpip installresolves to the latest pre-release automatically — no--preflag needed. It talks to a preview API behind theSANDBOX_PUBLIC_API_ENABLEDaccount parameter, which Snowflake enables selectively for specific customers during the preview. You can install and import the SDK on any account, butSandbox.create()calls succeed only once the preview is enabled for your account — contact your Snowflake account team about availability. General availability comes with the first stable (non-pre-release) version.
Hello, sandbox
from snowflake.sandbox import Sandbox
# Prerequisite: a configured Snowflake connection — a ~/.snowflake default
# (snow CLI), SNOWFLAKE_ACCOUNT + SNOWFLAKE_TOKEN env vars, or connection=.
# Without one, Sandbox.create() raises "snowflake.sandbox has no endpoint to talk to". (See below.)
with Sandbox.create() as sb:
result = sb.exec(["python", "-c", "print(40 + 2)"])
print(result.stdout) # "42\n"
Sandbox is blocking. AsyncSandbox is the coroutine twin — same verbs,
awaited — for driving many sandboxes concurrently:
import asyncio
from snowflake.sandbox import AsyncSandbox
async def main() -> None:
async with await AsyncSandbox.create() as sb:
result = await sb.exec(["python", "-c", "print(40 + 2)"])
print(result.stdout)
asyncio.run(main())
Auth via SNOWFLAKE_ACCOUNT + SNOWFLAKE_TOKEN env vars, a named connection in
~/.snowflake/connections.toml / config.toml (resolved by
snowflake-connector-python), or connection=Config(account=..., pat=...) on the call.
With none of those the SDK raises "snowflake.sandbox has no endpoint to talk to: ...",
which names every way to supply one.
HTTP and WebSocket endpoints
Use endpoint(port) for ordinary HTTP or WebSocket applications. The SDK resolves
an owned HTTPS origin and uses the current Snowflake credential for each request or
handshake. Backend ingress converts the traffic into the shared Session gRPC protocol.
from snowflake.sandbox import Sandbox
sb = Sandbox.create(
image="/DB/SCHEMA/REPO/my-app:latest",
command=["python", "/app/server.py"], # Your server listens on port 8080.
connection=connection,
)
with sb.endpoint(8080) as endpoint:
response = endpoint.request("GET", "/api/state")
response.raise_for_status()
print(response.json())
with endpoint.connect_websocket("/events") as socket:
socket.send("hello")
print(socket.recv())
sb.disconnect() # Preserve the running sandbox.
Resolving an endpoint does not start the guest application or wait for readiness. The first request or handshake reports availability; callers decide when to try again.
AsyncSandbox exposes the same methods with await and async with. Use
endpoint.stream(method, path) for incremental HTTP response reads; request() buffers
the body. Both accept headers, content and json. Paths begin with / and remain
within the endpoint's authority. Credential and Host headers are SDK-owned.
Native HTTP and WebSocket clients omit browser Origin headers. Authentication
still uses the current Snowflake credential and TLS verifies the owned authority.
Origin remains reserved and cannot be supplied by callers.
HTTP redirects are returned without being followed; WebSocket redirects are rejected.
TLS verification defaults on, with request/handshake waits bounded by the connection
configuration. Closing an endpoint closes its streams and sockets. Async cancellation
also cancels pending operations. The application owns reconnect and protocol state;
the transport makes one attempt and raises sanitized authentication or transport errors.
CLI
Installs as a snow sandbox plugin:
snow plugin enable snow-sandbox
snow sandbox run --app ./my-agent/agent_app.py # point at the module file
snow sandbox get <sandbox> --wait 600
Project layout
src/snowflake/sandbox/ # SDK — sandboxes, jobs, sessions
cli_sandbox/ # snow sandbox CLI plugin
examples/sandbox/ # Runnable examples
tests/
docs/ # Source for the docs site
Building the docs locally
uv run --extra docs mkdocs serve # live preview at http://127.0.0.1:8000
uv run --extra docs mkdocs build --strict
Contributing
See CONTRIBUTING.md in the source repository for dev setup, how to add new
methods, exceptions, and CLI commands.
Command execution
exec() executes the program and its arguments directly. Ordinary commands such
as exec(["echo", "hello"]) do not require Python in the sandbox image. For shell
builtins, use exec(["sh", "-c", "cd /tmp && pwd"]); for a script without a shebang,
use exec(["sh", "/path/script"]). Arguments are literal, without shell expansion.
python -c retains its historical alias to python3 -c.
This requires a server with command-array support. Python jobs, sessions, and directory helpers still require Python in the image.
Metadata
Release files for snowflake-sandbox-python 0.2.2a6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| snowflake_sandbox_python-0.2.2a6.tar.gz | 469.8 kB | Without provenance | Details for snowflake_sandbox_python-0.2.2a6.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| snowflake_sandbox_python-0.2.2a6-py3-none-any.whl | Python 3 | none | any | Details for snowflake_sandbox_python-0.2.2a6-py3-none-any.whl |
Total release size: 958.7 kB
Release files / snowflake_sandbox_python-0.2.2a6.tar.gz
| Download URL | snowflake_sandbox_python-0.2.2a6.tar.gz |
|---|---|
| Size | 469.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d844480a4cee43ae61547e022672a63b239d12f18fcf8accdab872a2be0944ce
|
|
BLAKE2b-256 checksum How to use checksums |
af1e97e2c9506b63b0804213a4c5b4c6aca4003c43acfd36a91892886d4d1662
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|
Release files / snowflake_sandbox_python-0.2.2a6-py3-none-any.whl
| Download URL | snowflake_sandbox_python-0.2.2a6-py3-none-any.whl |
|---|---|
| Size | 488.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1faece338e8252b1e9854268b145174131ab2a3eb25fa7be700220a422d1f8f8
|
|
BLAKE2b-256 checksum How to use checksums |
371e1dae69ba2f194696a11255055a53bc3ec51dccb94bd88faedfc8beb53ca9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|
Security for snowflake-sandbox-python 0.2.2a6
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.