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 dump(data, config_path, forced_type=None, **kwargs): """ Save `data` as `config_path`. :param data: Config data object to dump :: anyconfig.mergeabledict.MergeableDict by default :param config_path: Output filename :param forced_type: Forced configuration parser type :param kwargs: Backend specific optional arguments, e.g. {"indent": 2} for JSON loader/dumper backend """ dumper = _find_dumper(config_path, forced_type) LOGGER.info("Dumping: %s", config_path) dumper.dump(data, config_path, **kwargs)
def dump(data, path_or_stream, ac_parser=None, **options): """ Save `data` as `path_or_stream`. :param data: A mapping object may have configurations data to dump :param path_or_stream: Output file path or file / file-like object :param ac_parser: Forced parser type or parser object :param options: Backend specific optional arguments, e.g. {"indent": 2} for JSON loader/dumper backend """ dumper = _find_dumper(path_or_stream, ac_parser) LOGGER.info("Dumping: %s", anyconfig.utils.get_path_from_stream(path_or_stream)) dumper.dump(data, path_or_stream, **options)
def dump(data, path_or_stream, ac_parser=None, **options): """ Save `data` as `path_or_stream`. :param data: Config data object (dict[-like] or namedtuple) to dump :param path_or_stream: Output file path or file / file-like object :param ac_parser: Forced parser type or parser object :param options: Backend specific optional arguments, e.g. {"indent": 2} for JSON loader/dumper backend """ dumper = _find_dumper(path_or_stream, ac_parser) LOGGER.info("Dumping: %s", anyconfig.utils.get_path_from_stream(path_or_stream)) if anyconfig.mdicts.is_namedtuple(data): data = to_container(data, **options) # namedtuple -> dict-like dumper.dump(data, path_or_stream, **options)
def _single_load(input_, ac_parser=None, ac_template=False, ac_context=None, **options): """ :param input_: File path or file or file-like object or pathlib.Path object represents the file or a namedtuple 'anyconfig.globals.IOInfo' object represents some input to load some data from :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 :func:`single_load` supports except for ac_schema and ac_query :return: Mapping object :raises: ValueError, UnknownProcessorTypeError, UnknownFileTypeError """ ioi = anyconfig.ioinfo.make(input_) psr = find(ioi, forced_type=ac_parser) filepath = ioi.path # .. note:: # This will be kept for backward compatibility until 'ignore_missing' # option is deprecated and removed completely. if "ignore_missing" in options: warnings.warn( "keyword option 'ignore_missing' is deprecated, use " "'ac_ignore_missing' instead", DeprecationWarning) options["ac_ignore_missing"] = options["ignore_missing"] LOGGER.info("Loading: %s", filepath) if ac_template and filepath is not None: content = anyconfig.template.try_render(filepath=filepath, ctx=ac_context, **options) if content is not None: return psr.loads(content, **options) return psr.load(ioi, **options)
def dump(data, out, ac_parser=None, **options): """ Save `data` to `out`. :param data: A mapping object may have configurations data to dump :param out: An output file path or a file or a file-like object or a `pathlib.Path` object represents the file or a namedtuple `~anyconfig.globals.IOInfo` object represents output to dump some data to. :param ac_parser: Forced parser type or parser object :param options: Backend specific optional arguments, e.g. {"indent": 2} for JSON loader/dumper backend :raises: ValueError, UnknownParserTypeError, UnknownFileTypeError """ ioi = anyconfig.backends.inspect_io_obj(out, forced_type=ac_parser) LOGGER.info("Dumping: %s", ioi.path) ioi.processor.dump(data, ioi, **options)
def _maybe_schema(**options): """ :param options: Optional keyword arguments such as - ac_template: Assume configuration file may be a template file and try to compile it AAR if True - ac_context: Mapping object presents context to instantiate template - ac_schema: JSON schema file path to validate configuration files """ ac_schema = options.get("ac_schema", None) if ac_schema is not None: # Try to detect the appropriate as it may be different from the # original config file's format, perhaps. options["ac_parser"] = None options["ac_schema"] = None # Avoid infinite loop. LOGGER.info("Loading schema: %s", ac_schema) return load(ac_schema, **options) return None
def _load_schema(**options): """ :param options: Optional keyword arguments such as - ac_template: Assume configuration file may be a template file and try to compile it AAR if True - ac_context: A dict presents context to instantiate template - ac_schema: JSON schema file path to validate given config file """ ac_schema = options.get("ac_schema", None) if ac_schema is not None: # Try to detect the appropriate as it may be different from the # original config file's format, perhaps. options["ac_parser"] = None options["ac_schema"] = None # Avoid infinite loop. LOGGER.info("Loading schema: %s", ac_schema) return load(ac_schema, **options) return None
def dump(data, path_or_stream, forced_type=None, **kwargs): """ Save `data` as `path_or_stream`. :param data: Config data object to dump :: anyconfig.mergeabledict.MergeableDict by default :param path_or_stream: Output file path or file / file-like object :param forced_type: Forced configuration parser type :param kwargs: Backend specific optional arguments, e.g. {"indent": 2} for JSON loader/dumper backend """ dumper = _find_dumper(path_or_stream, forced_type) if _is_path(path_or_stream): LOGGER.info("Dumping: %s", path_or_stream) else: LOGGER.info("Dumping: %s", get_path_from_stream(path_or_stream)) dumper.dump(data, path_or_stream, **kwargs)
def dump(data, out, ac_parser=None, **options): """ Save 'data' to 'out'. :param data: A mapping object may have configurations data to dump :param out: An output file path, a file, a file-like object, :class:`pathlib.Path` object represents the file or a namedtuple 'anyconfig.globals.IOInfo' object represents output to dump some data to. :param ac_parser: Forced parser type or parser object :param options: Backend specific optional arguments, e.g. {"indent": 2} for JSON loader/dumper backend :raises: ValueError, UnknownProcessorTypeError, UnknownFileTypeError """ ioi = anyconfig.ioinfo.make(out) psr = find(ioi, forced_type=ac_parser) LOGGER.info("Dumping: %s", ioi.path) psr.dump(data, ioi, **options)
def _single_load(input_, ac_parser=None, ac_template=False, ac_context=None, **options): """ :param input_: File path or file or file-like object or pathlib.Path object represents the file or a namedtuple 'anyconfig.globals.IOInfo' object represents some input to load some data from :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 :func:`single_load` supports except for ac_schema and ac_query :return: Mapping object :raises: ValueError, UnknownProcessorTypeError, UnknownFileTypeError """ ioi = anyconfig.ioinfo.make(input_) psr = find(ioi, forced_type=ac_parser) filepath = ioi.path # .. note:: # This will be kept for backward compatibility until 'ignore_missing' # option is deprecated and removed completely. if "ignore_missing" in options: warnings.warn("keyword option 'ignore_missing' is deprecated, use " "'ac_ignore_missing' instead", DeprecationWarning) options["ac_ignore_missing"] = options["ignore_missing"] LOGGER.info("Loading: %s", filepath) if ac_template and filepath is not None: content = anyconfig.template.try_render(filepath=filepath, ctx=ac_context, **options) if content is not None: return psr.loads(content, **options) return psr.load(ioi, **options)
def single_load( config_path, forced_type=None, ignore_missing=False, ac_template=False, ac_context=None, ac_schema=None, **kwargs ): """ Load single config file. :param config_path: Configuration file path :param forced_type: Forced configuration parser type :param ignore_missing: Ignore and just return empty result if given file (``config_path``) does not exist :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 ac_schema: JSON schema file path to validate given config file :param kwargs: Backend specific optional arguments, e.g. {"indent": 2} for JSON loader/dumper backend :return: Dict-like object (instance of anyconfig.mergeabledict.MergeableDict by default) supports merge operations. """ config_path = anyconfig.utils.ensure_expandusr(config_path) cparser = find_loader(config_path, forced_type) if cparser is None: return None if ac_schema is not None: kwargs["ac_schema"] = None # Avoid infinit loop format_checker = kwargs.get("format_checker", None) LOGGER.info("Loading schema: %s", ac_schema) schema = load( ac_schema, forced_type=forced_type, ignore_missing=ignore_missing, ac_template=ac_template, ac_context=ac_context, **kwargs ) LOGGER.info("Loading: %s", config_path) if ac_template: try: LOGGER.debug("Compiling: %s", config_path) config_content = anyconfig.template.render(config_path, ac_context) config = cparser.loads(config_content, ignore_missing=ignore_missing, **kwargs) if ac_schema is not None: if not _validate(config, schema, format_checker): return None return config except Exception as exc: LOGGER.debug("Exc=%s", str(exc)) LOGGER.warn("Failed to compile %s, fallback to no template " "mode", config_path) config = cparser.load(config_path, ignore_missing=ignore_missing, **kwargs) if ac_schema is not None: if not _validate(config, schema, format_checker): return None return config
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)