Skip to main content

Simple configurations management for applications.

Project description

https://travis-ci.org/LudditeLabs/config-source.svg?branch=master

This package provides extensible configuration loading from various sources.

Features:

  • Dict-like configuration loading from:
    • python dictionaries
    • python objects
    • python files
    • environment variables
    • JSON files
  • Custom configuration sources and objects.

Basically config-source provides a way to register configuration loaders and call them by names. The loader accepts optional arguments, reads configuration from a specific source and populates a configuration object.

Example:

from config_source import DictConfig
from config_source import DictConfigLoader

config = DictConfig()
config.load_from('pyfile', '/path/to/config.py')
config.load_from('json', '/path/to/config.json')
config.load_from('env', prefix='MYCFG')

loader = DictConfigLoader(config)
loader.load('/path/to/config.py')
loader.load('/path/to/config.json')
loader.load(SomeClassWithConfigs)

Usage

Out of the box you could use:

  • Low level load_to() function.
  • DictConfig class.
  • DictConfigLoader class to assist in configurations loading.

load_to() calls a loader registered for a specific source and populates a config object passed to it:

load_to(config, 'source_name', ...)
  • config - configuration object to populate.
  • source_name - configuration source name.

DictConfig behaves like a regular python dictionary and provides load_from method to load configurations from various sources (it uses load_to() internally):

config = DictConfig()
config.load_from(<source_name>, *args, **kwargs)
  • <source_name> - configuration source name;
  • *args and **kwargs - arguments for configuration loader.

The following sources are provided out of the box for dict-like configurations.

Note: dict-like means any object with mapping interface can be used as configuration object:

config = {}
load_to(config, 'env', ...)

dictconfig = DictConfig()
dictconfig.load_from('env', ...)
load_to(dictconfig, 'env', ...)
  • object - load configuration from a python object. It reads attributes with uppercase names:

    config.load_from('object', <object>)
    

    Example:

    class MyConfig:
        SECRET_KEY = 123
        DEBUG = False
    
    ...
    
    config.load_from('object', MyConfig)
    
  • dict - load configuration from a python dictionary. Reads only uppercase keys:

    config.load_from('dict', <dict>)
    

    Example:

    myconfig = dict(SECRET_KEY=123, DEBUG=False)
    config.load_from('dict', myconfig)
    
  • env - load configuration from current runtime environment:

    config.load_from('env', prefix=<name_prefix>, trim_prefix=True)
    
    • prefix - Environment variable name prefix.
    • trim_prefix - Include or not prefix to result config name

    Example:

    # Load vars with names MYCFG_*, like MYCFG_SECRET.
    config.load_from('env', prefix='MYCFG')
    
  • pyfile - load configuration from a python file. Reads only uppercase attributes:

    config.load_from('env', filename, silent=False)
    
    • filename - filename to load.
    • silent - Don’t raise an error on missing files.

    Example:

    config.load_from('pyfile', 'config.py')
    
  • json - load configuration from a json file. Reads only uppercase keys:

    config.load_from('json', filename, silent=False)
    
    • filename - filename to load.
    • silent - Don’t raise an error on missing files.

    Example:

    config.load_from('json', '/path/to/config.json')
    

DictConfigLoader auto-detects source name from input configuration source:

loader = DictConfigLoader(config)
loader.load('/path/to/file.py')

# Same as:
config.load_from('pyfile', '/path/to/file.py')

You may subclass to extend auto-detection.

Add source

config_source decorator is used to register additional configuration sources:

from config_source import config_source

@config_source('source_name')
def myloader(config, arg1, arg2):
    config['XX'] = arg1 + arg2

config.load_from('source_name', 1, arg2=2)

Configuration loader must be a callable with at least one argument - configuration object to populate. Other arguments are optional and loader specific.

There is a possibility to register configuration sources by implementing a package with entry point:

setup(
    ...
    entry_points={'config_source.sources': '<source> = <package name>'},
    ...
)

In the package you use config_source decorator.

For more info on entry points see

Note: you could specify single entry point even if your package adds multiple sources.

Defaults

Instead of always passing parameters to configuration loaders you could set defaults in DictConfig:

config = DictConfig(defaults={
    'env': {'prefix': 'MYAPP'},
    'pyfile': {'filename': '/path/to/file.py'}
})

# 'prefix' will be set to MYAPP for 'env' config source.
# Load from 'MYAPP_*' vars by default.
config.load_from('env')

# Load from 'MY_*' vars
config.load_from('env', 'MY')

# Load from '/path/to/file.py' by default.
config.load_from('pyfile')

# Load from '/path/to/another/file.py'.
config.load_from('pyfile', '/path/to/another/file.py')

defaults is a map where keys are source names and values are keyword parameters to be passed to loaders.

Custom configuration type

You can register configuration source for specific type (by default it’s a dict):

@config_source('source_name', config_type='mytype')
def mytype_loader(config):
    ....

config_type here is a string defining configuration object type.

Now you populate your config object using that loader:

load_to(config, 'source_name', config_type='mytype')

where config is object implementing mytype interface.

list configuration example:

from config_source import config_source, load_to


@config_source('object', config_type='list')
def object_loader(config, obj):
has = False
for key in dir(obj):
    if key.isupper():
        has = True
        config.append(getattr(obj, key))
return has


class MyConfig:
    SECRET = 1
    DEBUG = False


cfg = []
load_to(cfg, 'object', config_type='list')

# cfg = [1, False]

# Fails because by default it calls loader for 'dict' configuration.
# load_to(cfg, 'object')

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help File type Python version Upload date
config_source-0.0.6-py3-none-any.whl (11.0 kB) Copy SHA256 hash SHA256 Wheel py3
config-source-0.0.6.tar.gz (7.0 kB) Copy SHA256 hash SHA256 Source None

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page