The blade CLI
blade is the command-line entry point to the platform — *"run Python functions on the GPU fleet"*. It is a grouped command tree: a handful of top-level commands (run, serve, deploy, logs, status, runs, cancel, nodes, setup, shell) plus sub-command groups (token, app, volume, secret, image, sandbox, cron, queue, dict, map). Invoking any group or the bare bladekit with no arguments prints its help.
| Group / command | Purpose |
|---|---|
blade setup | Browser authentication — mint and save an API token. |
blade run <script.py> | Execute a script's @app.local_entrypoint, streaming logs live. |
blade serve <script.py> | Dev loop: run, watch files, hot-reload the bundle. |
blade deploy <script.py> | Create a versioned deployment of an app's endpoints / crons. |
blade logs · status · runs · cancel | Inspect and control individual runs. |
blade nodes | Fleet view — GPUs free/busy per node. |
blade app … | Manage deployed apps: list, history, rollback, stop, scale. |
blade volume … | Network volumes: list, put, get, ls, rm. |
blade secret … | Secrets: set, list, rm. |
blade image … | Image catalogue and DSL builds: list, builds, logs. |
blade sandbox … · blade shell | Sandboxes: list, terminate, and an interactive shell. |
blade cron … · blade queue … · blade dict … · blade map … | Inspect schedules, queues, dicts and map batches. |
blade token … | Manage the saved API token / endpoint (set, show). |
Every command that reaches the control plane resolves credentials the same way: the token and API URL come from ~/.blade/config.toml, overridden by the FABRIC_TOKEN and FABRIC_API_URL environment variables. If no token is configured the command exits with code 2 and prints a hint to run blade token set or set FABRIC_TOKEN. Errors from the control plane are rendered with their machine code and human message (exit 1); usage errors exit 2; a Ctrl-C cancellation exits 130.
blade setup · authentication
blade setup authenticates this machine through the browser and saves an API token — like modal setup. It opens your browser to confirm your identity, mints a token bound to your workspace, and writes it to ~/.blade/config.toml. It long-polls for up to 5 minutes; if the window closes without confirmation it exits with code 1 and asks you to re-run.
blade setup--api-urlstrControl plane base URL to authenticate against. Defaults to the configured value /
FABRIC_API_URL. The confirmed URL is persisted alongside the token.
If a token was minted elsewhere, register it directly with blade token set instead. The token is never accepted as a positional argument — that would leak it into ps aux, shell history and process monitors — so it is read from --from-env or from stdin. blade token show prints the effective token (masked) and endpoint, and where each value came from.
| Command | Description |
|---|---|
blade token set [--from-env VAR] [--api-url URL] | Write the token (and optionally api_url) to ~/.blade/config.toml. --from-env reads the token from the named environment variable; with no flag it is read from stdin. |
blade token show | Show the effective token (masked) and endpoint, each annotated with its source (config file vs. environment). |
blade token set --from-env FABRIC_TOKENecho $TOKEN | blade token setblade run
Execute a script's @app.local_entrypoint and stream its logs live. The entrypoint runs locally; any .remote() / .map() calls it makes are dispatched to the fleet, and this process follows the first opened run's logs until it finishes. On success, hot containers are drained promptly. Ctrl-C cancels the remote run(s); if the node is unreachable the run sits in cancelling and the CLI prints *"cancellation pending on node"*.
blade run train.pyscriptPathPython script defining the app and its
@app.local_entrypoint(positional, required).--no-logsboolDefault:FalseDo not stream logs — just run and report the outcome.
blade serve
The development loop. blade serve runs the entrypoint, watches your files, and hot-reloads the bundle in under ~5 seconds on every save. The run is created with serve=true so its container never drains on idle: edit a file and the bundle is re-pushed (deduplicated by sha256) and the code reloads while the loaded model stays hot. Ctrl-C stops it.
blade serve app.pyscriptPathPython script defining the app (positional, required).
blade deploy
Create a versioned deployment from an app's @app.web_endpoint() / @app.asgi_app() surfaces (and any schedule= cron functions). The script must define exactly one bladekit.app; zero or more than one is an error. Each deploy creates (or reuses) the app, publishes a new immutable deployment version, and prints the app URL and every endpoint's methods, path and kind.
blade deploy api.py --label env=prod --label team=mlscriptPathPython script defining the app (positional, required).
--labelstrDeployment label as
KEY=VALUE, repeatable. An entry without=or with an empty key is rejected with exit code 2.
blade app · manage deployments
Lifecycle commands for deployed apps. Every command accepts either an app name or an app_… id; a name is resolved to its id, raising APP_NOT_FOUND if unknown.
| Command | Description |
|---|---|
blade app list [--state S] [--limit N] | List deployed apps — id, name, state, active deployment, created. --limit defaults to 50 (1–200). |
blade app history <app> [--limit N] | Deployment history for an app — deployment id, version, state, endpoint count, created. --limit defaults to 20 (1–200). |
blade app rollback <app> (--deployment-id ID | --version N) | Repoint the app's active deployment to a previous one. Pass exactly one of --deployment-id or --version (else exit 2). |
blade app stop <app> | Stop an app and drain its active deployment's replicas. |
blade app rollback my-api --version 3blade app scale
Update a deployed endpoint's autoscaling bounds live, with no redeploy — only the flags you pass change, and the autoscaler applies the new bounds within seconds. If the app has one endpoint it is chosen automatically; with several, pass --endpoint. You must pass at least one flag, otherwise the command exits 2 with *"Nothing to change."*
blade app scale my-api --min 2 --max 8 --reserved 2app_name_or_idstrApp name or
app_…id (positional, required).--endpoint, -estrEndpoint name to scale. Defaults to the only endpoint if there is exactly one.
--minintMinimum replicas (0–50).
--maxintMaximum replicas (1–50).
--concurrencyintMax concurrent inputs per replica (1–100).
--idleintScale-down idle seconds (30–3600).
--reservedintHybrid: replicas kept always-on on non-interruptible capacity; the rest burst on the endpoint's class.
--targetintAutoscaling v2: per-replica concurrency the autoscaler aims for (1–100,
<= --concurrency).--bufferintAutoscaling v2: warm spare replicas kept while active (0–10;
0removes the buffer).--vllm-waitingintvLLM preset: target requests waiting in vLLM's queue per replica (1–1000;
0removes it; web-server endpoints only).--clear-policyboolDefault:FalseClear the scaling policy entirely, back to default concurrency autoscaling.
Runs: logs · status · runs · cancel · nodes
Inspect and control runs after they start, and view fleet capacity.
| Command | Description |
|---|---|
blade logs <run_id> [-f/--follow] [--since SEQ] | Show a run's logs. --follow streams live until the run finishes; --since resumes from a seq cursor. The live stream reconnects transparently on transport drops. |
blade status <run_id> | Show a run's state, node, GPU, duration and call progress. If the run is pending, also its 1-based position in the scheduler queue. |
blade runs [--state S ...] [--limit N] | List runs, most recent first. --state filters by state (repeatable); --limit defaults to 50 (1–200). |
blade cancel <run_id> | Cancel a run. If the node is unreachable, prints *"cancellation pending on node"* instead of confirming. |
blade nodes [--state S ...] | Fleet view: GPUs free/busy per node. --state filters by node state (repeatable). |
blade logs run_01hxyz --followblade runs --state pending --state running --limit 100blade volume
Manage network volumes from the shell. Every command accepts a volume name or a vol_… id (an unknown name raises VOLUME_NOT_FOUND). Uploads and downloads use presigned URLs; put creates a new content-addressed generation.
| Command | Description |
|---|---|
blade volume list | List volumes — generation, size and file count. |
blade volume put <volume> <local_path> <remote_path> | Upload a single local file into the volume as a new generation. |
blade volume get <volume> <remote_path> <out> [--generation N] | Download a single file. --generation pins a historical generation instead of the latest. |
blade volume ls <volume> [--path P] [--generation N] | List entries under a path (from the manifest). --path defaults to /. |
blade volume rm <volume> | Delete a volume. Refused with VOLUME_IN_USE if it is mounted by an active run. |
blade volume put weights model.safetensors /ckpt/model.safetensorsblade secret
Manage secrets. Values are read from --from-env or from stdin — never from a positional argument, which would leak them into ps and shell history. list and the delete confirmation only ever show names and env-key names, never values.
| Command | Description |
|---|---|
blade secret set <name> [--from-env KEY ...] | Create or replace a secret. --from-env KEY reads KEY from the environment (repeatable). With no flag, KEY=VALUE lines are read from stdin. |
blade secret list | List secrets — names and env-key names only. |
blade secret rm <name> | Delete a secret (never blocked; pending runs that reference it will fail). |
blade secret set hf --from-env HF_TOKENprintf 'API_KEY=sk-...\nORG=acme\n' | blade secret set openaiblade image
Inspect the image catalogue and your DSL builds. The logs command is where the actionable hint on a failed bladekit.Image build points.
| Command | Description |
|---|---|
blade image list | List the catalogue aliases (maintained images such as fabric/base, fabric/torch, fabric/vllm). |
blade image builds [--limit N] | List recent DSL image builds — state and content hash. --limit defaults to 50 (1–200). |
blade image logs <build_id> [-f/--follow] | Show an image build's logs (ibld_… id). --follow streams live. |
blade image logs ibld_01hxyz --followblade shell · blade sandbox
blade shell opens an interactive shell inside a GPU sandbox — equivalent to Sandbox.create(...) then exec /bin/bash (or a command you pass). It streams stdin/stdout/stderr over the sandbox exec WebSocket and terminates the sandbox on exit. Use -- to separate a command from the flags.
blade shell --gpu RTX-A4500 -- python3 script.py--image, -istrDefault:"fabric/base"Image alias or ref for the sandbox.
--gpu, -gstrGPU type, e.g.
RTX-A4500. Omit for a CPU sandbox.--runtimestrDefault:"runsc"Sandbox runtime:
runsc(gVisor, default) orrunc(trusted-only debug).--timeoutintDefault:3600Sandbox lifetime in seconds.
--block-networkflagDefault:offGive the sandbox no network at all: loopback only, no DNS, no Internet. The shell, file I/O and tunnels still work; anything the code inside reaches for does not.
cmdlist[str]Command to run (positional, after
--). Defaults to/bin/bash.
The blade sandbox group inspects long-lived sandboxes created programmatically: blade sandbox list [--state S] [--limit N] lists them (states creating / running / terminating / terminated / failed; --limit defaults to 50, 1–200), and blade sandbox terminate <sandbox_id> tears one down (SIGTERM → grace → SIGKILL).
blade sandbox terminate sb_01hxyzcron · queue · dict · map
Small inspection groups for the primitives. Cron history is retained on the server; queue and dict commands operate on named distributed stores; map follows batch invocations.
| Command | Description |
|---|---|
blade cron list <app_id> | List an app's cron schedules — id, expression, state. |
blade cron history <cron_id> [--limit N] | Recent executions of a schedule. --limit defaults to 20. |
blade cron trigger <cron_id> | Fire a one-off execution immediately, outside the regular cadence. |
blade queue len <name> | Show the number of items in a distributed queue. |
blade dict get <name> <key> | Get a value from a distributed dict. |
blade dict set <name> <key> <value> | Set a value in a distributed dict — value must be valid JSON. |
blade map status <map_id> | Show a map batch's state, input count and completed count. |
blade map results <map_id> [--cursor C] [--order index|arrival] [--return-exceptions] [--limit N] | Stream a map batch's results (or resume from a cursor). --order defaults to index, --limit to 200. |
blade dict set config timeout 30blade map results map_01hxyz --order arrival --return-exceptionsReference from the Blade console · Updated .