Beispiel #1
0
    def load_config(cls, config_file: str) -> None:
        """
        Loads the log's configuration.
        Args:
            config_file (str): Path of the yaml config file for logging lib.

        Returns:
            None:
        """
        config_processor = ConfigProcessor()

        path = config_file
        filters = ()  # can choose to output only specific keys
        exclude_keys = ()  # can choose to remove specific keys
        output_format = "json"  # yaml/json

        ordered_config_dict = config_processor.process(
            path=path,
            filters=filters,
            exclude_keys=exclude_keys,
            output_format=output_format,
            print_data=False)
        logging.config.dictConfig(dict(ordered_config_dict))

        cls.logger = logging.getLogger()
Beispiel #2
0
    def load_config(self) -> dict:
        """
        Loads the configuration from a yaml file into a dictionary.
        Returns:
            dict: All configuration loaded from a yaml file.
        """

        try:

            config_processor = ConfigProcessor()

            path = self.filename
            filters = ()  # can choose to output only specific keys
            exclude_keys = ()  # can choose to remove specific keys
            output_format = "json"  # yaml/json

            ordered_config_dict = config_processor.process(
                path=path,
                filters=filters,
                exclude_keys=exclude_keys,
                output_format=output_format,
                print_data=False)

            cfg = dict(ordered_config_dict)
            if not isinstance(cfg, dict):
                raise AssertionError("Invalid format of the config file.")
            return cfg
        except Exception as exc:
            Logger.critical(
                f"Hum, this {self.getfile} file smells awful. Check it out. {exc} I can't "
                f"continue.")
            raise
Beispiel #3
0
    def __init__(self, config_uri: str):
        """
        Default constructor.

        :param config_uri:
            RFC-3986 Uniform Resource Identifier (URI)
        """
        self._log = logger.get_logger(self.__class__.__name__)
        self.yaml = ConfigProcessor()
        self.settings = {}
        self._load_configuration(config_uri)
Beispiel #4
0
def load_yaml(setups_path):
    config_processor = ConfigProcessor()
    tree = config_processor.process(path=setups_path,
                                    filters=(),
                                    exclude_keys=(),
                                    output_format="yaml",
                                    print_data=False)

    # use the simple yaml to read without interpolation
    psg_exp_file = os.path.join(setups_path, "experiments.yaml")
    stream = open(psg_exp_file, 'r')
    tree_nointerp = load(stream, Loader=Loader)
    return tree, tree_nointerp
Beispiel #5
0
def load_config(env: str = "dev") -> Dict:
    processor = ConfigProcessor()
    config_path = get_config_path(env)
    config = processor.process(path=config_path)

    config["logging"]["level"] = environ.get(
        "LOGGING_LEVEL", config["logging"]["level"]
    )
    config["logging"]["filename"] = environ.get(
        "LOGGING_FILENAME", config["logging"]["filename"]
    )
    config["redis"]["host"] = environ.get("REDIS_HOST", config["redis"]["host"])
    config["redis"]["port"] = int(environ.get("REDIS_PORT", config["redis"]["port"]))

    return config
Beispiel #6
0
class YamlConfigHandler(IConfigurationHandler):
    """
    YAML file based configuration handler implementation.
    """

    # protected members

    _log: Logger = None

    # public member functions

    def __init__(self, config_uri: str):
        """
        Default constructor.

        :param config_uri:
            RFC-3986 Uniform Resource Identifier (URI)
        """
        self._log = logger.get_logger(self.__class__.__name__)
        self.yaml = ConfigProcessor()
        self.settings = {}
        self._load_configuration(config_uri)

    @overrides
    def get_config_property(
            self, property_descriptor: ConfigurationProperty, expected_type: Type[Property]) -> Property:
        """
        Returns the config value of the specified property with the given type.

        :param property_descriptor:
            the descriptor of the wanted property
        :param expected_type:
            expected return type
        :return:
            the configured value of the setting, or the default value if not present
        """
        if not property_descriptor:
            self._log.error(PROPERTY_ERROR_MSG)
            raise ValueError
        item = self._recursive_search(property_descriptor, self.settings)
        # if no hit at all, then default value
        if item is None:
            return property_descriptor.default_value
        return item

    # protected member functions

    def _load_configuration(self, uri: str) -> None:
        """
        Loads in the configuration from the specified file resource.

        #see `adobe himl` package for more information:
        https://github.com/adobe/himl

        :param uri:
            RFC-3986 Uniform Resource Identifier (URI)
        """
        if not uritools.isuri(uri):
            raise ValueError(URI_ERROR_MSG)
        uri_tuple = uritools.urisplit(uri)
        yaml_file = uri_tuple[2][1:]
        try:
            self.settings = dict(self.yaml.process(path=yaml_file, output_format="yaml", print_data=True))
        except OSError:
            self._log.critical(OS_ERROR_MSG, yaml_file, exc_info=True)
            sys.exit()

    def _recursive_search(self, property_descriptor: ConfigurationProperty, property_settings: dict) -> object:
        """
        Search a key recursively in the given dict. Currently the recursion is only works for dict nested types.
        Early "None" returns are covered by the code. Nested Lists are treated as enums or evaluated as tuples.

        :param property_descriptor:
            descriptor of the property
        :param property_settings:
            dict where we want to search for the property
        :return:
            type casted value, or None
        """
        # hit
        if property_descriptor.label in property_settings:
            item = property_settings[property_descriptor.label]
            if isinstance(item, list):  # yaml parser making lists from enums
                typed_list = []
                if issubclass(property_descriptor.prop_type, tuple):
                    [typed_list.append(eval(x)) for x in item]
                else:
                    try:
                        # if not tuple, then we assuming an enum type
                        [typed_list.append(getattr(property_descriptor.prop_type, x)) for x in item]
                    except (AttributeError, TypeError):
                        if DEV_LOG:
                            self._log.debug(ATTRIBUTE_ERROR_MSG, item, property_descriptor.prop_type)
                return typed_list
            try:
                # trying to resolve as a simple enum type
                return getattr(property_descriptor.prop_type, item)
            except (AttributeError, TypeError):
                if DEV_LOG:
                    self._log.debug(ATTRIBUTE_ERROR_MSG, item, property_descriptor.prop_type)
            try:
                # trying to dynamic cast
                return property_descriptor.prop_type(item)
            except (TypeError, ValueError):
                self._log.error(DYNAMIC_CAST_ERROR_MSG, property_descriptor.label, property_descriptor.prop_type,
                                exc_info=True)
                return property_descriptor.default_value
        # no hit, then recursion (if nested structure is exists)
        for key, value in property_settings.items():
            if isinstance(value, dict):  # nested types are usually dicts
                item = self._recursive_search(property_descriptor, value)
                # covering early None returns
                if item is not None:
                    return item