import os from pathlib import Path from typing import IO, Optional, Union import pydantic from ruamel import yaml class DatabaseConfiguration(pydantic.BaseModel): '''Database configuration''' url: str = 'sqlite:///lycodon.db' '''Database connection URL''' class Configuration(pydantic.BaseModel): '''Application configuration''' database: DatabaseConfiguration = DatabaseConfiguration() '''Database configuration''' @classmethod def load(cls, path: Optional[Union[Path, str]] = None) -> 'Configuration': '''Load configuration from the specified file :param path: Path to the configuration file ''' if path is None: path = Path(os.environ.get('LYCODON_CONFIG', 'config.yml')) elif not isinstance(path, Path): path = Path(path) with path.open('r', encoding='utf-8') as f: return cls.from_file(f) @classmethod def from_file(cls, f: IO[str]) -> 'Configuration': '''Load configuration from an open file buffer :param f: Open readable file object ''' values = yaml.safe_load(f) or {} return cls.parse_obj(values)