Skip to main content

OpenEnv on Sprites

CI

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:

  1. Create a fresh authenticated Sprite.
  2. Clone an OpenEnv Space or HTTPS Git repository.
  3. Resolve and record the exact Git commit.
  4. Install pinned uv and run dependency synchronization. A present uv.lock is honored with uv sync --frozen by default.
  5. Register the environment's server entry point as a Sprite HTTP service.
  6. Poll the authenticated health endpoint to keep cold-start traffic active.
  7. Relay OpenEnv WebSockets through a capability-protected loopback bridge.
  8. 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 URLs
  • git+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=False is 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, and sh in the Sprite and installs uv 0.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

openenv_sprites-0.2.0.tar.gz (254.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openenv_sprites-0.2.0-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

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

Hashes for openenv_sprites-0.2.0.tar.gz
Algorithm Hash digest
SHA256 53c3f93692c51d415d4ec688be331e1d4bd89fcfe2d5063125cbfa8ac36cfbe2
MD5 f12d984141c9ebee8df50480973ecdd4
BLAKE2b-256 35ad80058ba14f20c57723f86424f4928fe6ddc06a6401b648663b1e9e7a1976

See more details on using hashes here.

Provenance

The following attestation bundles were made for openenv_sprites-0.2.0.tar.gz:

Publisher: publish.yml on superfly/openenv-sprites

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for openenv_sprites-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2301421c133f24fc6ed9c919c3f38fb9b70d4a5ab1722f90332f48578ee8a94e
MD5 247ffeff0d962facca8b27bb381c46cf
BLAKE2b-256 a87ef89e812a33b1eb0c0333f0eeff3ecdcd2dc7bfd4126d407675b01bd244fc

See more details on using hashes here.

Provenance

The following attestation bundles were made for openenv_sprites-0.2.0-py3-none-any.whl:

Publisher: publish.yml on superfly/openenv-sprites

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page