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.

Files for config-source, version 0.0.8
Filename, size File type Python version Upload date Hashes
Filename, size config_source-0.0.8-py3-none-any.whl (11.3 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size config-source-0.0.8.tar.gz (7.7 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page