Reuse a processing workflow with RecipePlan¶
When the same preprocessing steps must run on another recording, copying a method
chain also copies its input assumptions into application code. A RecipePlan records
the public Frame operations and their parameters separately from the data, so the same
workflow can be inspected, stored, and applied to a new input.
This tutorial builds a small preprocessing workflow, turns it into a Recipe, and proves that replay produces the same result as calling the Frame methods directly.
Build the workflow once¶
Create a representative input and process it with ordinary public Frame methods. No special builder API is required.
Recipe input: signal Operations: ['wandas.audio.remove_dc', 'wandas.audio.normalize']
RecipePlan.from_frame() reads semantic lineage already attached by the public calls.
One public call becomes one node, and the original sample values are not stored in the
plan.
Store and load the portable schema¶
to_dict() returns a strict JSON-compatible schema. A JSON roundtrip demonstrates
that the payload does not retain live Python operation objects. Loading resolves its
stable operation IDs through the built-in registry. A plan does not retain a registry;
extensions must pass the same immutable registry to from_frame(), from_dict(), and
apply().
Schema: wandas.recipe 2 Serialized bytes: 411
Apply it to a new Frame¶
Runtime inputs are supplied by the names chosen during extraction. Applying a plan
builds a lazy Frame workflow; numerical data is materialized only when this example
reads frame.data to verify the result.
Replay matches direct calls: yes Runtime metadata: {'recording': 'next'} History entries: 2
The plan supplies operation intent; the runtime Frame supplies samples, metadata, labels, sampling rate, and source-time information. The input Frame remains unchanged.
Multiple inputs remain explicit¶
Frame arithmetic, mix(), and external NumPy or Dask operands become additional named
inputs. Their values and container implementation are not embedded in the Recipe.
mixed = base.mix(other)
mix_plan = RecipePlan.from_frame(mixed, input_names=("base", "other"))
result = mix_plan.apply({"base": next_base, "other": next_other})
mix() combines samples by array index even when source-time offsets describe
different source periods. Align recordings explicitly first when source-time matching
is required.
Where to go next¶
- Run the executable Reusable Pipeline Recipes learning path.
- Use the RecipePlan how-to for multi-input and error boundaries.
- Consult the Pipeline API reference for signatures and exceptions.
- Read Recipe design only when you need the persistence or extension model.