marshmallow-configparser

ConfigParser meets marshmallow


Keywords
congfiparser, marshmallow, configparser
License
MIT
Install
pip install marshmallow-configparser==0.3.3

Documentation

Overview

version license wheel python_versions python_implementations travis docs requirements codacy_grade codecov

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

pip install marshmallow_configparser

Example

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

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

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:

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:

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

In the end we have:

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