Source code for id_translation.toml.meta._metaconf
import logging
from dataclasses import asdict, dataclass, field
from typing import Any, Self
from rics.paths import AnyPath, any_path_to_path
from .._load_toml import load_toml_file
LOGGER = logging.getLogger(__package__).getChild("Translator").getChild("config")
[docs]
@dataclass(frozen=True)
class EnvConf:
"""Control environment-variable interpolation.
All keys are forwarded to :func:`.load_toml_file`.
"""
allow_interpolation: bool = True
allow_blank: bool = False
allow_nested: bool = False
[docs]
@classmethod
def from_dict(cls, config: dict[str, bool]) -> Self:
"""Construct environment interpolation configuration object from a dict.
Args:
config: Dict representation of a ``EnvConf`` to consume.
Returns:
A new ``EnvConf`` instance.
"""
return cls(**config)
[docs]
@dataclass(frozen=True)
class EquivalenceConf:
"""Determines how equivalence between configuration files is determined."""
python_version: str = "{v.major}.{v.minor}.{v.micro}"
"""Used to format the ``'python_version'`` version using ``v=sys.version_info``."""
extra_packages: list[str] = field(default_factory=list)
"""Additional package whose versions are used to determine :class:`ConfigMetadata` equivalence."""
[docs]
@classmethod
def from_dict(cls, config: dict[str, Any]) -> Self:
"""Construct equivalence configuration object from a dict.
Args:
config: Dict representation of an ``EquivalenceConf`` to consume.
Returns:
A new ``EquivalenceConf`` instance.
"""
extra_packages = config.pop("extra_packages", [])
return cls(**config, extra_packages=[*extra_packages])
[docs]
@dataclass(frozen=True)
class Metaconf:
"""Python representation of ``metaconf.toml`` file.
The ``metaconf.toml`` file always lives next to the main configuration file. It determines how other configuration
files are read and validated.
.. code-block:: toml
[env]
allow_interpolation = true
allow_nested = true
allow_blank = false
[equivalence]
# python_version = "{v.major}.{v.minor}" # Uncomment to allow any patch version
extra_packages = ["bci-id-translation"]
The sample above comes from the https://github.com/rsundqvist/id-translation-project/tree/master/demo/bci-id-translation demo.
"""
env: EnvConf = field(default_factory=EnvConf)
"""Controls how and if variable substitution (on the form ``${VAR}``) is performed. See :class:`EnvConf`. """
equivalence: EquivalenceConf = field(default_factory=EquivalenceConf)
"""Controls how equivalence checks are performed. See :class:`EquivalenceConf`."""
[docs]
@classmethod
def from_dict(cls, config: dict[str, Any]) -> Self:
"""Construct meta configuration object from a dict.
Args:
config: Dict representation of a ``Metaconf`` to consume.
Returns:
A new ``Metaconf`` instance.
"""
env = config.pop("env", {})
equivalence = config.pop("equivalence", {})
if config:
raise TypeError(f"Unknown keys: {sorted(config)}")
return cls(
env=EnvConf.from_dict(env),
equivalence=EquivalenceConf.from_dict(equivalence),
)
[docs]
@classmethod
def from_path_or_default(cls, path: AnyPath) -> Self:
"""Read TOML configuration or return default configuration."""
path = any_path_to_path(path)
config = load_toml_file(path) if path.exists() else {}
return cls.from_dict(config)
[docs]
def as_dict(self) -> dict[str, Any]:
"""Return a dict representation of `self`."""
return asdict(self)