Python SDK and CLI for Flax Cloud: isolated cloud sandboxes.
Project description
flaxcloud - Python SDK & CLI for Flax Cloud
Programmatic access to Flax Cloud isolated sandboxes: create them, run commands, move files, preview servers, and wire them into agents/automation.
Install
pip install flaxcloud
Authenticate
Get an API key from the dashboard, then either set an environment variable or log in with the
CLI (which stores it in ~/.config/flax/config.json):
export FLAX_API_KEY=flax_live_...
# Optional, for local/self-hosted targets:
export FLAX_BASE_URL=https://flaxcloud.com
# or
flax login
Credentials resolve in this order: explicit api_key, CLI --key, FLAX_API_KEY, then
~/.config/flax/config.json. The base URL is base_url, CLI --url, FLAX_BASE_URL, then
https://flaxcloud.com.
SDK
from flaxcloud import FlaxClient
flax = FlaxClient() # reads FLAX_API_KEY and optional FLAX_BASE_URL
# create_sandbox returns a handle with methods; use it as a context manager to auto-destroy
with flax.create_sandbox(template="python", name="ci-run", memory_mb=512) as sb:
print(sb.name, sb.id)
out = sb.run("python3 -c 'print(6*7)'")
print(out.stdout) # "42\n"
sb.upload("/workspace/app.py", "print('hello')\n")
print(sb.run("python3 app.py").stdout)
# long-running server + a shareable preview link
sb.set_startup("python3 -m http.server 8000 --bind 0.0.0.0")
sb.run_startup()
print(sb.create_preview_link(8000).url)
Per-sandbox memory is plan-limited: Free 1 GB, Pro 2 GB, Builder 4 GB, Team 8 GB.
Requesting more than your plan allows raises FlaxQuotaError with code == "memory_limit":
from flaxcloud import FlaxClient, FlaxQuotaError
flax = FlaxClient()
try:
flax.create_sandbox(template="python", memory_mb=2048)
except FlaxQuotaError as exc:
if exc.code == "memory_limit":
print("Choose a smaller sandbox or upgrade your plan.")
else:
raise
Background commands:
sb = flax.create_sandbox(template="node")
job = sb.run("npm install", background=True)
done = sb.wait(job, timeout=600)
print(done.status, done.exit_code)
Environment variables, code execution, git, and filesystem helpers:
sb = flax.create_sandbox(template="python", env={"API_BASE": "https://example.com"})
sb.run("printenv TOKEN", env={"TOKEN": "secret"}) # per-command override
sb.code_run("print(6*7)", language="python") # also node/bash/ruby
sb.git.clone("https://github.com/me/repo.git", "/workspace/repo")
sb.mkdir("/workspace/out"); sb.find("/workspace", name="*.py")
Stateful sessions - working directory and exported env persist across commands:
with sb.create_session() as s: # auto-deletes on exit
s.run("cd /workspace && export TOKEN=abc")
print(s.run("pwd").stdout) # /workspace
print(s.run("echo $TOKEN").stdout) # abc
Streaming - live combined stdout/stderr as the command runs:
stream = sb.run_stream("for i in 1 2 3; do echo $i; sleep 1; done")
for chunk in stream:
print(chunk, end="", flush=True)
print("exit:", stream.exit_code)
Custom images - register any public registry image, then create sandboxes from it:
tpl = flax.create_template("my-python", image="python:3.12-slim") # waits until ready
sb = flax.create_sandbox(template="my-python")
print(sb.run("python3 --version").stdout)
You can also build a custom image from a Dockerfile (flax.create_template(..., dockerfile=...),
streamed with flax.build_logs(id)), or describe it declaratively with FlaxImage and let the SDK
generate the Dockerfile for you. The declarative builder uses the same Dockerfile build flow under
the hood, so build status, logs, and wait behave identically:
from flaxcloud import FlaxImage
image = (
FlaxImage.python("3.12")
.apt_install(["git", "ffmpeg"])
.pip_install(["requests", "beautifulsoup4"])
.env({"PYTHONUNBUFFERED": "1"})
.workdir("/workspace")
)
# Inspect the generated Dockerfile if you want:
print(image.to_dockerfile())
template = flax.create_template_from_image_definition("scraper-agent", image, wait=True)
sb = flax.create_sandbox(template="scraper-agent")
FlaxImage constructors: base(image), python(version), node(version), debian_slim().
Steps (chainable): apt_install, pip_install, npm_install, run, env, workdir,
copy_file, copy_dir. Each package/argument is single-quoted and validated, so version
specifiers like "requests>=2,<3" are safe; use .run(...) for anything custom. Note:
copy_file/copy_dir need a local build context, which the hosted builder does not accept yet, so
templates that use them can't be built remotely for now (use .run(...) to fetch files instead).
Filesystem snapshots - capture a prepared sandbox and create fresh sandboxes from it:
sb = flax.create_sandbox(template="python", env={"READY": "1"})
sb.upload("/workspace/app.py", "print('ready')\n")
snap = sb.create_snapshot("agent-base")
sb.destroy()
restored = flax.create_sandbox(snapshot_id=snap.id)
print(restored.read_text("/workspace/app.py"))
flax.delete_snapshot(snap.id)
Snapshots preserve /workspace and sandbox configuration, not running processes or RAM.
Fork a sandbox - create an independent copy of its filesystem and configuration:
base = flax.create_sandbox(template="python", env={"CASE": "base"})
base.upload("/workspace/input.txt", "baseline")
fork = base.fork(metadata={"branch": "eval-a"})
fork.upload("/workspace/input.txt", "changed in fork")
print(base.read_text("/workspace/input.txt")) # baseline
print(fork.read_text("/workspace/input.txt")) # changed in fork
Forks copy /workspace and sandbox configuration, not running processes, RAM, terminal sessions,
preview links, or command history.
Browser-capable sandboxes:
browser = flax.create_sandbox(capabilities=["browser"])
browser.browser.start()
cdp_url = browser.browser.get_cdp_url()
shot = browser.browser.screenshot_bytes()
Browser sandboxes persist browser artifacts under
/workspace/.flax/browser/{profile,screenshots,downloads,traces}. Browser automation is CDP-first:
connect Playwright, Puppeteer, browser-use, Stagehand, or your own CDP client to the short-lived
authenticated URL from get_cdp_url().
Async client:
import asyncio
from flaxcloud import AsyncFlaxClient
async def main():
async with AsyncFlaxClient() as flax:
async with await flax.create_sandbox(template="python") as sb:
print((await sb.run("echo hi")).stdout)
asyncio.run(main())
Errors are typed (FlaxAuthError, FlaxNotFoundError, FlaxQuotaError, …), all subclasses of
FlaxError. The client retries transient failures, sends a versioned User-Agent, and ships
type hints (py.typed).
CLI
flax login
flax sandbox create --browser
flax browser start sbx_browser
flax browser cdp-url sbx_browser
flax browser screenshot sbx_browser -o shot.png
flax sandbox create --template python --startup "python3 -m http.server 8000 --bind 0.0.0.0"
flax sandbox ls
flax run sbx_abc123 "python3 -c 'print(6*7)'"
flax run sbx_abc123 "make build" --stream # stream output live
flax session create sbx_abc123 # cwd/env persist across exec
flax session exec ses_xyz "cd src && export E=1"
flax cp ./app.py sbx_abc123:/workspace/app.py
flax ls sbx_abc123 /workspace
flax snapshot create sbx_abc123 agent-base
flax snapshot ls
flax snapshot rm snap_abc123
flax preview sbx_abc123 8000
flax sandbox rm sbx_abc123
flax --help lists every command.
Project details
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 flaxcloud-0.5.1.tar.gz.
File metadata
- Download URL: flaxcloud-0.5.1.tar.gz
- Upload date:
- Size: 28.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98892a83a0978590dafcebc2040b7d8f30dc2cafccea62471baccd7314f1f046
|
|
| MD5 |
3bea661115bffdd46e916088cd982aa3
|
|
| BLAKE2b-256 |
d5e19d05e216f5c80300bbed018129062b8280fc55b94f2b9d514b77de9eb021
|
File details
Details for the file flaxcloud-0.5.1-py3-none-any.whl.
File metadata
- Download URL: flaxcloud-0.5.1-py3-none-any.whl
- Upload date:
- Size: 33.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4116469077974fbda18666f38f72a5dcc679a7c3dfed6ee14dfe51ba85d06ef
|
|
| MD5 |
da5dd36b47afe53708a82093b0ec8bb6
|
|
| BLAKE2b-256 |
312bbcdad6a16e9517f45bf8fc49dab6d22db703756228322d1d2c5bc617bbc2
|