Source code for camacq.config

"""Handle the config file."""

from importlib import resources
import logging
import os
from pathlib import Path
from typing import Any

from ruamel.yaml import YAML, YAMLError

_LOGGER = logging.getLogger(__name__)

CONFIG_DIR_NAME = ".camacq"
YAML_CONFIG_FILE = "config.yml"
DEFAULT_CONFIG_TEMPLATE = "data/config.yml"


[docs] def get_default_config_dir() -> Path: """Get the default configuration directory based on OS. Returns ------- str Return the path to the configuration directory. """ data_dir = os.getenv("APPDATA") if os.name == "nt" else None return (Path(data_dir or Path.home()) / CONFIG_DIR_NAME).resolve()
[docs] def find_config_file(config_dir: Path) -> Path | None: """Find the configuration file in the configuration directory. Parameters ---------- config_dir : pathlib.Path The path to the configuration directory. Returns ------- pathlib.Path Return path to the configuration file if found, None if not found. """ config_path = config_dir / YAML_CONFIG_FILE return config_path if config_path.is_file() else None
[docs] def load_config_file(path: Path) -> dict[str, Any]: """Parse a YAML configuration file. Parameters ---------- path : pathlib.Path The path to the configuration YAML file. Returns ------- dict Return a dict with the configuration contents. """ yaml = YAML() try: with open(path, encoding="utf-8") as yml_file: cfg = yaml.load(yml_file) except YAMLError as exc: _LOGGER.error("Error reading YAML configuration file %s", path) raise YAMLError(exc) from exc if not isinstance(cfg, dict): _LOGGER.error( "The configuration file %s does not contain a dictionary", path.name, ) raise TypeError() return cfg
[docs] def create_default_config(config_dir: Path) -> Path | None: """Create a default config file in given configuration directory. Parameters ---------- config_dir : pathlib.Path The path to the configuration directory. Returns ------- pathlib.Path Return path to new configuration file if success, None if failed. """ config_path = config_dir / YAML_CONFIG_FILE default_config_template = resources.files(__package__) / DEFAULT_CONFIG_TEMPLATE data = load_config_file(Path(str(default_config_template))) yaml = YAML() try: with open(config_path, "w", encoding="utf-8") as config_file: yaml.dump(data, config_file) except OSError: _LOGGER.error("Unable to create default configuration file %s", config_path) return None return config_path
[docs] def ensure_config_exists(config_dir: Path) -> Path | None: """Ensure configuration file exists in the configuration directory. Create a default configuration file if needed. Parameters ---------- config_dir : pathlib.Path The path to the configuration directory. Returns ------- pathlib.Path Return path to the configuration file. """ config_path = find_config_file(config_dir) if config_path is None: print("Unable to find configuration. Creating default one in", config_dir) config_path = create_default_config(config_dir) return config_path