Metadata-Version: 2.0
Name: marshmallow-configparser
Version: 0.3.0
Summary: ConfigParser meets marshmallow
Home-page: https://github.com/tadamic/marshmallow_configparser
Author: Tomislav Adamic
Author-email: tomislav.adamic@gmail.com
License: MIT
Keywords: congiparser,marshmallow
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Dist: marshmallow
Provides-Extra: dev
Requires-Dist: bumpversion (>=0.5.3); extra == 'dev'
Requires-Dist: check-manifest (>=0.33.0); extra == 'dev'
Requires-Dist: colored-traceback (>=0.2.0); extra == 'dev'
Requires-Dist: coverage (>=4.2.0); extra == 'dev'
Requires-Dist: ipdb (>=0.10.0); extra == 'dev'
Requires-Dist: ipython (>=5.0.0); extra == 'dev'
Requires-Dist: isort; extra == 'dev'
Requires-Dist: jupyter (>=1.0.0); extra == 'dev'
Requires-Dist: mccabe (>=0.5.0); extra == 'dev'
Requires-Dist: pycodestyle (>=2.0.0); extra == 'dev'
Requires-Dist: pylint (>=1.6.0); extra == 'dev'
Requires-Dist: pytest (>=3.0.0); extra == 'dev'
Requires-Dist: pytest-colordots (>=0.1.0); extra == 'dev'
Requires-Dist: pytest-cov (>=2.3.0); extra == 'dev'
Requires-Dist: pytest-runner; extra == 'dev'
Requires-Dist: pytest-spec (>=1.0.0); extra == 'dev'
Requires-Dist: sphinx (>=1.4.0); extra == 'dev'
Requires-Dist: sphinx-rtd-theme (>=0.1.9); extra == 'dev'
Requires-Dist: yapf (>=0.11.0); extra == 'dev'

Overview
========



Ever wanted to load plain ``.ini`` config files and then validate loaded config?

Ever wanted to load config from multiple locations (``/etc/appconfig.con``, ``~/.appconfig.conf``) into single object and then validate that?

Worry no more!

Python's `ConfigParser`_ met `marshmallow`_ and now they get along just fine - without any JSON in sight to spoil the fun.


Installation
============

::

    pip install marshmallow_configparser


Example
=======

Having config file ``/tmp/example_config.conf`` looking like this:

.. code-block:: ini

    [Section1]
    option1 = mandatory string
    option2 = optional string
    option3 = 42
    option4 = 24

    [Section2]
    option1 = mandatory string
    option2 = optional string
    option3 = 42
    option4 = 24

And wanting to load it into our config object:

.. code-block:: python

    class ConfigObject(object):
        MANDATORY_STRING1 = None
        OPTIONAL_STRING1 = None
        MANDATORY_INTEGER1 = None
        OPTIONAL_INTEGER1 = None
        MANDATORY_STRING2 = None
        OPTIONAL_STRING2 = None
        MANDATORY_INTEGER2 = None
        OPTIONAL_INTEGER2 = None


We can define `marshmallow`_ schema:

.. code-block:: python

    from marshmallow.validate import Range

    from marshmallow_configparser import (ConfigBoolean, ConfigInteger,
                                          ConfigParserSchema, ConfigString,
                                          IsNotBlank)

    class ConfigSchema(ConfigParserSchema):
        class Meta:
            model = ConfigObject

        MANDATORY_STRING1 = ConfigString(
            section='Section1', load_from='option1', dump_to='option1',
            validate=[IsNotBlank()]
        )
        OPTIONAL_STRING1 = ConfigString(
            section='Section1', load_from='option2', dump_to='option2',
        )
        MANDATORY_INTEGER1 = ConfigInteger(
            section='Section1', load_from='option3', dump_to='option3',
            validate=[Range(min=24, max=42)]
        )
        OPTIONAL_INTEGER1 = ConfigInteger(
            section='Section1', load_from='option4', dump_to='option4',
        )

        MANDATORY_STRING2 = ConfigString(
            section='Section2', load_from='option1', dump_to='option1',
            validate=[IsNotBlank()]
        )
        OPTIONAL_STRING2 = ConfigString(
            section='Section2', load_from='option2', dump_to='option2',
        )
        MANDATORY_INTEGER2 = ConfigInteger(
            section='Section2', load_from='option3', dump_to='option3',
            validate=[Range(min=24, max=42)]
        )
        OPTIONAL_INTEGER2 = ConfigInteger(
            section='Section2', load_from='option4', dump_to='option4',
        )


Which can then load and validate our config:

.. code-block:: python

    schema = ConfigSchema()
    obj, errors = schema.load(['/tmp/example_config.conf'])

In the end we have:

.. code-block:: python

    obj.__dict_

    {'MANDATORY_INTEGER1': 42,
     'MANDATORY_INTEGER2': 42,
     'MANDATORY_STRING1': 'mandatory string',
     'MANDATORY_STRING2': 'mandatory string',
     'OPTIONAL_INTEGER1': 24,
     'OPTIONAL_INTEGER2': 24,
     'OPTIONAL_STRING1': 'optional string',
     'OPTIONAL_STRING2': 'optional string'}

Instead of using convenience classes like ``ConfigString``, there are also
classes in ``marshmallow_configparser.fields`` module that expose full `marshmallow`_ API. Check the docs for details.

Documentation
=============

http://marshmallow-configparser.readthedocs.io/en/latest/index.html


.. _marshmallow: https://github.com/marshmallow-code/marshmallow
.. _ConfigParser: https://docs.python.org/3/library/configparser.html#configparser.ConfigParser


Changelog
=========

unreleased
----------

0.3.0 (2017-05-08)
------------------

* config validation now fails if there is no config files to read from or they arre not readable.

0.2.0 (2017-05-02)
------------------

* Added convenience_fields module


0.1.0 (2017-04-30)
------------------

* First release on PyPI.


