Source code for pycloudlib.config

"""Deal with configuration file."""

import logging
import os
from io import StringIO
from pathlib import Path
from typing import Any, MutableMapping, Optional, Union

import toml

# Order matters here. Local should take precedence over global.
CONFIG_PATHS = [
    Path("~/.config/pycloudlib.toml").expanduser(),
    Path("/etc/pycloudlib.toml"),
]

ConfigFile = Union[Path, StringIO]
log = logging.getLogger(__name__)


[docs] class Config(dict): """Override dict to allow raising a more meaningful KeyError.""" def __getitem__(self, key): """Provide more meaningful KeyError on access.""" try: return super().__getitem__(key) except KeyError: raise KeyError(f"{key} must be defined in pycloudlib.toml to make this call") from None
[docs] def parse_config( config_file: Optional[ConfigFile] = None, ) -> MutableMapping[str, Any]: """Find the relevant TOML, load, and return it.""" possible_configs = [] if config_file: possible_configs.append(config_file) if os.environ.get("PYCLOUDLIB_CONFIG"): possible_configs.append(Path(os.environ["PYCLOUDLIB_CONFIG"])) possible_configs.extend(CONFIG_PATHS) for path in possible_configs: try: config = toml.load(path, _dict=Config) log.debug("Loaded configuration from %s", path) return config except FileNotFoundError: continue except toml.TomlDecodeError as e: raise ValueError(f"Could not parse configuration file pointed to by {path}") from e raise ValueError( "No configuration file found! Copy pycloudlib.toml.template to " "~/.config/pycloudlib.toml or /etc/pycloudlib.toml" )