Esempio n. 1
0
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)
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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)
Esempio n. 5
0
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)
Esempio n. 6
0
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)
Esempio n. 7
0
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)
Esempio n. 8
0
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)
Esempio n. 9
0
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
Esempio n. 10
0
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
Esempio n. 11
0
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)
Esempio n. 12
0
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)
Esempio n. 13
0
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)
Esempio n. 14
0
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)
Esempio n. 15
0
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
Esempio n. 16
0
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)