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
https://packaging.python.org/guides/creating-and-discovering-plugins/
http://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points
http://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
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')
Metadata
Release files for config-source 0.0.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| config-source-0.0.8.tar.gz | 7.7 kB | Without provenance | Details for config-source-0.0.8.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| config_source-0.0.8-py3-none-any.whl | Python 3 | none | any | Details for config_source-0.0.8-py3-none-any.whl |
Total release size: 19.0 kB
Release files / config-source-0.0.8.tar.gz
| Download URL | config-source-0.0.8.tar.gz |
|---|---|
| Size | 7.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
15cfc26c0bac969be2f3f51c0dcbff0ec934e94292ecc0aa2651f0acd5292071
|
|
BLAKE2b-256 checksum How to use checksums |
c7a03f5017b47958d2eafcf6e9d71b95c7f6c1dd39df59a12d85223cc589636e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.12.1 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.7.3 requests-toolbelt/0.9.1 tqdm/4.30.0 CPython/3.5.2
|
Release files / config_source-0.0.8-py3-none-any.whl
| Download URL | config_source-0.0.8-py3-none-any.whl |
|---|---|
| Size | 11.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
155c87fb730db914787bd57520a0bdc40a759fbbe16ab4cc43904bfa59dc65d5
|
|
BLAKE2b-256 checksum How to use checksums |
0d42c4478aa0440db4e646d17343fdd1e37977a11e8e291916417258160a59a3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.12.1 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.7.3 requests-toolbelt/0.9.1 tqdm/4.30.0 CPython/3.5.2
|
Security for config-source 0.0.8
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.