Metadata-Version: 2.1
Name: marshmallow-configparser
Version: 0.4.0
Summary: ConfigParser meets marshmallow
Home-page: https://github.com/tadams42/marshmallow_configparser
Author: Tomislav Adamic
Author-email: tomislav.adamic@gmail.com
License: MIT
Keywords: congfiparser,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.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
Provides-Extra: dev
Provides-Extra: docs
Requires-Dist: marshmallow
Provides-Extra: dev
Requires-Dist: bumpversion; extra == 'dev'
Requires-Dist: check-manifest; extra == 'dev'
Requires-Dist: coverage; extra == 'dev'
Requires-Dist: factory-boy; extra == 'dev'
Requires-Dist: faker; extra == 'dev'
Requires-Dist: ipython; extra == 'dev'
Requires-Dist: isort; extra == 'dev'
Requires-Dist: m2r; extra == 'dev'
Requires-Dist: pycodestyle; extra == 'dev'
Requires-Dist: pylint; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest-mock; extra == 'dev'
Requires-Dist: pytest-sugar; extra == 'dev'
Requires-Dist: pytest (>=3.0.0); extra == 'dev'
Requires-Dist: sphinx; extra == 'dev'
Requires-Dist: sphinx-rtd-theme; extra == 'dev'
Requires-Dist: yapf; extra == 'dev'
Provides-Extra: docs
Requires-Dist: m2r (>=0.1.14); extra == 'docs'
Requires-Dist: sphinx (>=1.4); extra == 'docs'
Requires-Dist: sphinx-rtd-theme; extra == 'docs'

# Overview



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

Ever wanted to load config from multiple locations (`/etc/appconfig.conf`, `~/.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

~~~sh
pip install marshmallow_configparser
~~~

## Example

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

~~~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:

~~~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:

~~~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:

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

In the end we have:

~~~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



