Native runner helpers¶
For authors writing a workflow runner in Python. A runner is one program implementing the steps of one workflow: the manager launches it once per attempt, names the step, and reads exactly one published outcome back. There is no graph language — a step decides at run time what to spawn and what runs next:
#!/usr/bin/env python3
from httk.workflow import Runner
run = Runner("demo.relax")
@run.step
def prepare(a):
a.put("POSCAR", "POSCAR") # stage into the job's data
a.advance("relax")
@run.step
def relax(a):
result = a.run(["vasp-or-mock"], timeout=3600)
if result.returncode:
a.fail("relax_failed", "relaxation failed", retryable=True)
else:
a.succeed()
raise SystemExit(run.main())
job new --workflow ./relax.py publishes and digest-pins it; the same surface
exists in Bash, C, Fortran, Rust, Perl, Ada, C++, and Java (Runner SDKs),
and the normative operation table is Python and Bash authoring parity.
The full guide, Native runner helpers in detail, covers the complete Attempt
surface — parameters, settings, declared environment, state, transactional
data, spawning and gathering children (ChildSpec, join conditions),
outcomes and retry semantics, logging, and a full defect-campaign example.