extro-sim — Python client
Install
# hosted archive (the console serves the packaged client at /package.zip)
pip install https://extropic.dev/package.zip
# or from a checkout of the repo
pip install ./clients/python
Not on PyPI yet — the hosted zip is the install path until pip install extro-sim lands there (the distribution name; it imports as extro_sim).
Do NOT
pip install extropic— the PyPI package by that name is an unrelated squatted package (no client API, no console script). Always install from the repo as above. Post-install smoke check:python -c "import extro_sim; print(extro_sim.DEFAULT_API_URL)"
Defaults are baked for the production deployment (api.extropic.dev); no
configuration needed. Auth is extro-sim auth (browser login, stored session) —
and a job submitted from an interactive terminal without a session triggers the
same flow automatically. Set STAGING=1 to target the staging deployment
(api.staging.extropic.dev) instead.
A first-class Python interface to the Extropic thermodynamic compute cloud.
Decorate a function, then run it on the cloud with .remote() / .submit().
import extro_sim as xtr
xtr.configure(api_url="https://api.extropic.dev", token="<supabase-jwt>")
@xtr.job(tier="cpu", timeout_s=120)
def add(a, b):
return {"sum": a + b}
add(2, 3) # {"sum": 5} — runs locally, like any function
add.local(2, 3) # {"sum": 5} — explicit local run
add.remote(2, 3) # {"sum": 5} — runs on Extropic, blocks for the result
job = add.submit(2, 3) # fire-and-forget, returns a handle
job.state # "running" | "succeeded" | ...
job.result() # blocks, returns {"sum": 5}
job.cancel()
Configuration
xtr.configure(...) or environment variables:
| env | notes | |
|---|---|---|
api_url |
EXTROPIC_API_URL |
default https://api.extropic.dev |
| — | STAGING |
STAGING=1 targets staging (api.staging.extropic.dev) as a set |
token |
EXTROPIC_TOKEN |
Supabase JWT — overrides the extro-sim auth session (CI/staging) |
user_id |
EXTROPIC_USER_ID |
dev identity (local, X-User-Id) |
Hardware
Pass tier= to @xtr.job — labels state the hardware explicitly:
cpu (1 vCPU · 4 GB) · l4 (4 vCPU · 16 GB · 1×L4) · a100 (8 vCPU · 64 GB · 1×A100 80GB) · h100 (8 vCPU · 64 GB · 1×H100)
GPU tiers: JAX must be the CUDA build
A plain pip install thrml (or jax) pulls CPU-only jaxlib — on the GPU
tiers the GPU sits idle and JAX silently runs on cpu:0. Install the CUDA 13
extra explicitly:
pip install "jax[cuda13]" thrml
Avoid jax[cuda12]: on newer GPUs it runs, but cuBLAS < 13.2 has a known
concurrent-kernel TMEM bug (silent data corruption warning at import). Sanity
check inside the job before doing real work:
import jax
assert jax.default_backend() == "gpu", jax.devices()
API contract notes
- Rate limits: submit bursts can 429 — raised as typed
RateLimitedwith.retry_after(seconds). Submits are never retried automatically (a blind retry could double-submit); honorretry_afterwhen fanning out. - Auth expiry: if the stored session can't be refreshed the client raises
extro_sim.auth.AuthExpiredbefore any request — runextro-sim auth login. GET /jobs/{id}/resultcurrently returns the full job record (not a narrow result view);Job.result()handles either shape.DELETE /jobs/{id}means cancellation requested — the response may still showpending/running; poll until terminal (cancelled)./healthzrequires auth by design; there is no anonymous health probe.- output & tracebacks:
stdout,stderrandresultare artifacts — durable objects in the store, synced while the job runs and always flushed before the runner exits (a failed flush errors the job rather than losing bytes).Job.follow()subscribes to all three from the store (chunks a few seconds behind live; ends with the result / raises the terminal error);Job.stream_logs(stream=...)follows one stream and uses the live per-job tunnel (runner_urlon the view) when present for lower latency, artifact polling otherwise. On failure the full Pythontracebackis an artifact and rides in theJobFailedmessage (e.traceback). - status polling never false-fails:
Job.result()/.wait()treat a 429 during polling as retry-after-and-continue, never as a job failure — a rate-limited poll of a healthy running job must not report it dead. - You are never billed before compute starts: a job stays
pending(unbilled, hold only) until its sandbox is actually allocated. If the backend can't provide capacity within the start deadline the job endsat_capacity— retryable, $0 charged.timeout_scounts from when your code's sandbox exists, not from submit.
Errors
.result() raises a typed error for non-success states: JobFailed,
OutOfCredits, AtCapacity (retry later), JobCancelled — all subclasses of
ExtropicError. A 503 on submit also raises AtCapacity.
CLI
Installing the client (from the repo — see Install above) also installs the
extro-sim command — submit · supervise · collect:
submit/runship the file's source into the sandbox — keep the file plain (no top-levelimport extro_sim, no decorator; the base image doesn't have the package). The decorated@xtr.job+.remote()form is the SDK path and never goes throughextro-sim run.
extro-sim auth # log in via the browser (reuses your console session)
extro-sim submit job.py --entrypoint main --tier cpu --arg 2 --arg 3 --wait
extro-sim run job.py --arg 2 --arg 3 # submit + supervise + collect in one shot
extro-sim jobs # list your jobs
extro-sim supervise <id> # stream state/progress until it finishes
extro-sim collect <id> # wait for + print the result
extro-sim logs <id> -f # follow a job's stdout live
extro-sim cancel <id>
extro-sim balance # credit balance + holds
extro-sim recharge 25 # start a top-up (finish the card in the web console)
extro-sim auth opens the web console, which signs you in with Supabase (instantly
if you're already logged in there) and hands the session back to the CLI; it's
stored under ~/.config/extropic/credentials.json and auto-refreshed. auth status
/ auth logout manage it. Point the CLI at your console + API with
EXTROPIC_FRONTEND_URL and EXTROPIC_API_URL (or --api-url); the edge/WAF
secret must be supplied at runtime as EXTROPIC_EDGE_SECRET and is never baked
into the package. --arg/--kwarg values parse as JSON when possible, else as
strings.
Constraints (v1)
Functions ship via cloudpickle: closures, objects, and non-JSON args/results all work. The pickle carries interpreter bytecode, so the sandbox runs a matching Python/cloudpickle (the SDK ships both versions in the job envelope); the function's imports must exist in the sandbox image for its tier.
Metadata
Release files for extro-sim 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| extro_sim-0.4.0.tar.gz | 58.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| extro_sim-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 116.9 kB
Release files / extro_sim-0.4.0.tar.gz
| Download URL | extro_sim-0.4.0.tar.gz |
|---|---|
| Size | 58.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e73e1a2d40f28f420e2f9a9b87d058300df9420b013b789e2439b5c62e584336
|
|
BLAKE2b-256 checksum How to use checksums |
73765b9e2412fdf0c1841e36ee8f1690664334fef70b6020a5cb3b882507f2de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency logRelease files / extro_sim-0.4.0-py3-none-any.whl
| Download URL | extro_sim-0.4.0-py3-none-any.whl |
|---|---|
| Size | 59.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5c0de454833d3eb7d74bcef7ea24a116c1f32950f7f18ed9757b1c5f33dfb251
|
|
BLAKE2b-256 checksum How to use checksums |
9ccf1df2da5801b39aaa38d9ce657ca62b2651dfa86d309a712224b002cacded
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency log