Recipe YAML Format¶
PyPTS accepts recipe language 2.0.0. Exact fields, types, required status,
defaults, aliases, and discriminator values are generated from the production
models in the Recipe Language 2.0 Reference. The downloadable
JSON Schema describes the
same contract.
A complete maintained example is included below. This file is parsed by the test suite with the production parser.
# SPDX-FileCopyrightText: 2026 CERN <home.cern>
# SPDX-License-Identifier: CC-BY-SA-4.0
---
name: Recipe language 2 documentation example
version: "1.0"
recipe_version: 2.0.0
description: Demonstrate canonical version 2 syntax and typed mappings.
main_sequence: Main
continue_on_error: false
report: overwrite
report_name_include_serial: true
test_package: acceptance.tests
globals:
target: 12
saved_result: null
---
sequence_name: Main
description: Run a measurement and then the calibration sequence.
parameters: {}
outputs: {}
locals:
expected: 12
measured: null
setup_steps: []
steps:
- steptype: PythonModuleStep
step_name: Measure channels
description: Exercise every input mapping and representative outputs.
id: measure-channels
skip: false
critical: true
continue_on_error: false
action_type: method
module: measurements.py
method_name: measure
input_mapping:
channels: {type: direct, value: [0, 1], indexed: true}
expected: {type: local, local_name: expected}
target: {type: global, global_name: target}
transform: {type: method, value: normalize}
output_mapping:
passed: {type: passfail}
exact: {type: equals, value: 12}
bounded: {type: range, min: 10, max: 14}
measured: {type: local, local_name: measured}
saved: {type: global, global_name: saved_result}
chart: {type: image}
- steptype: SequenceStep
step_name: Calibrate
description: Run a nested sequence and use its aggregate verdict.
sequence: {type: internal, name: Calibration}
input_mapping: {}
output_mapping:
result: {type: passthrough}
stored: {type: local, local_name: measured}
teardown_steps: []
---
sequence_name: Calibration
description: Wait for the equipment to stabilize.
parameters: {}
outputs: {}
locals: {}
setup_steps: []
steps:
- steptype: WaitStep
step_name: Stabilize
description: Wait before returning to the caller.
input_mapping:
wait_time: {type: direct, value: 1}
output_mapping: {}
teardown_steps: []
Multi-document structure¶
A recipe is one YAML stream containing multiple documents, separated by
---:
The first document is a RecipeHeader. Its required
recipe_versionis2.0.0andmain_sequencenames an existing sequence.Every later document is a Sequence. Sequence names must be unique, and at least one sequence is required.
Each sequence owns
setup_steps,steps, andteardown_stepslists. Step definitions use one of the exact, case-sensitive canonical discriminators listed in the generated reference.
Validation is strict. Unknown fields, wrong scalar types, duplicate YAML keys, unsafe YAML tags, missing required fields, invalid sequence references, and unsupported versions produce diagnostics. PyPTS does not repair or silently normalize legacy syntax.
Variables and mappings¶
globals belong to the recipe header and are available throughout the run.
locals belong to one active sequence. parameters and outputs are
currently reserved metadata dictionaries; the runtime does not automatically
bind nested-sequence inputs or outputs from them.
Every input mapping has an explicit type:
input_mapping:
literal: {type: direct, value: 12}
repeated: {type: direct, value: [1, 2], indexed: true}
from_local: {type: local, local_name: expected}
from_global: {type: global, global_name: target}
callback: {type: method, value: normalize}
The exact input structures are DirectInput, LocalInput, GlobalInput, and MethodInput. Indexed direct inputs must contain lists, and all indexed inputs on one step must have equal lengths.
Output mappings also require an explicit type. passfail, equals,
and range contribute verdicts; all configured verdict checks must pass.
passthrough consumes an already-computed result and must be the only
verdict mapping on a step. local and global store values, while
image publishes report images. See the generated
PassFailOutput through RangeOutput
definitions for exact fields.
Runtime-specific behavior¶
PythonModuleStep resolves module relative to test_package when the
header supplies that package. Without test_package, the runtime uses its
file-based module lookup. A method action requires method_name.
SequenceStep references another sequence in the same YAML stream.
WaitStep requires a wait_time input. SSH steps require the connection
globals documented by the parser and must follow connect, upload, close order.
Exact step-specific fields are linked from the generated reference, beginning
with PythonModuleStep.
Error handling applies to execution errors, not failed verdicts. A header-level
continue_on_error overrides step-level values when present; critical
errors still stop execution. Teardown steps run during sequence cleanup.
Serialization and readable examples¶
recipe_to_yaml() accepts a validated aggregate recipe definition and
returns deterministic multi-document YAML text without performing file I/O.
It emits aliases and model defaults, omits None, and always writes explicit
document separators. Parsing that output recreates an equal aggregate
definition.
Serialization is formatting-destructive: comments, quoting choices, key layout, and other source formatting are not retained. Maintained examples are therefore kept readable by hand and may include comments. YamVIEW and programmatic serialization produce normalized YAML instead.
Migrating version 1 recipes¶
Version 1 is rejected; there is no automatic migration command or runtime compatibility path. To migrate a file:
Set the required header field to
recipe_version: 2.0.0.Use exact canonical step names such as
PythonModuleStep,WaitStep, andUserInteractionStep. Lowercase spellings are invalid.Add
type: directto every literal input mapping that previously relied on the implicit default. All input and output mappings are discriminated explicitly.Remove sequence-level
serial_number. UseSerialNumberStepand a mapped global or local value when the run needs a serial number.Add every now-required field, including header, sequence, and step descriptions, and remove unknown fields.
Validate the complete multi-document file. Strict validation reports all detected migration issues with paths and source positions; PyPTS never changes legacy spelling or meaning silently.
After migration, parse the source, serialize with recipe_to_yaml(), and
parse again. Equal aggregate definitions establish semantic stability; byte
equality and preservation of source comments are intentionally not required.