Beispiel #1
0
def loads(content,
          ac_parser=None,
          ac_dict=None,
          ac_template=False,
          ac_context=None,
          **options):
    """
    :param content: Configuration file's content (a string)
    :param ac_parser: Forced parser type or ID 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: Context dict to instantiate template
    :param options:
        Optional keyword arguments. See also the description of `options` in
        :func:`single_load` function.

    :return: Mapping object or any query result might be primitive objects
    :raises: ValueError, UnknownProcessorTypeError
    """
    if ac_parser is None:
        LOGGER.warning("ac_parser was not given but it's must to find correct "
                       "parser to load configurations from string.")
        return None

    psr = Parsers().find_by_type_or_id(ac_parser)
    schema = None
    ac_schema = options.get("ac_schema", None)
    if ac_schema is not None:
        options["ac_schema"] = None
        schema = loads(ac_schema,
                       ac_parser=psr,
                       ac_dict=ac_dict,
                       ac_template=ac_template,
                       ac_context=ac_context,
                       **options)

    if ac_template:
        compiled = anyconfig.template.try_render(content=content,
                                                 ctx=ac_context,
                                                 **options)
        if compiled is not None:
            content = compiled

    cnf = psr.loads(content, ac_dict=ac_dict, **options)
    cnf = _try_validate(cnf, schema, **options)
    return anyconfig.query.query(cnf, **options)
Beispiel #2
0
def dumps(data, ac_parser=None, **options):
    """
    Return string representation of `data` in forced type format.

    :param data: Config data object to dump
    :param ac_parser: Forced parser type or parser object
    :param options: see :func:`dump`

    :return: Backend-specific string representation for the given data
    :raises: ValueError, UnknownProcessorTypeError
    """
    psr = Parsers().find_by_type(ac_parser)
    return psr.dumps(data, **options)
Beispiel #3
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_, forced_type=ac_parser)
    psr = Parsers().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)
Beispiel #4
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, UnknownProcessorTypeError, UnknownFileTypeError
    """
    ioi = anyconfig.ioinfo.make(out, forced_type=ac_parser)
    psr = Parsers().find(ioi, forced_type=ac_parser)
    LOGGER.info("Dumping: %s", ioi.path)
    psr.dump(data, ioi, **options)
Beispiel #5
0
def find(obj=None, forced_type=None):
    """
    This function is very similar to the above :func:`find` but returns a
    parser objects instead of a list of parser objects.

    :param obj:
        a file path, file or file-like object, pathlib.Path object, an
        'anyconfig.globals.IOInfo' (namedtuple) object, or None
    :param forced_type:
        Forced configuration parser type or parser object itself
    :return:
        An instance of processor class of highest priority to process 'obj'
    :raises: ValueError, UnknownProcessorTypeError, UnknownFileTypeError
    """
    return Parsers().find(obj, forced_type=forced_type)
Beispiel #6
0
def findall(obj=None, forced_type=None):
    """
    Find out parser objects can load and/or dump data from given 'obj' which
    may be a file path, file or file-like object, pathlib.Path object or an
    'anyconfig.globals.IOInfo' (namedtuple) object.

    :param obj:
        a file path, file or file-like object, pathlib.Path object, an
        'anyconfig.globals.IOInfo' (namedtuple) object, or None
    :param forced_type:
        Forced configuration parser type or parser object itself
    :return: A list of instances of processor classes to process 'obj'
    :raises: ValueError, UnknownProcessorTypeError, UnknownFileTypeError
    """
    return Parsers().findall(obj, forced_type=forced_type)
Beispiel #7
0
def open(path, mode=None, ac_parser=None, **options):
    """
    Open given configuration file with appropriate open flag.

    :param path: Configuration file path
    :param mode:
        Can be 'r' and 'rb' for reading (default) or 'w', 'wb' for writing.
        Please note that even if you specify 'r' or 'w', it will be changed to
        'rb' or 'wb' if selected backend, xml and configobj for example, for
        given config file prefer that.
    :param options:
        Optional keyword arguments passed to the internal file opening APIs of
        each backends such like 'buffering' optional parameter passed to
        builtin 'open' function.

    :return: A file object or None on any errors
    :raises: ValueError, UnknownProcessorTypeError, UnknownFileTypeError
    """
    psr = Parsers().find(path, forced_type=ac_parser)

    if mode is not None and mode.startswith('w'):
        return psr.wopen(path, **options)

    return psr.ropen(path, **options)
Beispiel #8
0
def find_loader(path, parser_or_type=None):
    """
    Find out parser object appropriate to load configuration from a file of
    given path or file or file-like object.

    :param path:
        Configuration file path or file or file-like object or pathlib.Path
        object if it's available
    :param parser_or_type:
        Forced configuration parser type or parser object itself

    :return:
        An instance of a class inherits :class:`~anyconfig.backend.base.Parser`
        or None
    """
    try:
        return Parsers().find(path, forced_type=parser_or_type)
    except (ValueError, UnknownProcessorTypeError, UnknownFileTypeError):
        raise
Beispiel #9
0
def list_by_extension():
    """
    List supported parser by file extension supported, [(extension,
    [Parser_class])].
    """
    return Parsers().list_by_x("extensions")
Beispiel #10
0
def list_by_type():
    """List supported parser by types, [(type, [Parser_class])].
    """
    return Parsers().list_by_x("type")
Beispiel #11
0
def list_by_cid():
    """List supported parsers, [(cid, [Parser_class])].
    """
    return Parsers().list_by_x("cid")
Beispiel #12
0
def list_types():
    """List supported parser types.
    """
    return sorted(Parsers().list_x("type"))
Beispiel #13
0
def load_plugins():
    """[Re-]Load pluggable parsers.
    """
    Parsers().load_plugins()
Beispiel #14
0
def list_types():
    return Parsers().list_types()
Beispiel #15
0
def multi_load(inputs, ac_parser=None, ac_template=False, ac_context=None,
               **options):
    r"""
    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 inputs are multiple ones.

    The first argument `inputs` may be a list of a file paths or a glob pattern
    specifying them or a pathlib.Path object represents file[s] or a namedtuple
    `~anyconfig.globals.IOInfo` object represents some inputs to load some data
    from.

    About glob patterns, for example, 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 inputs:
        A list of file path or a glob pattern such as r'/a/b/\*.json'to list of
        files, file or file-like object or pathlib.Path object represents the
        file or a namedtuple `~anyconfig.globals.IOInfo` object represents some
        inputs to load some data from
    :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:

        - ac_dict, ac_ordered, ac_schema and ac_query are the options common in
          :func:`single_load`, :func:`multi_load`, :func:`load`: and
          :func:`loads`. See the descriptions of them in :func:`single_load`.

        - 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`` does not exist.

        - Backend specific options such as {"indent": 2} for JSON backend

    :return: Mapping object or any query result might be primitive objects
    :raises: ValueError, UnknownProcessorTypeError, UnknownFileTypeError
    """
    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.expand_paths(inputs, marker=marker)
    if anyconfig.utils.are_same_file_types(paths):
        ac_parser = Parsers().find(paths[0], forced_type=ac_parser)

    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 = _try_validate(cnf, schema, **options)
    return anyconfig.query.query(cnf, **options)