OpenEnv on Sprites
openenv-sprites is an experimental OpenEnv ContainerProvider backed by
Fly.io Sprites. It provides a fresh, private Sprite for
each environment lifecycle; it does not maintain an idle pool and does not
depend on Sprite forking or cross-Sprite checkpoint restore.
[!IMPORTANT] This project is an alpha integration under active development. Its API and operational behavior may change between minor releases.
The provider has been exercised with the OpenEnv Echo and Coding environments, including two concurrent Coding lifecycles. In that run both environments preserved their own session state, remained isolated, and were deleted after use. The slower of the two cold environments reached readiness in 34.6 seconds; Sprite creation itself took about 0.25 seconds, while source/dependency setup dominated startup.
Lifecycle
Each provider instance owns at most one Sprite:
- Create a fresh authenticated Sprite.
- Clone an OpenEnv Space or HTTPS Git repository.
- Resolve and record the exact Git commit.
- Install pinned
uvand run dependency synchronization. A presentuv.lockis honored withuv sync --frozenby default. - Register the environment's
serverentry point as a Sprite HTTP service. - Poll the authenticated health endpoint to keep cold-start traffic active.
- Relay OpenEnv WebSockets through a capability-protected loopback bridge.
- Delete the Sprite with bounded retries when the client closes.
Allocation and preparation are separate internal boundaries. Today allocation returns a blank Sprite that requires preparation. A future implementation can return a prepared fork without changing the OpenEnv-facing lifecycle.
Install and run
Install from PyPI with uv:
uv add openenv-sprites
Or with pip:
pip install openenv-sprites
Then add or inject the client package for the desired environment, for example:
uv add "openenv-echo-env @ git+https://huggingface.co/spaces/openenv/echo_env"
Published environment packages currently span several OpenEnv core versions. The explicit lifecycle works across those versions:
from echo_env import EchoEnv
from openenv_sprites import SpritesProvider
provider = SpritesProvider(source="hf://openenv/echo_env")
with provider:
base_url = provider.start_container()
provider.wait_for_ready(base_url)
with EchoEnv(base_url=base_url).sync() as env:
result = env.reset()
With a current OpenEnv client, the native provider-owned async lifecycle is:
from echo_env import EchoEnv
from openenv_sprites import SpritesProvider
provider = SpritesProvider()
env = await EchoEnv.from_docker_image(
"hf://openenv/echo_env",
provider=provider,
)
async with env:
result = await env.reset()
The image parameter is provider-specific here. Accepted source identifiers
are:
hf://<owner>/<space>[@revision]https://...Git URLsgit+https://...Git URLs
Credential-bearing Git URLs, query strings, and fragments are rejected to keep secrets out of commands and diagnostics. Arbitrary OCI images are not supported.
Authentication
Set SPRITES_API_TOKEN or pass token=. The legacy SPRITE_TOKEN environment
variable is accepted as a fallback. For deployed use, prefer a restricted
Sprites token whose policy constrains all of the following:
- name prefix
openenv-; - required label
openenv; - an appropriate total Sprite limit; and
- an expiration time.
The token remains in the client process. It is never copied into the Sprite or
returned in diagnostics. The local WebSocket URL includes a random, per-provider
capability path, binds only to 127.0.0.1, and injects the bearer token only on
the upstream connection. The Python SDK does not yet expose mint/revoke methods
for restricted tokens, so token provisioning remains the caller's responsibility.
Environment source and its dependencies execute inside the Sprite. Only run
sources you trust, and assume they can read every value supplied through
env_vars. Do not put credentials in source URLs or command arguments. See
the security policy for private vulnerability reporting.
Configuration
The common constructor options are:
| Option | Default | Purpose |
|---|---|---|
source |
none | Source used when start_container(image=...) omits image. |
revision |
none | Git branch, tag, or commit to fetch. |
sprite_name_prefix |
openenv |
Prefix for generated names and restricted-token policies. |
labels |
("openenv",) |
Labels applied at Sprite creation. |
sprite_config |
API default | Sprites CPU, RAM, region, and storage configuration. |
sprite_runtime |
API default | default or dev Sprite runtime. |
url_settings |
API default | Sprite URL authentication settings. |
server_command |
uv run server ... |
Service command with template placeholders. |
dependency_command |
uv sync |
Dependency setup command. |
frozen_dependencies |
True |
Add --frozen when the default sync finds uv.lock. |
health_path |
/health |
Authenticated readiness endpoint. |
bridge_max_message_size_mb |
100 |
Maximum WebSocket message size in both directions. |
delete_attempts |
4 |
Maximum idempotent cleanup attempts. |
delete_on_stop |
True |
Set false only when retaining a Sprite for debugging. |
Commands are executed directly as argument arrays, not through a shell. Command
templates may use {uv_bin}, {project_dir}, {port}, and {workers}. A
per-start cmd= override accepts either a shell-like string parsed with
shlex.split or a sequence of arguments. workers greater than one requires an
explicit {workers} placeholder.
Clone, installer, dependency, bridge, and readiness timeouts are separately
configurable; cleanup has bounded retry and backoff controls. provider.timings
and provider.diagnostics return defensive copies and never intentionally
contain supplied credentials or environment-variable values. Health response
bodies are excluded unless
include_health_body_in_diagnostics=True is explicitly selected.
Examples
uv run --with "openenv-echo-env @ git+https://huggingface.co/spaces/openenv/echo_env" \
python examples/run_echo.py
uv run --with "openenv-coding-env @ git+https://huggingface.co/spaces/openenv/coding_env" \
python examples/run_coding.py
The concurrent fresh-lifecycle harness creates and deletes exactly two new Sprites per round:
uv run --with "openenv-coding-env @ git+https://huggingface.co/spaces/openenv/coding_env" \
python examples/run_fresh_lifecycle.py --rounds 1
All commands require SPRITES_API_TOKEN in the environment.
Current boundaries
- Startup installs each environment from public source and is intentionally not optimized with retained Sprites or a pool.
delete_on_stop=Falseis debugging-only; retained Sprites are not reset or reused.- The bridge proxies only OpenEnv's WebSocket endpoint. Health checks go directly to the authenticated Sprite URL.
- The default bootstrap requires
git,curl, andshin the Sprite and installsuv0.12.6 under/opt/openenv/bin. - Private Git authentication, OCI/Compose semantics, GPUs, attached devices, egress policy, and workload-specific setup are not inferred automatically.
See Hardening and upstream work for the production threat
model, operational behavior, and the remaining sprites-api, sprites-py, and
future-fork integration work.
Contributing
Bug reports and pull requests are welcome. See CONTRIBUTING.md for development, verification, and release instructions. Please report security issues according to SECURITY.md, not in a public issue. Participation is governed by our Code of Conduct.
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 openenv_sprites-0.2.0.tar.gz.
File metadata
- Download URL: openenv_sprites-0.2.0.tar.gz
- Upload date:
- Size: 254.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53c3f93692c51d415d4ec688be331e1d4bd89fcfe2d5063125cbfa8ac36cfbe2
|
|
| MD5 |
f12d984141c9ebee8df50480973ecdd4
|
|
| BLAKE2b-256 |
35ad80058ba14f20c57723f86424f4928fe6ddc06a6401b648663b1e9e7a1976
|
Provenance
The following attestation bundles were made for openenv_sprites-0.2.0.tar.gz:
Publisher:
publish.yml on superfly/openenv-sprites
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openenv_sprites-0.2.0.tar.gz -
Subject digest:
53c3f93692c51d415d4ec688be331e1d4bd89fcfe2d5063125cbfa8ac36cfbe2 - Sigstore transparency entry: 2627135055
- Sigstore integration time:
-
Permalink:
superfly/openenv-sprites@ab24a004a4c978810c0920fc50ea0cde59d18887 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/superfly
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ab24a004a4c978810c0920fc50ea0cde59d18887 -
Trigger Event:
push
-
Statement type:
File details
Details for the file openenv_sprites-0.2.0-py3-none-any.whl.
File metadata
- Download URL: openenv_sprites-0.2.0-py3-none-any.whl
- Upload date:
- Size: 19.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2301421c133f24fc6ed9c919c3f38fb9b70d4a5ab1722f90332f48578ee8a94e
|
|
| MD5 |
247ffeff0d962facca8b27bb381c46cf
|
|
| BLAKE2b-256 |
a87ef89e812a33b1eb0c0333f0eeff3ecdcd2dc7bfd4126d407675b01bd244fc
|
Provenance
The following attestation bundles were made for openenv_sprites-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on superfly/openenv-sprites
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openenv_sprites-0.2.0-py3-none-any.whl -
Subject digest:
2301421c133f24fc6ed9c919c3f38fb9b70d4a5ab1722f90332f48578ee8a94e - Sigstore transparency entry: 2627135059
- Sigstore integration time:
-
Permalink:
superfly/openenv-sprites@ab24a004a4c978810c0920fc50ea0cde59d18887 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/superfly
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ab24a004a4c978810c0920fc50ea0cde59d18887 -
Trigger Event:
push
-
Statement type: