def load(path_specs, ac_parser=None, ac_template=False, ac_context=None, **options): r""" Load single or multiple config files or multiple config files specified in given paths pattern. :param path_specs: Configuration file path or paths or its pattern such as r'/a/b/\*.json' or a list of files/file-like objects :param ac_parser: Forced parser type or parser object :param ac_template: Assume configuration file may be a template file and try to compile it AAR if True :param ac_context: A dict presents context to instantiate template :param options: Optional keyword arguments. See also the description of `options` in `multi_load` function. :return: dict or dict-like object supports merge operations """ marker = options.setdefault("ac_marker", options.get("marker", '*')) if is_path(path_specs) and marker in path_specs or _is_paths(path_specs): return multi_load(path_specs, ac_parser=ac_parser, ac_template=ac_template, ac_context=ac_context, **options) else: return single_load(path_specs, ac_parser=ac_parser, ac_template=ac_template, ac_context=ac_context, **options)
def single_load(path_or_stream, ac_parser=None, ac_template=False, ac_context=None, **options): """ Load single config file. :param path_or_stream: Configuration file path or file / file-like object :param ac_parser: Forced parser type or parser object :param ac_template: Assume configuration file may be a template file and try to compile it AAR if True :param ac_context: A dict presents context to instantiate template :param options: Optional keyword arguments such as: - Common options: - ac_namedtuple: Convert result to nested namedtuple object if True - ac_schema: JSON schema file path to validate given config file - Common backend options: - ignore_missing: Ignore and just return empty result if given file (``path_or_stream``) does not exist. - Backend specific options such as {"indent": 2} for JSON backend :return: dict or dict-like object supports merge operations """ is_path_ = is_path(path_or_stream) if is_path_: path_or_stream = anyconfig.utils.ensure_expandusr(path_or_stream) filepath = path_or_stream else: filepath = anyconfig.utils.get_path_from_stream(path_or_stream) psr = find_loader(path_or_stream, ac_parser, is_path_) if psr is None: return None schema = _load_schema(ac_template=ac_template, ac_context=ac_context, **options) options["ac_schema"] = None # It's not needed now. LOGGER.info("Loading: %s", filepath) if ac_template and filepath is not None: try: LOGGER.debug("Compiling: %s", filepath) content = anyconfig.template.render(filepath, ac_context) cnf = psr.loads(content, **options) return _maybe_validated(cnf, schema, **options) except Exception as exc: LOGGER.warning( "Failed to compile %s, fallback to no template " "mode, exc=%r", path_or_stream, exc) cnf = psr.load(path_or_stream, **options) return _maybe_validated(cnf, schema, **options)
def single_load(path_or_stream, ac_parser=None, ac_template=False, ac_context=None, **options): """ Load single config file. :param path_or_stream: Configuration file path or file / file-like object :param ac_parser: Forced parser type or parser object :param ac_template: Assume configuration file may be a template file and try to compile it AAR if True :param ac_context: A dict presents context to instantiate template :param options: Optional keyword arguments such as: - Common options: - ac_namedtuple: Convert result to nested namedtuple object if True - ac_schema: JSON schema file path to validate given config file - Common backend options: - ignore_missing: Ignore and just return empty result if given file (``path_or_stream``) does not exist. - Backend specific options such as {"indent": 2} for JSON backend :return: dict or dict-like object supports merge operations """ is_path_ = is_path(path_or_stream) if is_path_: path_or_stream = anyconfig.utils.ensure_expandusr(path_or_stream) filepath = path_or_stream else: filepath = anyconfig.utils.get_path_from_stream(path_or_stream) psr = find_loader(path_or_stream, ac_parser, is_path_) if psr is None: return None schema = _load_schema(ac_template=ac_template, ac_context=ac_context, **options) options["ac_schema"] = None # It's not needed now. LOGGER.info("Loading: %s", filepath) if ac_template and filepath is not None: try: LOGGER.debug("Compiling: %s", filepath) content = anyconfig.template.render(filepath, ac_context) cnf = psr.loads(content, **options) return _maybe_validated(cnf, schema, **options) except Exception as exc: LOGGER.warning("Failed to compile %s, fallback to no template " "mode, exc=%r", path_or_stream, exc) cnf = psr.load(path_or_stream, **options) return _maybe_validated(cnf, schema, **options)
def load(path_specs, ac_parser=None, ac_dict=None, ac_template=False, ac_context=None, **options): r""" Load single or multiple config files or multiple config files specified in given paths pattern. :param path_specs: Configuration file path or paths or its pattern such as r'/a/b/\*.json' or a list of files/file-like objects :param ac_parser: Forced parser type or parser object :param ac_dict: callable (function or class) to make mapping object will be returned as a result or None. If not given or ac_dict is None, default mapping object used to store resutls is dict or :class:`~collections.OrderedDict` if ac_ordered is True and selected backend can keep the order of items in mapping objects. :param ac_template: Assume configuration file may be a template file and try to compile it AAR if True :param ac_context: A dict presents context to instantiate template :param options: Optional keyword arguments. See also the description of `options` in :func:`multi_load` function. :return: Mapping object or any query result might be primitive objects """ marker = options.setdefault("ac_marker", options.get("marker", '*')) if is_path(path_specs) and marker in path_specs or _is_paths(path_specs): return multi_load(path_specs, ac_parser=ac_parser, ac_dict=ac_dict, ac_template=ac_template, ac_context=ac_context, **options) else: cnf = single_load(path_specs, ac_parser=ac_parser, ac_dict=ac_dict, ac_template=ac_template, ac_context=ac_context, **options) return anyconfig.query.query(cnf, **options)
def multi_load(paths, ac_parser=None, ac_template=False, ac_context=None, **options): """ Load multiple config files. .. note:: :func:`load` is a preferable alternative and this API should be used only if there is a need to emphasize given file paths are multiple ones. The first argument `paths` may be a list of config file paths or a glob pattern specifying that. That is, if a.yml, b.yml and c.yml are in the dir /etc/foo/conf.d/, the followings give same results:: multi_load(["/etc/foo/conf.d/a.yml", "/etc/foo/conf.d/b.yml", "/etc/foo/conf.d/c.yml", ]) multi_load("/etc/foo/conf.d/*.yml") :param paths: List of configuration file paths or a glob pattern to list of these paths, or a list of file or file-like objects :param ac_parser: Forced parser type or parser object :param ac_template: Assume configuration file may be a template file and try to compile it AAR if True :param ac_context: Mapping object presents context to instantiate template :param options: Optional keyword arguments: - Options common with :func:`multi_load` and :func:`load`: - ac_dict: callable (function or class) to make mapping object will be returned as a result or None. If not given or ac_dict is None, default mapping object used to store resutls is dict or :class:`~collections.OrderedDict` if ac_ordered is True and selected backend can keep the order of items in mapping objects. - ac_ordered: True if you want to keep resuls ordered. Please note that order of items may be lost depends on backend used. - ac_schema: JSON schema file path to validate given config file - ac_query: JMESPath expression to query data - ac_dict: callable (function or class) to make a dict or dict-like object, dict and OrderedDict for example - Options specific to this function and :func:`load`: - ac_merge (merge): Specify strategy of how to merge results loaded from multiple configuration files. See the doc of :mod:`anyconfig.dicts` for more details of strategies. The default is anyconfig.dicts.MS_DICTS. - ac_marker (marker): Globbing marker to detect paths patterns. - Common backend options: - ignore_missing: Ignore and just return empty result if given file (``path_or_stream``) does not exist. - Backend specific options such as {"indent": 2} for JSON backend :return: Mapping object or any query result might be primitive objects """ marker = options.setdefault("ac_marker", options.get("marker", '*')) schema = _maybe_schema(ac_template=ac_template, ac_context=ac_context, **options) options["ac_schema"] = None # Avoid to load schema more than twice. paths = anyconfig.utils.norm_paths(paths, marker=marker) if anyconfig.utils.are_same_file_types(paths): ac_parser = find_loader(paths[0], ac_parser, is_path(paths[0])) cnf = ac_context for path in paths: opts = options.copy() cups = single_load(path, ac_parser=ac_parser, ac_template=ac_template, ac_context=cnf, **opts) if cups: if cnf is None: cnf = cups else: merge(cnf, cups, **options) if cnf is None: return anyconfig.dicts.convert_to({}, **options) cnf = _maybe_validated(cnf, schema, **options) return anyconfig.query.query(cnf, **options)
def single_load(path_or_stream, ac_parser=None, ac_template=False, ac_context=None, **options): """ Load single configuration file. .. note:: :func:`load` is a preferable alternative and this API should be used only if there is a need to emphasize given file path is single one. :param path_or_stream: Configuration file path or file or file-like object :param ac_parser: Forced parser type or parser object itself :param ac_template: Assume configuration file may be a template file and try to compile it AAR if True :param ac_context: A dict presents context to instantiate template :param options: Optional keyword arguments such as: - Options common with :func:`multi_load` and :func:`load`: - ac_dict: callable (function or class) to make mapping object will be returned as a result or None. If not given or ac_dict is None, default mapping object used to store resutls is dict or :class:`~collections.OrderedDict` if ac_ordered is True and selected backend can keep the order of items in mapping objects. - ac_ordered: True if you want to keep resuls ordered. Please note that order of items may be lost depends on backend used. - ac_schema: JSON schema file path to validate given config file - ac_query: JMESPath expression to query data - Common backend options: - ignore_missing: Ignore and just return empty result if given file (``path_or_stream``) does not exist. - Backend specific options such as {"indent": 2} for JSON backend :return: Mapping object """ is_path_ = is_path(path_or_stream) if is_path_: filepath = path_or_stream = anyconfig.utils.normpath(path_or_stream) else: filepath = anyconfig.utils.get_path_from_stream(path_or_stream) psr = find_loader(path_or_stream, ac_parser, is_path_) schema = _maybe_schema(ac_template=ac_template, ac_context=ac_context, **options) LOGGER.info("Loading: %s", filepath) if ac_template and filepath is not None: content = anyconfig.template.try_render(filepath=filepath, ctx=ac_context) if content is not None: cnf = psr.loads(content, **options) return _maybe_validated(cnf, schema, **options) cnf = psr.load(path_or_stream, **options) return _maybe_validated(cnf, schema, **options)
def multi_load(paths, ac_parser=None, ac_template=False, ac_context=None, **options): """ Load multiple config files. The first argument `paths` may be a list of config file paths or a glob pattern specifying that. That is, if a.yml, b.yml and c.yml are in the dir /etc/foo/conf.d/, the followings give same results:: multi_load(["/etc/foo/conf.d/a.yml", "/etc/foo/conf.d/b.yml", "/etc/foo/conf.d/c.yml", ]) multi_load("/etc/foo/conf.d/*.yml") :param paths: List of config file paths or a glob pattern to list paths, or a list of file/file-like objects :param ac_parser: Forced parser type or parser object :param ac_template: Assume configuration file may be a template file and try to compile it AAR if True :param ac_context: A dict presents context to instantiate template :param options: Optional keyword arguments: - Common options: - ac_merge (merge): Specify strategy of how to merge results loaded from multiple configuration files. See the doc of :mod:`m9dicts` for more details of strategies. The default is m9dicts.MS_DICTS. - ac_marker (marker): Globbing marker to detect paths patterns. - ac_namedtuple: Convert result to nested namedtuple object if True - ac_schema: JSON schema file path to validate given config file - Common backend options: - ignore_missing: Ignore and just return empty result if given file (``path_or_stream``) does not exist. - Backend specific options such as {"indent": 2} for JSON backend :return: dict or dict-like object supports merge operations """ marker = options.setdefault("ac_marker", options.get("marker", '*')) schema = _load_schema(ac_template=ac_template, ac_context=ac_context, **options) options["ac_schema"] = None # It's not needed now. cnf = to_container(ac_context, **options) same_type = anyconfig.utils.are_same_file_types(paths) if is_path(paths) and marker in paths: paths = anyconfig.utils.sglob(paths) for path in paths: opts = options.copy() opts["ac_namedtuple"] = False # Disabled within this loop. # Nested patterns like ['*.yml', '/a/b/c.yml']. if is_path(path) and marker in path: cups = multi_load(path, ac_parser=ac_parser, ac_template=ac_template, ac_context=cnf, **opts) else: if same_type: ac_parser = find_loader(path, ac_parser, is_path(path)) cups = single_load(path, ac_parser=ac_parser, ac_template=ac_template, ac_context=cnf, **opts) if cups: cnf.update(cups) return _maybe_validated(cnf, schema, **options)