bioimageflow¶
The orchestrator package. Main process only. Depends on pandas and pydantic.
Workflow¶
Workflow container and progress events.
- class bioimageflow.workflow.WorkflowInputRef[source]¶
Bases:
objectSymbolic reference to a public input owned by one workflow.
- class bioimageflow.workflow.WorkflowInputPort[source]¶
Bases:
objectCanonical definition of one workflow input port.
- __init__(id, name, kind, annotation=None, schema=None, default=<bioimageflow.workflow._Missing object>, targets=<factory>)¶
- class bioimageflow.workflow.WorkflowOutputPort[source]¶
Bases:
objectCanonical definition of one workflow output port.
- class bioimageflow.workflow.WorkflowEnvironment[source]¶
Bases:
objectMutable launch configuration for a Wetlands environment.
-
spec:
EnvironmentSpec|None= None¶
-
spec:
- class bioimageflow.workflow.ProgressEvent[source]¶
Bases:
objectProgress event reported by the engine.
- __init__(node_name, status, row=0, total_rows=0, message=None, current=None, maximum=None, timestamp=0.0, result_key=None, record_id=None)¶
- class bioimageflow.workflow.OutputView[source]¶
Bases:
objectHuman-facing output materialization policy.
- class bioimageflow.workflow.InvalidatedSelection[source]¶
Bases:
objectA cache selection removed by
Workflow.invalidate().
- class bioimageflow.workflow.Workflow[source]¶
Bases:
objectHolds the DAG and provides configuration for execution.
- MISSING = <bioimageflow.workflow._Missing object>¶
- __init__(storage_path='./bif_data', *, name='workflow', display_name=None, engine='wetlands', execution='parallel', on_progress=None, wetlands_config=None, max_workers=1, output_view=None)[source]¶
- input(name, annotation=None, *, kind='field', default=<bioimageflow.workflow._Missing object>, id=None)[source]¶
Declare and return a symbolic public workflow input.
- expose_input(node, target, *, name, annotation=None, kind='field', default=<bioimageflow.workflow._Missing object>, id=None)[source]¶
Publish an existing node target through the canonical interface.
- topological_order()[source]¶
Return node names in dependency order. Raises on cycle.
Thin wrapper over
bioimageflow.engine.topological_order(). If the graph may contain a cycle, callvalidate()first.
- invalidate(node_ids, *, cascade=True)[source]¶
Remove cache selections for the given nodes.
Returns the selections whose
current.jsonpointers were removed.cascade=True(the default) also removes selections for every node transitively downstream of each input node, so a subsequent run recomputes or reselects everything that depended on the changed node. Immutablerecords/<record-id>/directories are retained.KeyErroris raised if any name innode_idsis not registered with this workflow — matching the existing behavior ofdownstream_of().- Return type:
- Parameters:
Concurrency¶
This method is not safe to call concurrently with
compute()on the same workflow. The library does not currently expose a public lock primitive; callers that need to invalidate while a compute is in flight must coordinate externally (e.g., cancel + join + invalidate).
- downstream_of(node_name)[source]¶
Return node names transitively downstream of
node_name.Excludes
node_nameitself. Useful for callers (GUIs, external schedulers) that need to mark dependents as cache-invalidated after a parameter change.
- plan(*, dev_mode=False)[source]¶
Return a per-node cache-status plan.
Instantiates a non-Wetlands
DefaultEngineand calls itsplan(). No tool code runs.
- create_engine(*, environment_lifetime='execution', env_manager=None)[source]¶
Create an engine preserving this workflow’s execution configuration.
environment_lifetimecontrols whether Wetlands workers stop after each execution ("execution"), remain warm untilengine.close()("engine"), or are owned entirely by the caller ("external"). An existing manager can be injected so multiple workflows and engines share the same worker environments.- Return type:
- Parameters:
environment_lifetime (EnvironmentLifetime | str)
env_manager (WetlandsEnvManager | None)
- validate(*, dev_mode=False, _recursion_stack=())[source]¶
Return all domain-level problems in this workflow.
Runs, in order:
Cycle detection (one error per cycle).
Type compatibility on every column binding.
Missing-required-input check for every node.
Pydantic validation of every node’s supplied constants.
Recursive validation of workflow invocations (
pathis prefixed with the parent’s node name).
Steps 1–3 are already enforced by
Node.__init__during construction; this method exists so GUIs that built the workflow viacapture_errors()/from_dict()can re-check after the fact. Step 4 (constant Pydantic validation) only runs here — it is intentionally not performed at construction time, so a GUI editing one field at a time does not need every other field to be valid yet.
- capture_errors()[source]¶
Capture node-construction errors as
ValidationError.Usage:
wf = Workflow() with wf, wf.capture_errors() as errors: MyTool()(input=upstream["bad_col"]) # errors: list[ValidationError]
Nested blocks push their own list; the outer list is restored on exit. Disables the “raise on first error” behavior of
Nodeconstruction only for the duration of the block.
- property errors: list[ValidationError]¶
Build-time errors accumulated during
from_dict().Empty when the workflow was constructed programmatically (via the context-manager / call-tools pattern) or when
from_dictwas called in strict mode.
- property failed_nodes: dict[str, ValidationError]¶
Map of node name →
ValidationErrorfor nodes that failed to construct duringfrom_dict().Populated only when
from_dictis called withpartial=Trueand a node’s tool resolution or construction raised. Empty otherwise.
- property is_partial: bool¶
Whether the workflow is missing nodes that the input dict described.
Truewhen at least one entry in the sourcedata["nodes"]is absent fromnodes(typically because it failed to construct in collect mode).Falsefor fully-built workflows and for workflows constructed withoutfrom_dict().
- get_environment(target)[source]¶
Get the launch configuration proxy for an environment.
- Parameters:
target (
ProcessingTool|EnvironmentSpec|str) – A ProcessingTool instance, an EnvironmentSpec, or an env name string.- Return type:
- Returns:
A shared WorkflowEnvironment proxy. Multiple calls with tools sharing the same environment return the same object.
- compute(*targets, inputs=None, dev_mode=False, engine=None)[source]¶
Execute the workflow and return results.
- Parameters:
- Return type:
- compute_steps(*targets, inputs=None, dev_mode=False, engine=None)[source]¶
Execute the workflow step by step, yielding a
NodeStepfor each node in topological (dependency) order.- Parameters:
- Return type:
The engine stays alive between yields so Wetlands environments remain warm — ideal for interactive debugging.
Usage:
for step in wf.compute_steps(results): print(f"Next: {step.node_name}") step.prepare() # optional: launches env — attach debugger here df = step.execute() print(df.head())
If
step.execute()is not called before advancing to the next iteration, the step auto-executes to keep downstream nodes consistent.
- export_outputs(*, mode='symlink', scope='latest', run_id=None)[source]¶
Materialize human-facing output files from the portable JSON views.
- to_dict(*, include_custom_tools=False)[source]¶
Serialize the strict recursive schema-version-1 graph.
- classmethod load(path)[source]¶
Deserialize a workflow from a JSON file.
Thin wrapper around
from_dict(). Preserves the original behavior: raises on the first error, auto-installs missing versioned packages.
- classmethod from_python(path_or_module)[source]¶
Execute a trusted module’s exact
build_workflowfactory once.
- classmethod import_archive(path, destination)[source]¶
Extract a BioImageFlow zip archive to
destinationand load it.
- classmethod from_dict(data, *, validate_only=False, partial=False, auto_install=True, storage_path_override=None, on_progress=None, engine=None, execution=None, wetlands_config=None)[source]¶
Reconstruct a Workflow from a serialized dict.
- Parameters:
data (
dict[str,Any]) – A schema-version-1 recursive graph produced byto_dict(), or a portable archive envelope produced byexport().validate_only (
bool) – Drives the return type. WhenTrue, returns a(workflow, errors)tuple; the workflow may be partial. WhenFalse(default), returns theWorkflowdirectly and aggregates any captured errors into a raised exception.partial (
bool) – Drives error suppression / continuation. WhenTrue, per-node failures are captured asValidationErrorentries and construction continues; the workflow may be best-effort partially wired. WhenFalse(default), construction stops at the first failure.auto_install (
bool) – When True (default), missing versioned packages are installed automatically. When False, missing packages produce anunknown_toolerror (when captured) or raise.storage_path_override (
Union[str,Path,None]) – Overridedata["config"]["storage_path"]without mutating the dict. Useful for GUIs that validate a graph against a specific cache path.on_progress (
Optional[Callable[[ProgressEvent],None]]) – Passed toWorkflow.Nonemeans “use the values fromdata['config'](or defaults)”.engine (
Optional[str]) – Passed toWorkflow.Nonemeans “use the values fromdata['config'](or defaults)”.execution (
Optional[str]) – Passed toWorkflow.Nonemeans “use the values fromdata['config'](or defaults)”.wetlands_config (
Optional[dict[str,Any]]) – Passed toWorkflow.Nonemeans “use the values fromdata['config'](or defaults)”.
- Return type:
Notes
The
partial=False, validate_only=Truecombination returns a(workflow, errors)tuple whereerrorscontains at most one entry (the first failure) and the workflow may be empty — useful as a fail-fast diagnostic.
Node¶
Node and ColumnRef — graph construction primitives.
- exception bioimageflow.node.ColumnNotFoundError[source]¶
Bases:
ExceptionRaised when a column reference targets a non-existent column.
- exception bioimageflow.node.BindingError[source]¶
Bases:
ExceptionRaised when a required input field has no source.
- exception bioimageflow.node.IndexAlignmentError[source]¶
Bases:
ExceptionRaised when upstream indices are incompatible.
- exception bioimageflow.node.SourceToolUpstreamError[source]¶
Bases:
ExceptionRaised when a source DataFrameTool (
accepts_upstream = False) is constructed with positional upstream arguments.
- class bioimageflow.node.ColumnRef[source]¶
Bases:
objectReferences a specific column from a specific upstream node.
- bioimageflow.node.scoped_node_names(names)[source]¶
Expose immutable execution paths without changing structural names.
- class bioimageflow.node.Node[source]¶
Bases:
objectA node in the computation DAG. Wraps a tool and its configuration.
- get_output_schema()[source]¶
Resolve this node’s output column schema as currently configured.
Algorithm: :rtype:
dict[str,dict[str,Any]] |NoneDataFrameToolwith aresolve_merge_schemaoverride (built-in merge tools): collect upstream schemas via each positional arg’sget_output_schema()and calltool.resolve_merge_schema(upstream_schemas, kwargs).DataFrameTool(or subclass) withresolve_outputs→tool.resolve_outputs(kwargs).ProcessingTool→ staticserialize_output_schema(type(tool)).
Returns
Nonewhen the schema is unresolvable (any required upstream returnsNone, or the tool has noOutputsand no override). Idempotent and side-effect free.
Engine¶
Execution engines for BioImageFlow workflows.
- class bioimageflow.engine.EnvironmentLifetime[source]¶
-
Ownership policy for Wetlands environments used by an engine.
EXECUTIONpreserves the historical behavior and stops environments after everyDefaultEngine.execute()orDefaultEngine.execute_steps()call.ENGINEretains them untilDefaultEngine.close().EXTERNALleaves cleanup entirely to the owner of the injected environment manager.- EXECUTION = 'execution'¶
- ENGINE = 'engine'¶
- EXTERNAL = 'external'¶
- __new__(value)¶
- bioimageflow.engine.topological_order(workflow)[source]¶
Return the names of the nodes in
workflowin dependency order.Uses
graphlib.TopologicalSorterover all registered nodes. RaisesCycleErrorif the graph contains a cycle; callers that want to tolerate cycles should catch that or useWorkflow.validate().
- bioimageflow.engine.source_processing_signature_material(node)[source]¶
Return the cache-signature material for source ProcessingTool nodes.
- exception bioimageflow.engine.DisabledNodeError[source]¶
Bases:
ExceptionRaised when all requested target nodes are disabled or unreachable.
- exception bioimageflow.engine.WorkflowCancelledError[source]¶
Bases:
ExceptionRaised when a workflow execution is cancelled via
Workflow.cancel().
- exception bioimageflow.engine.CycleInWorkflowError[source]¶
Bases:
ValueErrorRaised by
DefaultEngine.plan()/Workflow.plan()when the graph contains a cycle.Use
Workflow.validate()for non-fatal cycle reporting (it returns aValidationErrorwithkind="cycle"instead of raising).
- class bioimageflow.engine.NodePlanStatus[source]¶
-
Per-node status returned alongside
NodePlan.Use this enum (or its string values) instead of inspecting the cache directory layout — the platform should not need to know how the library stores cached node results.
Values¶
- CACHED
The node result key has a valid selected current record;
compute()would short-circuit.- PRIOR_SELECTION_MISS
The planned result key has no selected current record, but the same node has another selected current record from prior result-key material.
compute()would re-execute and publish or select a record.- UNEXECUTED
No known cache record exists for this node.
- SKIPPED
The node is disabled, or has a disabled upstream that prevents execution.
final_result_keyandselected_record_idareNone.- PENDING_UPSTREAM
At least one upstream selected record is not known yet, so the node’s final result key cannot be determined from a stable record graph snapshot.
- CACHED = 'cached'¶
- PRIOR_SELECTION_MISS = 'prior_selection_miss'¶
- UNEXECUTED = 'unexecuted'¶
- SKIPPED = 'skipped'¶
- PENDING_UPSTREAM = 'pending_upstream'¶
- __new__(value)¶
- class bioimageflow.engine.NodePlan[source]¶
Bases:
objectA single node’s pre-execution plan entry, returned by
DefaultEngine.plan().- Variables:
node_name – Scoped node name (
"workflow-node/internal"for nested workflow internals, plain name otherwise).final_result_key – V1 result key for this node when it can be computed from known selected upstream records;
Nonefor skipped and pending nodes.selected_record_id – Currently selected record ID for
final_result_keywhen the node is cached; otherwiseNone.status – Per-node
NodePlanStatus— the canonical signal for external callers wanting to display “cached / prior selection miss / unexecuted / skipped” in a GUI.upstream – Scoped names of this node’s direct upstreams.
pending_upstreams – Upstream node names whose selected records are not known yet.
logical_signature – Diagnostic logical signature computed by the same helpers as execution. It is not the public cache identity field.
accessors (cached and skipped are read-only convenience)
CACHED, (derived from status (cached == status is)
SKIPPED). (skipped == status is)
-
status:
NodePlanStatus¶
- __init__(node_name, logical_signature, status, upstream, final_result_key=None, selected_record_id=None, pending_upstreams=())¶
- exception bioimageflow.engine.WorkerTimeoutError[source]¶
Bases:
RuntimeErrorRaised when the engine-side safety timeout fires on a Wetlands task.
This is a last-resort timeout that wraps
task.wait_for()in_dispatch_via_wetlands. It only fires when the Wetlands-side health monitor fails to catch a dead or hung worker withinworker_timeout * 1.5(orworker_timeout + 60, whichever is larger).
- exception bioimageflow.engine.WorkerTaskError[source]¶
Bases:
RuntimeErrorRaised when a Wetlands worker task fails while executing a node.
- class bioimageflow.engine.NodeStep[source]¶
Bases:
objectHandle for a single node in a stepped workflow execution.
Yielded by
DefaultEngine.execute_steps(). The caller may optionally callprepare()(to warm up the Wetlands environment before execution — useful for attaching a debugger) and must callexecute()to run the node (or it will auto-execute when the generator advances to the next step).- property cached: bool¶
True if the node’s result is already in the cache.
The first access triggers logical-signature computation and cache lookup; subsequent accesses reuse the result.
- prepare()[source]¶
Launch the tool’s Wetlands environment (ProcessingTool only).
No-op for DataFrameTools, when Wetlands is disabled, or when the node’s result is already cached (no environment needed). After this call the environment is running and a debugger can be attached to it before
execute()triggers the actual computation.- Return type:
- execute()[source]¶
Execute the node and return its output DataFrame.
Idempotent — calling more than once returns the cached result. If the cache was already checked (via
cachedorprepare()) and a hit was found, returns it directly without re-entering the engine. RaisesDisabledNodeErrorif the node is skipped.- Return type:
DataFrame
- class bioimageflow.engine.DefaultEngine[source]¶
Bases:
objectExecutes workflow nodes with optional parallelism.
When
_force_sequentialis False (default), independent DAG branches can execute concurrently and intra-node rows can run in parallel across Wetlands workers. When True (set bySequentialEngine), execution is strictly sequential — useful for debugging and deterministic reproduction.The non-Wetlands
_dispatch_direct()path is a testing/development fallback and does not support sub-row progress reporting (Feature 3) or cooperative cancellation (Feature 4).- __init__(use_wetlands=False, wetlands_config=None, force_sequential=False, env_manager=None, environment_lifetime=EnvironmentLifetime.EXECUTION)[source]¶
- Parameters:
use_wetlands (bool)
force_sequential (bool)
env_manager (WetlandsEnvManager | None)
environment_lifetime (EnvironmentLifetime | str)
- Return type:
None
- property environment_lifetime: EnvironmentLifetime¶
Return the engine’s Wetlands environment ownership policy.
- property environment_manager: WetlandsEnvManager | None¶
Return the Wetlands manager used by this engine, if any.
- close()[source]¶
Close the engine and stop environments it owns.
The method is idempotent. Externally owned managers are never shut down; their owner must call
WetlandsEnvManager.shutdown_all().- Return type:
- execute_steps(targets, workflow)[source]¶
Yield a
NodeStepfor each node in topological order.The engine (and any Wetlands environments) stays alive between yields. The caller controls execution via
step.prepare()/step.execute(). Ifexecute()is not called before advancing, the step auto-executes to keep the results chain consistent for downstream nodes.WorkflowNodes are expanded: their internal nodes are yielded individually with scoped names (
workflow_node/internal_name).Cleanup runs when the generator is exhausted or closed (early
break).
- plan(workflow)[source]¶
Return the cache status and diagnostic plan state of every node.
Walks the graph in topological order, computes diagnostic logical signatures with the same helpers as
execute(), and reports result-key/current-record state when enough upstream cache selections are known. No tool code runs, and no Wetlands environment is launched.Nested workflow tools appear under scoped names (
"workflow_node/internal_name"), matchingexecute_steps().Disabled nodes and nodes downstream of disabled nodes are returned with
skipped=Trueand no final result key.- Raises:
CycleInWorkflowError – If the graph contains a cycle. Use
Workflow.validate()for non-fatal cycle reporting.- Return type:
- Parameters:
workflow (Any)
- class bioimageflow.engine.SequentialEngine[source]¶
Bases:
DefaultEngineForces sequential execution — useful for debugging and deterministic reproduction.
Inherits from
DefaultEnginebut forces_force_sequential=Trueand overrides worker resolution to always use a single worker with noworker_env.
DataFrameTool¶
DataFrameTool base class — main process only.
- class bioimageflow.dataframe_tool.Passthrough[source]¶
Bases:
IOModelMarker base class for DataFrameTool Outputs that preserve input columns.
- class bioimageflow.dataframe_tool.DataFrameTool[source]¶
Bases:
BaseToolTool that transforms DataFrames in the main process.
-
accepts_upstream:
bool= True¶ Whether this tool accepts positional upstream Nodes.
Set to
Falseon source tools (e.g.Files,Generate) that produce a DataFrame from constants alone. A source tool raisesSourceToolUpstreamErrorif any positional argument is passed.
- classmethod resolve_outputs(inputs=None)[source]¶
Return the output column schema for the given (possibly partial) inputs.
Each value has the per-field shape produced by
serialize_output_schema():{"type": str, "default": Any | None, "image_spec": dict | None}.Default implementation: :rtype:
dict[str,dict[str,Any]] |NoneOutputsdeclared asIOModel→ returns the static schema.Outputsis aPassthroughsubclass → returns the marker dict{"_passthrough": True, **declared_extra_fields}.Otherwise → returns
None(schema unknown without input information).
Tools whose output column names are derived from their inputs (e.g.
Generate, wherecolumn_nameis a runtime parameter) override this method. Merge tools whose output schema depends on upstream schemas (rather than just inputs) instead overrideresolve_merge_schema().Must be pure (no I/O, no side effects). Returning
Noneor a partial dict is allowed wheninputsis incomplete.
- classmethod resolve_merge_schema(upstream_schemas, inputs=None)[source]¶
Return the merged output schema given upstream schemas.
Override this on merge tools whose output columns are computed from upstream column sets (
InnerJoin,CrossJoin,JoinOnColumn,Concat,Collect).Returns
Nonewhen any required upstream schema isNone(caller should treat that as “schema unresolvable”). The default implementation returnsNonesoNode.get_output_schema()falls back toresolve_outputs()for non-merge tools.Each entry has the same shape as the values returned by
resolve_outputs().
-
accepts_upstream:
Cache¶
Hashing, caching, and provenance.
- bioimageflow.cache.normalize_dependencies(dependencies)[source]¶
Normalize dependencies for consistent hashing.
- bioimageflow.cache.deterministic_serialize(obj)[source]¶
Serialize an object deterministically for hashing.
- bioimageflow.cache.compute_signature_hash(tool_name, tool_version, env_hash, resolved_params, upstream_hashes, source_hash=None)[source]¶
Compute the logical digest for a node.
- bioimageflow.cache.cache_load(cache_path)[source]¶
Load a DataFrame from cache.
Accepts either a
.parquetor.csvpath.- Return type:
DataFrame- Parameters:
cache_path (Path)
- bioimageflow.cache.dataframe_result_key(node_name, sig_hash)[source]¶
Return the result key for a DataFrameTool node.
- bioimageflow.cache.processing_result_key(node_name, sig_hash)[source]¶
Return the result key for a ProcessingTool node.
- bioimageflow.cache.iter_dataframe_result_metadata(storage_path, known_node_signatures=None)[source]¶
Return DataFrameTool result metadata, inferring metadata-less records when possible.
- bioimageflow.cache.iter_processing_result_metadata(storage_path, known_node_signatures=None)[source]¶
Return ProcessingTool result metadata, inferring metadata-less records when possible.
- bioimageflow.cache.dataframe_lookup(storage_path, node_name, sig_hash)[source]¶
Load a DataFrameTool cache hit, or return
Noneon miss.
- bioimageflow.cache.dataframe_publish(storage_path, node_name, sig_hash, df)[source]¶
Publish a DataFrameTool result through the immutable record model.
- bioimageflow.cache.processing_prepare_attempt(storage_path, node_name, sig_hash)[source]¶
Create an attempt staging tree for a ProcessingTool node.
- bioimageflow.cache.processing_lookup(storage_path, node_name, sig_hash, path_columns, shared_array_columns=None, hydrate_assets=True)[source]¶
Load a ProcessingTool cache hit, or return
Noneon miss.
- bioimageflow.cache.processing_publish(storage_path, node_name, sig_hash, df, *, result_key, attempt_id, staging_dir, staging_assets_dir, path_columns, owned_path_columns, shared_array_columns=None, declared_owned_artifact_paths=None, declared_scalar_outputs=None)[source]¶
Publish a source ProcessingTool attempt as an immutable record.
- Return type:
DataFrame- Parameters:
Storage¶
Low-level cache storage primitives for the current cache/v1 storage layout.
Output/cache storage primitives.
The on-disk cache schema is versioned, but this module is the clean storage implementation used by the current runtime.
- exception bioimageflow.storage.CacheCorruptionError[source]¶
Bases:
RuntimeErrorRaised when cache metadata points to corrupt or unsafe state.
- class bioimageflow.storage.OutputViewCapability[source]¶
Bases:
objectStructured result from probing one output-view materialization mode.
- bioimageflow.storage.canonical_json_bytes(value)[source]¶
Return canonical UTF-8 JSON bytes for hashing.
- bioimageflow.storage.make_result_key(material)[source]¶
Create a deterministic result key from canonical material.
- bioimageflow.storage.result_shard_parts(result_key)[source]¶
Return deterministic nested shard path parts for a result key.
- bioimageflow.storage.make_node_keys(names)[source]¶
Return storage-safe node keys, disambiguating normalized collisions.
- bioimageflow.storage.validate_relative_posix_path(path)[source]¶
Validate and normalize a record-relative POSIX path.
- bioimageflow.storage.canonical_scalar_payload(value)[source]¶
Return the canonical payload for scalar manifest metadata.
- bioimageflow.storage.canonical_dataframe_digest(df, *, declared_columns=None, column_kinds=None)[source]¶
Return a stable digest for the supported dataframe surface.
- bioimageflow.storage.asset_digest_and_size(path)[source]¶
Return deterministic size and digest metadata for a file or directory asset.
- bioimageflow.storage.make_record_id(manifest_material)[source]¶
Create a record ID from content material, excluding execution metadata.
- class bioimageflow.storage.RecordManifest[source]¶
Bases:
objectStructured manifest helper for a reusable record.
- class bioimageflow.storage.CurrentPointer[source]¶
Bases:
objectStructured helper for
current.json.- __init__(result_key, record_id, manifest, attempt_id, run_id, policy='first-valid', schema='bioimageflow.cache.current.v1', selected_at=None)¶
- class bioimageflow.storage.Storage[source]¶
Bases:
objectFilesystem paths and guarded metadata updates for versioned storage.
- probe_output_view_mode(mode)[source]¶
Probe an output-view mode on the workflow storage filesystem.
- Return type:
- Parameters:
mode (str)
- write_run_metadata(run_id, *, workflow_identity, engine, status, target_nodes, started_at=None, completed_at=None)[source]¶
Write workflow-level run metadata.
- write_run_node_result(run_id, node_key, *, result_key, record_id, cache_hit)[source]¶
Write a run-local view over the selected current record for one node.
- update_latest_node(node_key, run_id)[source]¶
Atomically point
views/latest/<node-key>at a run-node view.
- update_latest_success_run(run_id)[source]¶
Atomically point
views/runs/latest-successat a successful run view.
- materialize_run_outputs(run_id, mode)[source]¶
Materialize owned assets for one run under
outputs/runs.
- materialize_latest_node_outputs(node_key, mode)[source]¶
Materialize owned assets for one latest node pointer under
outputs/latest.
- materialize_latest_outputs(mode)[source]¶
Materialize owned assets for all latest node pointers under
outputs/latest.
Template¶
Output templating engine for ProcessingTool.
- bioimageflow.template.get_output_templates(outputs_cls, inputs_cls, overrides=None)[source]¶
Extract templates from explicit Template defaults.
Path outputs without a Template default use the built-in default template. Non-path outputs may not declare Template defaults.
- bioimageflow.template.validate_template(template_str, input_annotations)[source]¶
Check that all template references are valid. :rtype:
None{field.xxx}— field must exist in Inputs, xxx must be a valid property (stem, name, ext, exts).{bare}— must be a special variable, acolumn:reference, or an input field. Unknown bare references emit a warning.
Tool registry¶
Public tool-registry abstraction.
A ToolRegistry wraps load_versioned_package(),
resolve_tool_class(), and serialize_input_schema() /
serialize_output_schema() behind a single object that GUIs and
other consumers can use without rebuilding metadata serialization or
package-resolution layers themselves.
The registry deliberately separates install (a slow, network-bound side effect) from register (a fast, in-process index lookup):
ToolRegistry.install_package()installs a package into the tool store, doing the network work.ToolRegistry.register_package()only loads what is already installed and indexes its tools — never installs.
GUIs that validate on every keystroke must call register_package
on hot paths and install_package only from a user-initiated
action.
Workflow exports may also carry embedded custom tool modules. GUIs can
call ToolRegistry.register_workflow() to discover those local tools
for the specific workflow being edited without promoting them to a
versioned tool package.
- class bioimageflow.registry.ToolMetadata[source]¶
Bases:
objectPublic, serialized description of a tool class.
Produced by
ToolRegistry.register_package()for every BaseTool subclass found in the loaded package.- Variables:
package – The tool’s package name (e.g.
"my_tools").version – Pinned package version (e.g.
"1.2.3").module – Canonical module path (e.g.
"my_tools.alpha").class_name – The class name as written in the source.
inputs_schema – Output of
serialize_input_schema()for this class.outputs_schema – Output of
serialize_output_schema()for this class.display_name – Human-readable label declared on the class, or the class name.
tags – Free-form tags declared on the class (empty list if none).
- __init__(package, version, module, class_name, inputs_schema, outputs_schema, display_name, tags=<factory>)¶
- class bioimageflow.registry.ToolRegistry[source]¶
Bases:
objectStateful index of tool classes loaded from packages or workflows.
- install_package(name, version)[source]¶
Install a versioned package into the tool store.
This is the slow, network-bound side effect — it does not load or index anything. Call
register_package()separately once the install completes.nameis the import name (the module a workflow expects to import).ensure_installedinfers the PyPI name from this by replacing underscores with hyphens, matching the convention used byWorkflow.from_dict()’s auto-installer.
- register_package(name, version)[source]¶
Load an already installed package and index its tools.
Returns the metadata for every BaseTool subclass discovered in the package. Raises
FileNotFoundErrorif the package is not present in the store — the caller must install it first viainstall_package()(or skip registration on the hot path).- Return type:
- Parameters:
- register_workflow(workflow)[source]¶
Index custom tools carried by a workflow.
workflowmay be either a livebioimageflow.Workflowinstance or an exported workflow dict. Live workflows are inspected recursively; exported archives carry one deduplicatedcustom_sourcestable. Package tools referenced by the workflow are not loaded or installed here; useregister_package()for those.- Return type:
- Parameters:
workflow (Any)
- get_class(class_name, *, package=None, version=None, module=None)[source]¶
Return a registered class, or
Noneif not registered.When several package versions expose the same class name, callers can pass
package/version/moduleto select the intended class. A name-only lookup keeps the historical behavior and returns the most recently registered matching class.
- get_metadata(class_name, *, package=None, version=None, module=None)[source]¶
Return registered
ToolMetadata, orNone.
Workflow session¶
Incremental editing session for GUI clients.
A WorkflowSession is a parallel data model to Workflow
that holds the wire-format dict and exposes mutation operations. It
materializes a Workflow on demand and caches it across edits,
selectively rebuilding only when structural changes (add/remove
node/edge) demand it. Edits that don’t change the graph topology
(set_constant, set_enabled) mutate the cached workflow in
place — so a constant edit followed by validate() does not
re-resolve any tool class.
Why a separate class? Workflow builds nodes eagerly during
construction, with _upstream_nodes references and column bindings
wired at __init__ time. Retrofitting incremental mutation onto that
model would require invasive changes to Node. A dict-backed
session, materialized to a Workflow only when needed, is both simpler
and matches what GUIs actually want to send over the wire.
- class bioimageflow.session.WorkflowSession[source]¶
Bases:
objectA mutable, dict-backed editing session for a workflow.
The session is the canonical state. Call
to_workflow()to obtain a builtWorkflowfor execution, orto_dict()to snapshot the wire format.- add_node(node)[source]¶
Append a node entry to the session.
nodeis a wire-format dict with at leastnameand tool identification keys for either a tool or recursive workflow node.
- set_constant(node, field, value)[source]¶
Update a constant binding on a node.
This is a non-structural edit: the cached
Workflow(if any) is mutated in place so that subsequentto_workflow()/validate()/plan()calls do not re-resolve any tool class.
- set_enabled(node, enabled)[source]¶
Toggle a node’s enabled flag.
Non-structural: the cached workflow is updated in place.
- property errors: list[ValidationError]¶
Cached errors from the last
validate()call (or empty).
- property failed_nodes: dict[str, ValidationError]¶
Failed nodes from the last
to_workflow()build.
- to_workflow()[source]¶
Return a built
Workflow, caching the result.Uses
Workflow.from_dict(partial=True, validate_only=True)so per-node failures are captured inWorkflow.failed_nodesrather than raising.- Return type:
- validate()[source]¶
Return the validation errors for the current state.
Cached across non-structural edits.
- Return type:
list[ValidationError]
Workflow nodes¶
A workflow invocation embedded as a node in another workflow.
Wetlands configuration¶
Orchestrator-side Wetlands environment management.
Provides a single shared EnvironmentManager instance used by both
the execution engine (tool dispatch) and the tool loader (package install).
Call configure_wetlands() once at the top of your script to set paths;
everything else picks up the same instance automatically.
- bioimageflow.env_manager.configure_wetlands(**config)[source]¶
Set Wetlands configuration for the entire process.
Must be called before any tool loading or workflow execution. Subsequent calls are ignored with a warning if the manager is already initialized.
- Common parameters:
wetlands_instance_path: Path for Wetlands state (logs, pixi). conda_path: Path to the pixi or micromamba installation. main_conda_environment_path: Main conda env for dep checking. debug: Enable debugpy in worker processes. Use
BIOIMAGEFLOW_USE_LOCAL_CORE=1to inject the local editablebioimageflow-corecheckout into worker environments.
Return the process-wide Wetlands
EnvironmentManager.On first call, creates the manager using configuration from
configure_wetlands()(merged with any config kwargs passed here). Subsequent calls return the cached instance.- Return type:
EnvironmentManager- Parameters:
config (Any)
- class bioimageflow.env_manager.WetlandsEnvManager[source]¶
Bases:
objectManages Wetlands environments for ProcessingTool execution.
Creates environments lazily on first use.
Caches launched environments by name.
Auto-injects
bioimageflow-coreinto every environment’s pip deps.Provides dispatch helpers that route calls through the Wetlands proxy.
- __init__(wetlands_instance_path=None, conda_path=None, main_conda_environment_path=None, bioimageflow_core_dependency=None, use_local_bioimageflow_core=None, **kwargs)[source]¶
- get_or_create(env_spec, max_workers=1, worker_env=None, worker_timeout=None)[source]¶
Get or create a Wetlands environment.
Wetlands validates same-name environment recipe reuse. On first creation,
env.launch(max_workers=..., worker_env=..., worker_timeout=...)is called. Subsequent calls with a differentmax_workersorworker_timeoutlog a warning but do not re-launch.This method is thread-safe and may be called concurrently.
- Return type:
- Parameters:
env_spec (EnvironmentSpec)
max_workers (int)
worker_env (Any | None)
worker_timeout (float | None)
- submit_process_batch(env_spec, tool_file_path, tool_class_name, arguments_dicts, context_dict, max_workers=1, worker_env=None, worker_timeout=None)[source]¶
Submit a batch call via
env.submit(). Returns aTask.
- map_process_rows(env_spec, tool_file_path, tool_class_name, arguments_dicts, context_dicts, max_workers=1, worker_env=None, worker_timeout=None)[source]¶
Submit per-row calls via
env.map_tasks(). Returnslist[Task].
- stop(env_name)[source]¶
Stop one launched environment.
Returns
Truewhen an environment was stopped andFalsewhen env_name was not running. The manager forgets a failed worker exit so a later execution can launch a fresh environment with the same name.
Validation¶
The validation surface (errors, schema serializers, single-field
helpers) has many internal helpers that automodule would surface
verbatim. See bioimageflow.validation for the curated reference, and
Errors for the error catalogue.