Reading previous step results¶
A step can read the result of any step that has already completed in the current run — on a fresh pass and on a replay — through the current execution context:
from everystep import context, step
@step
def create_vm(name, size):
return cloud_api.create_vm(name=name, size=size)
@step
def tag_vm():
vm_id = context.current().outcomes["create-vm"]["result"]
cloud_api.tag(vm_id, "provisioned")
return None
@workflow
def provision_vm(args):
create_vm(args["name"], args["size"], everystep_id="create-vm")
tag_vm()
return None
The outcome store¶
context.current().outcomes maps each step id to a dict:
{
"name": "provision.create_vm", # qualified function name
"status": "done", # "done" or "failed"
"result": {...}, # None when the step failed
"error": None, # encoded exception when it failed
}
The store is kept current by the engine: it is seeded with everything recorded before the current claim, and each step's outcome is added as soon as it is recorded. So a step sees every step that completed before it starts, including steps recorded earlier in the same pass, and it sees the same thing on a replay.
Rules:
- A step never sees its own result — that is only recorded after the step returns.
- Steps are keyed by step id: a named step by its
everystep_id(e.g."create-vm"), an unnamed step by its positional dotpath ("1","2", ...). Name the steps you read, so the lookup is stable across code edits. - Within a
parallel, sibling branches run concurrently: do not read a sibling's outcome. Completion order is not guaranteed, and a branch's step is keyed by its full dotpath (e.g."fanout.0.attach-ip"). Read sibling values fromparallel's return tuple. Steps from an earlierparallelor from earlier sequential steps are safe to read. - Within a sequence branch, steps run in order, so a later step can read an earlier step's outcome from the same branch.
- Treat
.outcomesas read-only; the engine maintains it.
Where it helps¶
- A step that needs another step's output without it being threaded through the workflow body's local variables.
- A step that wants to branch on how a previous step ended: check
.outcomes[step_id]["status"]and read the encodederrorif it failed. - Building up state across a long pipeline without carrying it as arguments.