from __future__ import annotations import dataclasses import os.path import typing import yaml _cached_config: typing.Optional[Config] = None @dataclasses.dataclass class Config: controllers: typing.List[str] server_names: typing.List[str] comm_secret: str cookie_secret: str venue_info_url: typing.Optional[str] session_timeout: int # in seconds debug: bool @staticmethod def load_default_once() -> Config: global _cached_config if not _cached_config: _cached_config = Config.load() return _cached_config @staticmethod def load(filename: typing.Optional[str]=None) -> Config: if filename is None: for name in ('capport.yaml', '/etc/capport.yaml'): if os.path.exists(name): return Config.load(name) raise RuntimeError("Missing config file") with open(filename) as f: data = yaml.safe_load(f) controllers = list(map(str, data['controllers'])) return Config( controllers=controllers, server_names=data.get('server-names', []), comm_secret=str(data.get('comm-secret', None) or data['secret']), cookie_secret=str(data['cookie-secret']), venue_info_url=str(data.get('venue-info-url')), session_timeout=data.get('session-timeout', 3600), debug=data.get('debug', False) )