API reference¶
The public API is small on purpose. Everything you need to write workflows is four callables and one exception; the rest is what you use to observe runs and steps. Rendered from the source.
Core¶
The four core callables live in everystep.api and are re-exported from the
everystep package (lazily, so importing everystep does not import Django). The
blocks below document them at their definition site.
Mark a function as a durable workflow.
The function takes the arguments passed to schedule() and combines
step calls, sequentially or through parallel(). Workflows are
scheduled by name; the return value is the persisted workflow result.
Called outside a running workflow, it runs as a plain function.
Source code in everystep/api.py
Mark a function as a durable step.
Inside a running workflow, the call is recorded: the outcome (result or
exception) is persisted in SQL and served from the store on replay, so
the function body only runs for unrecorded steps. Called outside a
running workflow, it runs as a plain function with no recording. Pass
everystep_id=... at the call site for a stable step identity.
With unsafe_to_repeat=True, the step's side effect must not happen
twice. The engine records the step as started before running it, and if
a replay finds a started step without an outcome — the worker died in
the effect window — it does not re-execute the step: the run ends in
the blocked status until a human resolves it with the
everystep_resolve_step management command.
Source code in everystep/api.py
Run zero-arg callables concurrently; return their results in order.
Each branch is a single step (a @step function or a lambda calling one), or a list of zero-arg callables run in order within the branch; such a sequence branch returns a tuple of its steps' results. If any branch raises, the first error is re-raised (single branch) or an ExceptionGroup is raised (several branches).
Pass everystep_id="..." to give the fork a stable name, so the branch step ids ("name.0.1", "name.1.1") do not shift when steps before it change.
Source code in everystep/api.py
Insert a scheduled workflow into the current transaction.
The workflow becomes claimable by workers once the transaction commits. With an idempotency_key, a concurrent or repeated schedule with the same key returns the existing workflow instead of creating a new one.
Source code in everystep/api.py
Bases: EverystepError
Raised from a step to stop the workflow for a known reason.
The step in flight finishes and is recorded; no new step starts and the
engine will not retry the workflow. It ends in the stopped status with
the reason and payload recorded on it, so the caller can take over (for
example, re-scheduling with a different resource). Not a failure: it is
never reported to Sentry.
Source code in everystep/errors.py
Execution context¶
Execution state for one workflow run, or one branch of one fork.
Steps are identified by a dotpath like "3" or "3.1.2". Unnamed steps
take the next position in their scope; a step called with everystep_id
takes that name as its segment instead, which makes its id stable
against edits elsewhere in the body. Names must be unique within a
scope (one body, or one branch). The shared outcomes dict maps step
ids to {name, status, result, error} outcomes. It is seeded with all
outcomes recorded before the current claim and updated as each step
completes, so inside a step you can read any previously-completed
step's outcome from the current context. Treat it as read-only.
Source code in everystep/context.py
Exceptions¶
Bases: EverystepError
A workflow body diverged from its previously recorded step identities.
Bases: EverystepError
A step marked unsafe to repeat may have performed its effect.
The step's outcome was never recorded (the worker died in the effect
window, or another claimant holds it), so the engine cannot tell whether
the effect happened. It refuses to execute the step again and ends the
run in the blocked status — a holding state, not a failure: it is
never reported to Sentry. The run is resolved by a human with the
everystep_resolve_step management command.
Source code in everystep/errors.py
Bases: EverystepError
A recorded step failure whose original exception type is unavailable.
Bases: EverystepError
Raised from a test fault handler to simulate a process death mid-step.
The runner re-raises it without writing any further state, leaving the workflow exactly as it would be if the worker had died.
Bases: EverystepError
Raised at a step boundary when the runner is draining after a stop signal.
The step in flight at the signal finishes and is recorded; no new step starts. The worker requeues the workflow so any runner can claim it and resume it from the recorded steps.
Source code in everystep/errors.py
Stored exceptions¶
Encode an exception into a JSON-serializable dict for storage.
Source code in everystep/serde.py
Decode a stored exception dict into an exception instance.
Returns the original exception type when it is importable, otherwise a StepFailure carrying the stored message.
Source code in everystep/serde.py
Worker¶
Claim due workflows and execute them on a thread pool.
See the running section of the documentation for the claim loop, the name contract, and the SIGTERM drain behavior.
Source code in everystep/worker.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | |