Source code for ophyd_async.core._yaml_settings

import warnings
from enum import Enum
from pathlib import Path
from typing import Any

import numpy as np
import numpy.typing as npt
import yaml
from pydantic import BaseModel

from ._settings import SettingsProvider


def ndarray_representer(dumper: yaml.Dumper, array: npt.NDArray[Any]) -> yaml.Node:
    return dumper.represent_sequence(
        "tag:yaml.org,2002:seq", array.tolist(), flow_style=True
    )


def pydantic_model_abstraction_representer(
    dumper: yaml.Dumper, model: BaseModel
) -> yaml.Node:
    return dumper.represent_data(model.model_dump(mode="python"))


def enum_representer(dumper: yaml.Dumper, enum: Enum) -> yaml.Node:
    return dumper.represent_data(enum.value)


[docs] class YamlSettingsProvider(SettingsProvider): """For providing settings from yaml to signals.""" def __init__(self, directory: Path | str): self._directory = Path(directory) def _file_path(self, name: str) -> Path: return self._directory / (name + ".yaml")
[docs] async def store(self, name: str, data: dict[str, Any]): yaml.add_representer(np.ndarray, ndarray_representer, Dumper=yaml.Dumper) yaml.add_multi_representer( BaseModel, pydantic_model_abstraction_representer, Dumper=yaml.Dumper, ) yaml.add_multi_representer(Enum, enum_representer, Dumper=yaml.Dumper) with open(self._file_path(name), "w") as file: yaml.dump(data, file)
[docs] async def retrieve(self, name: str) -> dict[str, Any]: with open(self._file_path(name)) as file: data = yaml.full_load(file) if isinstance(data, list): warnings.warn( DeprecationWarning( "Found old save file. Re-save your yaml settings file " f"{self._file_path(name)} using " "ophyd_async.plan_stubs.store_settings" ), stacklevel=2, ) merge = {} for d in data: merge.update(d) return merge return data