Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions docs/source/explanation/configuration.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Principles and Syntax of the Configuration
# Configuration Structure and Syntax

By creating a configuration it is possible to have pyAML build devices and applications automatically for several control modes.

Expand Down Expand Up @@ -45,19 +45,19 @@ model:

The configuration describes what should be constructed; it does not contain executable Python code. This keeps configuration readable, reviewable, and usable by tools such as JSON Schema editors.

The configuration is possible to maintain separately to pyAML, for example in a separate Git repository or in a database.
The configuration is possible to maintain separately from pyAML, for example in a separate Git repository or in a database.

## Supported Formats

The configuration can be written and loaded in different formats:

**File**: It can be written as a text file and loaded using `Accelerator.load()`. Both `YAML` and `JSON` are supported but `YAML` is considered the default option.
**File**: It can be written as a text file and loaded using `Accelerator.load()`. Both YAML and JSON are supported.

**Dictionary**: It can also be written as a nested dictionary and loaded using `Accelerator.from_dict()`.

## Configuration Root

The configuration root is the directory used to resolve relative configuration paths. It applies to the file passed to `Accelerator.load()`, paths used by resolvers, and automatic file includes. Relative paths are resolved against this directory.
The configuration root is the directory used to resolve relative configuration paths. It applies to the file passed to `Accelerator.load()` and paths used by [resolvers](#resolvers. Relative paths are resolved against this directory.

By default, the root is the current working directory when pyAML is imported. It can be changed before loading a configuration with `ROOT.set()`:

Expand All @@ -67,11 +67,15 @@ from pyaml.configuration import ROOT
ROOT.set("/path/to/configuration")
```

After setting the root, `devices/quadrupole.yaml` refers to `/path/to/configuration/devices/quadrupole.yaml`. Absolute paths are normalized and used directly. Setting the root makes it possible to keep a configuration and its included files in a portable directory tree while selecting that tree at runtime.
After setting the root, a file written as `devices/quadrupole.yaml` in the configuration file will refer to `/path/to/configuration/devices/quadrupole.yaml`.

Setting the root makes it possible to keep a configuration and its included files in a portable directory tree while selecting that tree at runtime.

Absolute paths are normalized and used directly.

## Resolvers

Resolvers let a configuration value refer to information that is supplied when the configuration is loaded, such as an environment variable or another configuration file. A resolver expression has the following form:
Resolvers can be used in the configuration to let a value refer to information which is supplied when the configuration is loaded, for example an environment variable or another configuration file. A resolver expression has the following form:

```yaml
${resolver:payload}
Expand All @@ -85,6 +89,9 @@ The following built-in resolvers are available:
| --- | --- | --- |
| `env` | Environment variable | The value of the named environment variable. An error is raised if it is not set. |
| `path` | A file or directory path | The absolute, normalized path, resolved relative to pyAML's configuration root. The target is not loaded as part of loading the configuration. |
| `file` | A YAML, YML, or JSON file path | The path to a file which should be loaded and expanded into the configuration as part of loading the configuration. Relative paths use the configuration root.
| `file` | A YAML, YML, or JSON file path | The path to a file which should be loaded and expanded into the configuration as part of loading it. Relative paths use the configuration root.

Configuration files can also be included without an explicit `file` expression. A string ending in `.yaml`, `.yml`, or `.json` is loaded automatically for convenience. This makes it easy to split the configuration into several files if one wishes.

Configuration files can also be included without an explicit `file` expression. A string ending in `.yaml`, `.yml`, or `.json` is loaded automatically for convenience if one wishes to split the configuration into several files.
```{warning}
If you include a `.yaml`, `.yml`, or `.json` in the configuration file which you do not want to be loaded and expanded into the configuration (for example a lattice in JSON format), remember to put `${path:filename}` or you will get an error when loading the configuration.
19 changes: 13 additions & 6 deletions docs/source/how-to/configuration/create-configuration.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
# Create and Load Configuration

The principles and syntax of the configuration are explained in more detail in [Principles and Syntax of the Configuration](../../explanation/configuration). This guide focuses on the different ways to create it.
The structure and syntax of the configuration are explained in detail in [Configuration Structure and Syntax](../../explanation/configuration). This guide focuses on the different ways to create it.

There are several ways to create a configuration. It is recommended to test the different options and see which one you prefer:
There are many ways to create a configuration. It is recommended to test the different
options and see which one you prefer:

- [Use ConfigurationSchema](./use-configuration-schema.ipynb) objects and export as a dictionary or text file
- Use a [JSON Schema in VS Code](./use-vscode-json-schema.md)

- Use a JSON Schema in the [MetaConfigurator](./use-meta-configurator.md)

- Use a [JSON Schema in VS Code](./use-vscode-json-schema.md)
- [Use ConfigurationSchema](./use-configuration-schema.ipynb) objects and export as a dictionary or text file

Another option is to use AI coding assistance tools. You can then for example supply a lattice file, information describing the naming conventions for your control system and a JSON Schema for the pyAML configuration and get help to write it.

For information about what a JSON Schema is and how to generate it, see [Configuration Schemas and Validation](../../explanation/schema_and_validation.md) and [Generate JSON Schemas](./generate-json-schema.ipynb).

## Load the Configuration

The configuration can be loaded into the `Accelerator` in several ways:
The configuration can be loaded into the `Accelerator` in two ways:

| Type| Command | Description |
| --- | --- | --- |
| File | `Accelerator.load()` | A text file in JSON on YAML format.
| File | `Accelerator.load()` | A text file in JSON or YAML format.
| Dictionary | `Accelerator.from_dict()` | A nested dictionary.

See the API documentation for the [Accelerator](https://pyaml.readthedocs.io/en/stable/api/pyaml.accelerator.html#module-pyaml.accelerator) for more details.

## Validation

The configuration is validated when loading it into the `Accelerator` but it can also be validated without having to load it. This is useful if you want to be able to maintain it separately from pyAML. See [Validate Configuration](./validate-configuration) for details.
26 changes: 13 additions & 13 deletions docs/source/how-to/configuration/generate-json-schema.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"source": [
"# Generate JSON Schemas\n",
"\n",
"This guide shows how to use the `SchemaRegistry` to generate JSON Schemas."
"This guide shows how to use the `SchemaRegistry` to generate [JSON Schemas](https://json-schema.org/). For details about what a JSON Schema and how it can be used, see [Configuration Schemas and Validation](./../../explanation/schema_and_validation.md)."
]
},
{
Expand All @@ -19,7 +19,7 @@
"\n",
"First create the registry and register the classes you want included in the schema.\n",
"\n",
"Here the discovery function is used to register all classes in `pyaml` and other packages which define entry points."
"Here the discovery function is used to register all classes in `pyaml` and other packages which define entry points. See [Use the Schema Registry](./use-schema-registry) for details."
]
},
{
Expand All @@ -42,14 +42,14 @@
"source": [
"## Generate JSON Schema\n",
"\n",
"Use the `SchemaGenerator` to generate a JSON Schema to use with external tools.\n",
"Use the [SchemaGenerator](https://pyaml.readthedocs.io/en/stable/api/pyaml.validation.html#pyaml.validation.SchemaGenerator) to generate a JSON Schema to use with external tools.\n",
"\n",
"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."
]
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": null,
"id": "dfb96bb7",
"metadata": {},
"outputs": [
Expand All @@ -68,7 +68,7 @@
" 'lattice_names': {'default': None,\n",
" 'title': 'Lattice Names',\n",
" 'type': ['string', 'null']},\n",
" 'model': {'anyOf': [{'anyOf': [{'additionalProperties': False,\n",
" 'model': {'anyOf': [{'oneOf': [{'additionalProperties': False,\n",
" 'properties': {'class': {'const': 'pyaml.magnet.identity_cfm_model.IdentityCFMagnetModel',\n",
" 'description': 'Fully '\n",
" 'qualified '\n",
Expand Down Expand Up @@ -143,7 +143,7 @@
" 'path.',\n",
" 'title': 'Class',\n",
" 'type': 'string'},\n",
" 'curves': {'items': {'anyOf': [{'additionalProperties': False,\n",
" 'curves': {'items': {'oneOf': [{'additionalProperties': False,\n",
" 'properties': {'class': {'const': 'pyaml.magnet.csvcurve.CSVCurve',\n",
" 'description': 'Fully '\n",
" 'qualified '\n",
Expand Down Expand Up @@ -180,7 +180,7 @@
" 'title': 'Hardware '\n",
" 'Units',\n",
" 'type': 'array'},\n",
" 'matrix': {'anyOf': [{'anyOf': [{'additionalProperties': False,\n",
" 'matrix': {'anyOf': [{'oneOf': [{'additionalProperties': False,\n",
" 'properties': {'class': {'const': 'pyaml.magnet.csvmatrix.CSVMatrix',\n",
" 'description': 'Fully '\n",
" 'qualified '\n",
Expand Down Expand Up @@ -263,7 +263,7 @@
" 'crosstalk': {'default': 1.0,\n",
" 'title': 'Crosstalk',\n",
" 'type': 'number'},\n",
" 'curve': {'anyOf': [{'anyOf': [{'additionalProperties': False,\n",
" 'curve': {'anyOf': [{'oneOf': [{'additionalProperties': False,\n",
" 'properties': {'class': {'const': 'pyaml.magnet.csvcurve.CSVCurve',\n",
" 'description': 'Fully '\n",
" 'qualified '\n",
Expand Down Expand Up @@ -337,7 +337,7 @@
" 'type': 'array'}],\n",
" 'default': 1.0,\n",
" 'title': 'Crosstalk'},\n",
" 'curves': {'anyOf': [{'anyOf': [{'additionalProperties': False,\n",
" 'curves': {'anyOf': [{'oneOf': [{'additionalProperties': False,\n",
" 'properties': {'class': {'const': 'pyaml.magnet.csvcurve.CSVCurve',\n",
" 'description': 'Fully '\n",
" 'qualified '\n",
Expand Down Expand Up @@ -368,7 +368,7 @@
" 'title': 'InlineCurveConfigurationSchema',\n",
" 'type': 'object'}],\n",
" 'title': 'CurveConfigurationSchema'},\n",
" {'items': {'anyOf': [{'additionalProperties': False,\n",
" {'items': {'oneOf': [{'additionalProperties': False,\n",
" 'properties': {'class': {'const': 'pyaml.magnet.csvcurve.CSVCurve',\n",
" 'description': 'Fully '\n",
" 'qualified '\n",
Expand Down Expand Up @@ -439,7 +439,7 @@
" 'crosstalk': {'default': 1.0,\n",
" 'title': 'Crosstalk',\n",
" 'type': 'number'},\n",
" 'curve': {'anyOf': [{'additionalProperties': False,\n",
" 'curve': {'oneOf': [{'additionalProperties': False,\n",
" 'properties': {'class': {'const': 'pyaml.magnet.csvcurve.CSVCurve',\n",
" 'description': 'Fully '\n",
" 'qualified '\n",
Expand Down Expand Up @@ -498,9 +498,9 @@
],
"source": [
"from pprint import pprint\n",
"\n",
"from pyaml.validation import SchemaGenerator\n",
"\n",
"# Generate the JSON Schema for a quadrupole magnet\n",
"json_schema = SchemaGenerator.generate(\"pyaml.magnet.quadrupole.Quadrupole\")\n",
"pprint(json_schema)"
]
Expand All @@ -510,7 +510,7 @@
"id": "d329d7e5",
"metadata": {},
"source": [
"The result can also be saved directly to a file."
"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."
]
},
{
Expand Down
Loading