Generate JSON Schemas#
This guide shows how to use the SchemaRegistry to generate JSON Schemas. For details about what a JSON Schema and how it can be used, see Configuration Schemas and Validation.
Create the Registry#
First create the registry and register the classes you want included in the schema.
Here the discovery function is used to register all classes in pyaml and other packages which define entry points. See Use the Schema Registry for details.
from pyaml.validation import SchemaRegistry
registry = SchemaRegistry()
registry.discover()
Generate JSON Schema#
Use the SchemaGenerator to generate a JSON Schema to use with external tools.
If a base schema has registered concrete or virtual subclasses, the generated JSON Schema includes those alternatives. This allows editors and other JSON Schema tools to offer the appropriate fields for each configuration type.
from pprint import pprint
from pyaml.validation import SchemaGenerator
# Generate the JSON Schema for a quadrupole magnet
json_schema = SchemaGenerator.generate("pyaml.magnet.quadrupole.Quadrupole")
pprint(json_schema)
{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.quadrupole.Quadrupole',
'description': 'Fully qualified class path.',
'title': 'Class',
'type': 'string'},
'description': {'default': None,
'title': 'Description',
'type': ['string', 'null']},
'lattice_names': {'default': None,
'title': 'Lattice Names',
'type': ['string', 'null']},
'model': {'anyOf': [{'oneOf': [{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.identity_cfm_model.IdentityCFMagnetModel',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'multipoles': {'items': {'type': 'string'},
'title': 'Multipoles',
'type': 'array'},
'physics': {'anyOf': [{'items': {'type': ['string',
'null']},
'type': 'array'},
{'type': 'null'}],
'default': None,
'title': 'Physics'},
'powerconverters': {'anyOf': [{'items': {'type': ['string',
'null']},
'type': 'array'},
{'type': 'null'}],
'default': None,
'title': 'Powerconverters'},
'units': {'anyOf': [{'items': {'type': 'string'},
'type': 'array'},
{'type': 'null'}],
'default': None,
'title': 'Units'}},
'required': ['class',
'multipoles'],
'title': 'IdentityCFMagnetModelConfigurationSchema',
'type': 'object'},
{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.identity_model.IdentityMagnetModel',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'physics': {'default': None,
'title': 'Physics',
'type': ['string',
'null']},
'powerconverter': {'default': None,
'title': 'Powerconverter',
'type': ['string',
'null']},
'unit': {'default': None,
'title': 'Unit',
'type': ['string',
'null']}},
'required': ['class'],
'title': 'IdentityMagnetModelConfigurationSchema',
'type': 'object'},
{'additionalProperties': False,
'properties': {'calibration_factors': {'anyOf': [{'items': {'type': 'number'},
'type': 'array'},
{'type': 'null'}],
'default': None,
'title': 'Calibration '
'Factors'},
'calibration_offsets': {'anyOf': [{'items': {'type': 'number'},
'type': 'array'},
{'type': 'null'}],
'default': None,
'title': 'Calibration '
'Offsets'},
'class': {'const': 'pyaml.magnet.linear_cfm_model.LinearCFMagnetModel',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'curves': {'items': {'oneOf': [{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.csvcurve.CSVCurve',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'file': {'title': 'File',
'type': 'string'}},
'required': ['class',
'file'],
'title': 'CSVCurveConfigurationSchema',
'type': 'object'},
{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.inline_curve.InlineCurve',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'mat': {'items': {'items': {'type': 'number'},
'type': 'array'},
'title': 'Mat',
'type': 'array'}},
'required': ['class',
'mat'],
'title': 'InlineCurveConfigurationSchema',
'type': 'object'}],
'title': 'CurveConfigurationSchema'},
'title': 'Curves',
'type': 'array'},
'hardware_units': {'items': {'type': 'string'},
'title': 'Hardware '
'Units',
'type': 'array'},
'matrix': {'anyOf': [{'oneOf': [{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.csvmatrix.CSVMatrix',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'file': {'title': 'File',
'type': 'string'}},
'required': ['class',
'file'],
'title': 'CSVMatrixConfigurationSchema',
'type': 'object'},
{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.inline_matrix.InlineMatrix',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'mat': {'items': {'items': {'type': 'number'},
'type': 'array'},
'title': 'Mat',
'type': 'array'}},
'required': ['class',
'mat'],
'title': 'InlineMatrixConfigurationSchema',
'type': 'object'}],
'title': 'MatrixConfigurationSchema'},
{'type': 'null'}],
'default': None},
'multipoles': {'items': {'type': 'string'},
'title': 'Multipoles',
'type': 'array'},
'powerconverters': {'items': {'type': ['string',
'null']},
'title': 'Powerconverters',
'type': 'array'},
'pseudo_factors': {'anyOf': [{'items': {'type': 'number'},
'type': 'array'},
{'type': 'null'}],
'default': None,
'title': 'Pseudo '
'Factors'},
'pseudo_offsets': {'anyOf': [{'items': {'type': 'number'},
'type': 'array'},
{'type': 'null'}],
'default': None,
'title': 'Pseudo '
'Offsets'},
'units': {'anyOf': [{'items': {'type': 'string'},
'type': 'array'},
{'type': 'null'}],
'default': None,
'title': 'Units'}},
'required': ['class',
'multipoles',
'curves',
'powerconverters',
'hardware_units'],
'title': 'LinearCFMagnetModelConfigurationSchema',
'type': 'object'},
{'additionalProperties': False,
'properties': {'calibration_factor': {'default': 1.0,
'title': 'Calibration '
'Factor',
'type': 'number'},
'calibration_offset': {'default': 0.0,
'title': 'Calibration '
'Offset',
'type': 'number'},
'class': {'const': 'pyaml.magnet.linear_model.LinearMagnetModel',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'crosstalk': {'default': 1.0,
'title': 'Crosstalk',
'type': 'number'},
'curve': {'anyOf': [{'oneOf': [{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.csvcurve.CSVCurve',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'file': {'title': 'File',
'type': 'string'}},
'required': ['class',
'file'],
'title': 'CSVCurveConfigurationSchema',
'type': 'object'},
{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.inline_curve.InlineCurve',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'mat': {'items': {'items': {'type': 'number'},
'type': 'array'},
'title': 'Mat',
'type': 'array'}},
'required': ['class',
'mat'],
'title': 'InlineCurveConfigurationSchema',
'type': 'object'}],
'title': 'CurveConfigurationSchema'},
{'type': 'null'}],
'default': None},
'hardware_unit': {'title': 'Hardware '
'Unit',
'type': 'string'},
'powerconverter': {'default': None,
'title': 'Powerconverter',
'type': ['string',
'null']},
'unit': {'title': 'Unit',
'type': 'string'}},
'required': ['class',
'unit',
'hardware_unit'],
'title': 'LinearMagnetModelConfigurationSchema',
'type': 'object'},
{'additionalProperties': False,
'properties': {'calibration_factors': {'anyOf': [{'type': 'number'},
{'items': {'type': 'number'},
'type': 'array'},
{'type': 'null'}],
'default': None,
'title': 'Calibration '
'Factors'},
'calibration_offsets': {'anyOf': [{'type': 'number'},
{'items': {'type': 'number'},
'type': 'array'},
{'type': 'null'}],
'default': None,
'title': 'Calibration '
'Offsets'},
'class': {'const': 'pyaml.magnet.linear_serialized_model.LinearSerializedMagnetModel',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'crosstalk': {'anyOf': [{'type': 'number'},
{'items': {'type': 'number'},
'type': 'array'}],
'default': 1.0,
'title': 'Crosstalk'},
'curves': {'anyOf': [{'oneOf': [{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.csvcurve.CSVCurve',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'file': {'title': 'File',
'type': 'string'}},
'required': ['class',
'file'],
'title': 'CSVCurveConfigurationSchema',
'type': 'object'},
{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.inline_curve.InlineCurve',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'mat': {'items': {'items': {'type': 'number'},
'type': 'array'},
'title': 'Mat',
'type': 'array'}},
'required': ['class',
'mat'],
'title': 'InlineCurveConfigurationSchema',
'type': 'object'}],
'title': 'CurveConfigurationSchema'},
{'items': {'oneOf': [{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.csvcurve.CSVCurve',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'file': {'title': 'File',
'type': 'string'}},
'required': ['class',
'file'],
'title': 'CSVCurveConfigurationSchema',
'type': 'object'},
{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.inline_curve.InlineCurve',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'mat': {'items': {'items': {'type': 'number'},
'type': 'array'},
'title': 'Mat',
'type': 'array'}},
'required': ['class',
'mat'],
'title': 'InlineCurveConfigurationSchema',
'type': 'object'}],
'title': 'CurveConfigurationSchema'},
'type': 'array'}],
'title': 'Curves'},
'hardware_unit': {'default': None,
'title': 'Hardware '
'Unit',
'type': ['string',
'null']},
'powerconverter': {'default': None,
'title': 'Powerconverter',
'type': ['string',
'null']},
'unit': {'default': None,
'title': 'Unit',
'type': ['string',
'null']}},
'required': ['class', 'curves'],
'title': 'LinearSerializedMagnetModelConfigurationSchema',
'type': 'object'},
{'additionalProperties': False,
'properties': {'alpha': {'default': 0.0,
'title': 'Alpha',
'type': 'number'},
'calibration_factor': {'default': 1.0,
'title': 'Calibration '
'Factor',
'type': 'number'},
'calibration_offset': {'default': 0.0,
'title': 'Calibration '
'Offset',
'type': 'number'},
'class': {'const': 'pyaml.magnet.spline_model.SplineMagnetModel',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'crosstalk': {'default': 1.0,
'title': 'Crosstalk',
'type': 'number'},
'curve': {'oneOf': [{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.csvcurve.CSVCurve',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'file': {'title': 'File',
'type': 'string'}},
'required': ['class',
'file'],
'title': 'CSVCurveConfigurationSchema',
'type': 'object'},
{'additionalProperties': False,
'properties': {'class': {'const': 'pyaml.magnet.inline_curve.InlineCurve',
'description': 'Fully '
'qualified '
'class '
'path.',
'title': 'Class',
'type': 'string'},
'mat': {'items': {'items': {'type': 'number'},
'type': 'array'},
'title': 'Mat',
'type': 'array'}},
'required': ['class',
'mat'],
'title': 'InlineCurveConfigurationSchema',
'type': 'object'}],
'title': 'CurveConfigurationSchema'},
'hardware_unit': {'default': None,
'title': 'Hardware '
'Unit',
'type': ['string',
'null']},
'powerconverter': {'default': None,
'title': 'Powerconverter',
'type': ['string',
'null']},
'unit': {'default': None,
'title': 'Unit',
'type': ['string',
'null']}},
'required': ['class', 'curve'],
'title': 'SplineMagnetModelConfigurationSchema',
'type': 'object'}],
'title': 'MagnetModelConfigurationSchema'},
{'type': 'null'}],
'default': None},
'name': {'title': 'Name', 'type': 'string'}},
'required': ['class', 'name'],
'title': 'QuadrupoleConfigurationSchema',
'type': 'object'}
The result can also be saved directly to a file. As can be seen, the schema is very long and not easy to read but it is not meant to be used by humans, only by tools which make use of the JSON Schema standard.
SchemaGenerator.save("pyaml.magnet.quadrupole.Quadrupole","quadrupole-schema.json")
PosixPath('quadrupole-schema.json')