Writing Your Own Runtime¶
In progress
This guide will expand as the public runtime API stabilizes.
A runtime is a Python file inside your Docker image with one @main function.
The platform imports the file, builds a Context, and calls your function.
from armnet_runtime import Context, main
@main
def run(ctx: Context) -> dict:
ctx.report_progress("starting")
return {"ok": True}
Volumes¶
Use ctx.volume for durable user data such as checkpoints. See
Volumes for the full guide.
checkpoint_dir = ctx.volume.path("openpi/checkpoints/my-checkpoint")
Use ctx.cache_home for best-effort cache data:
print(ctx.cache_home)
HF_HOME is set inside the container to a directory under ctx.cache_home, so
Hugging Face downloads can be reused across runs.
Secrets¶
Secrets requested by the submitter are available as both environment variables
and ctx.secrets. See Secrets for the full guide.
token = ctx.secrets["HF_TOKEN"]
Robot Cell¶
Robot-cell information is available through ctx.cell:
ctx.cell.robot_port
ctx.cell.robot_id
ctx.cell.reset()
ctx.cell.is_complete()
See the Context reference for the complete field list.
Finishing gracefully on timeout¶
A job that exceeds its timeout_seconds is not killed instantly. The cell
first opens a short grace window in which the robot is locked out (further robot
calls fail) but your code can still finalize — save and upload whatever it has
collected — before the container is force-killed. Poll ctx.cell.is_shutting_down()
(or ctx.is_shutting_down()) in your loop and break out to your finalize/upload
path so a run that overruns ends cleanly instead of losing data:
@main
def run(ctx: Context) -> dict:
for episode in range(n_episodes):
if ctx.cell.is_shutting_down():
break # stop early, then finalize below
run_episode(ctx)
dataset.push_to_hub() # always runs, even on an overrun
return {"episodes": episode}
It returns False whenever no cell is attached or the status can't be read, so
it's always safe to call in a control loop.