import logging from pathlib import Path from pprint import pformat from typing import Dict from typing import Optional from dependency_injector import containers from dependency_injector import providers from serial import Serial from .util import log_function_call DEFAULTS_DIR = Path(__file__).parent / "defaults" CONFIG_FILE = DEFAULTS_DIR / "config.yml" _logger = logging.getLogger(__name__) class Container(containers.DeclarativeContainer): config = providers.Configuration("config") serial = providers.Factory( Serial, port=config.device_id.required(), baudrate=config.baudrate.required(), ) @log_function_call def get_initialize_container( config: Optional[Dict] = None, config_file: Optional[Path] = None, ) -> Container: logger = _logger.getChild("initialize_container") logger.debug("initialize container...") container = Container() logger.debug(f"initialize container from config file: {CONFIG_FILE}") container.config.from_yaml(CONFIG_FILE, required=True) user_config = Path.cwd() / "config.yml" if user_config.is_file(): logger.debug(f"initialize container from user config file: {user_config}") container.config.from_yaml(user_config, required=True) if config is not None: logger.debug(f"initialize container with config: {config}") container.config.from_dict(config) if config_file is not None: logger.debug(f"initialize container from config file: {config_file}") container.config.from_yaml(config_file) logger.debug(f"container config:\n{pformat(container.config())}") return container