Skip to main content
ntro.workflow is the orchestration surface every runbook subclasses. For the concept-level walkthrough of authoring a runbook, see Build runbooks. This page is the API reference.

Install

The [workflow] extra brings in Temporal, all ntro.capabilities.* modules, ntro.events, ntro.accounting, and ntro.data — everything a runbook needs at runtime.

Surface

Runtime backends

runbook and activity dispatch to whichever backend is auto-selected at first attribute access: One INFO log line on first selection so it’s obvious which is active:
To force a specific runtime in tests, call ntro.workflow.set_runtime(...) before importing any runbook module. Otherwise the auto-selection runs once and is cached.

NtroWorkflow

Subclasses get four auto-wired queries / signals at construction: Your subclass doesn’t need to register these — the base class does it. Add domain-specific signals (tb_submitted, document_submitted, …) as needed.

@runbook.step

The decorator wraps the method so step lifecycle (_current_step_id, _steps_completed) tracks automatically. Class-definition order is breadcrumb order in the UI sidebar.

wait_for_action

Block on a HITL signal. The display_hint tells the Tenant UI which review component to render.
Returns UserAction(action, payload, corrections). corrections is workflow-specific (e.g. row-level edits to an extracted document).

await_signal_with_action

Block until a predicate is true. Advertises the pending action via current_pending_action so the UI knows what to surface.
Useful when the workflow waits for an upload, an email arrival, or any human-driven event without a fixed schedule. Pair with a @runbook.signal handler that mutates the predicate’s state.

run_child_workflow

Dispatch another runbook. Children get their own progress tree under the parent’s step.
Cardinality many (fan-out): call run_child_workflow in a loop; awaits join.

WorkflowError

Raised inside an activity to fail the workflow. Replaces the legacy from temporalio.exceptions import ApplicationError import.
Under TemporalRuntime, WorkflowError subclasses temporalio.exceptions.ApplicationError so the ntro-worker’s existing non-retryable interceptor catches it unchanged. Under LocalRuntime it subclasses Exception directly — non_retryable has no effect (there are no retries to suppress) and the exception bubbles up to whoever awaited the activity. For Temporal’s ActivityError wrapping pattern (used in the journal-proposer’s HITL-vs-propagate discrimination), also re-exported:
Under LocalRuntime both alias to WorkflowError so the except (ActivityError, ApplicationError) clause parses — though no exception is actually wrapped in ActivityError under LocalRuntime, the ApplicationError branch picks up WorkflowError directly.

Running locally

ntro.workflow.run_local(cls, arg, *, workflow_id=..., task_queue=...) is the entry helper for python -m runbooks.X-style scripts. Instantiates the runbook, sets up the WorkflowInfo contextvar, and awaits cls().run(arg). See Running locally for the full walkthrough — when LocalRuntime is selected, what works and what doesn’t, and how to force a specific runtime from test fixtures.

Build runbooks (concept)

Worked walkthrough of authoring a runbook from scratch.

ntro.workflow.task

Load context from prior task executions.

ntro.workflow.agents

Invoke a registered external agent from inside a @runbook.step.

Running locally

Run a runbook end-to-end in-process under LocalRuntime — no Temporal cluster, sub-second feedback.

UI and Temporal signals

How Tenant UI actions reach workflows end-to-end.