Generate Configuration Using Configuration Schemas#
This guide shows how to use ConfigurationSchema to create a configuration. This allows to program the configuration if you prefer instead of using any of the options based on a JSON Schema.
Discover Schemas#
First create the registry and discover available schemas.
from pyaml.validation import SchemaRegistry
registry = SchemaRegistry()
registry.discover()
Create Configuration for Accelerator#
To create a configuration for an accelerator start by extracting the schema for it from the registry. You can see the required fields and their description using describe().
Unfortunately static type checking does not work since the schema is generated dynamically.
accelerator_schema = registry["pyaml.accelerator.Accelerator"]
print(accelerator_schema.describe())
AcceleratorConfigurationSchema(
class_path: str — Fully qualified class path.
facility: str
machine: str
energy: float
alphac: float | None
harmonic_number: int | None
controls: list[pyaml.control.controlsystem.ControlSystemConfigurationSchema] | None
simulators: list[pyaml.lattice.simulator.SimulatorConfigurationSchema] | None
arrays: list[pyaml.arrays.array.ArrayConfigConfigurationSchema] | None
devices: list[pyaml.common.element.ElementConfigurationSchema] | None
data_folder: str | None
description: str | None
)
For the subschemas, you can list available subclasses that are available in the registry.
from pprint import pprint
control_system_schema = registry["pyaml.control.controlsystem.ControlSystem"]
subclasses = registry.subclasses_of(control_system_schema)
pprint(subclasses)
{'pyaml_cs_oa.controlsystem.OphydAsyncControlSystem': <class 'pyaml_cs_oa.controlsystem.OphydAsyncControlSystemConfigurationSchema'>,
'tango.pyaml.controlsystem.TangoControlSystem': <class 'tango.pyaml.controlsystem.TangoControlSystemConfigurationSchema'>}
You can list the required fields for them in the same way as before.
tango_schema = registry["tango.pyaml.controlsystem.TangoControlSystem"]
print(tango_schema.describe())
TangoControlSystemConfigurationSchema(
class_path: str — Fully qualified class path.
name: str
tango_host: str | None
catalog: tango.pyaml.catalog.CatalogConfigurationSchema | None
debug_level: str | int | None
lazy_devices: bool
timeout_ms: int
)
Since ConfigurationSchema inherits from Pydantic BaseModel the configuration is validated for each object you create, meaning you can validate the configuration step-by-step instead of validating the whole nested structure in one step.
live_mode = tango_schema(
class_path = "tango.pyaml.controlsystem.TangoControlSystem",
name = "live",
)
print(type(live_mode))
print(live_mode)
<class 'tango.pyaml.controlsystem.TangoControlSystemConfigurationSchema'>
class_path='tango.pyaml.controlsystem.TangoControlSystem' name='live' tango_host=None catalog=None debug_level=None lazy_devices=True timeout_ms=3000
accelerator = accelerator_schema(
class_path='pyaml.accelerator.Accelerator',
facility = 'pyaml_facility',
machine = 'storage_ring',
energy = 1e6,
controls = [live_mode]
)
print(type(accelerator))
print(accelerator)
<class 'pyaml.accelerator.AcceleratorConfigurationSchema'>
class_path='pyaml.accelerator.Accelerator' facility='pyaml_facility' machine='storage_ring' energy=1000000.0 alphac=None harmonic_number=None controls=[TangoControlSystemConfigurationSchema(class_path='tango.pyaml.controlsystem.TangoControlSystem', name='live', tango_host=None, catalog=None, debug_level=None, lazy_devices=True, timeout_ms=3000)] simulators=None arrays=None devices=None data_folder=None description=None
You have now created a Pydantic BaseModel which describes the configuration and can dump it to a dictionary or JSON using Pydantic functionality depending on what you prefer.
print(accelerator.model_dump())
{'class_path': 'pyaml.accelerator.Accelerator', 'facility': 'pyaml_facility', 'machine': 'storage_ring', 'energy': 1000000.0, 'alphac': None, 'harmonic_number': None, 'controls': [{'class_path': 'tango.pyaml.controlsystem.TangoControlSystem', 'name': 'live', 'tango_host': None, 'catalog': None, 'debug_level': None, 'lazy_devices': True, 'timeout_ms': 3000}], 'simulators': None, 'arrays': None, 'devices': None, 'data_folder': None, 'description': None}
print(accelerator.model_dump_json(indent=2))
{
"class_path": "pyaml.accelerator.Accelerator",
"facility": "pyaml_facility",
"machine": "storage_ring",
"energy": 1000000.0,
"alphac": null,
"harmonic_number": null,
"controls": [
{
"class_path": "tango.pyaml.controlsystem.TangoControlSystem",
"name": "live",
"tango_host": null,
"catalog": null,
"debug_level": null,
"lazy_devices": true,
"timeout_ms": 3000
}
],
"simulators": null,
"arrays": null,
"devices": null,
"data_folder": null,
"description": null
}