Simple configuration management for python
# released version
pip install python-simpleconf
# Install support for ini
pip install python-simpleconf[ini]
# Install support for dotenv
pip install python-simpleconf[dotenv]
# Install support for yaml
pip install python-simpleconf[yaml]
# Install support for toml
pip install python-simpleconf[toml]
# Install support for all supported formats
pip install python-simpleconf[all]
- Multiple formats supported
- Type casting
- Profile support
- Simple APIs
from simpleconf import Config
# Load a single file
conf = Config.load('~/xxx.ini')
# load multiple files, later files override previous ones
conf = Config.load(
'~/xxx.ini', '~/xxx.env', '~/xxx.yaml', '~/xxx.toml',
'~/xxx.json', 'simpleconf.osenv', {'a': 3}
)
# Load a single file with a different loader
conf = Config.load('~/xxx.ini', loader="toml")
from simpleconf import Config
conf = Config.load({'a': 1, 'b': {'c': 2}})
# conf.a == 1
# conf.b.c == 2
.ini/.cfg/.config
(parsed byiniconfig
).- For confiurations without profiles, an ini-like configuration like must have a
default
(case-insensitive) section.
- For confiurations without profiles, an ini-like configuration like must have a
.env
(usingpython-dotenv
). A file with environment variables..yaml/.yml
(usingpyyaml
). A file with YAML data..toml
(usingrtoml
). A file with TOML data..json
(usingjson
). A file with JSON data.XXX.osenv
: System environment variables with prefixXXX_
(case-sensitive) is used.XXX_A=1
will be loaded asconf.A = 1
.
- python dictionary.
from simpleconf import ProfileConfig
conf = ProfileConfig.load({'default': {'a': 1})
# conf.a == 1
config.env
# config.env
default_a=1
from simpleconf import ProfileConfig
conf = ProfileConfig.load('config.env')
# conf.a == 1
# config.ini
[default]
a = 1
from simpleconf import ProfileConfig
conf = ProfileConfig.load('config.ini')
# conf.a == 1
config.json
{
"default": {
"a": 1
}
}
from simpleconf import ProfileConfig
conf = ProfileConfig.load('config.json')
# conf.a == 1
from os import environ
from simpleconf import ProfileConfig
environ['XXX_DEFAULT_A'] = '1'
conf = ProfileConfig.load('XXX.osenv')
# conf.a == 1
# config.toml
[default]
a = 1
from simpleconf import ProfileConfig
conf = ProfileConfig.load('config.toml')
# conf.a == 1
# config.yaml
default:
a: 1
from simpleconf import ProfileConfig
conf = ProfileConfig.load('config.yaml')
# conf.a == 1
from simpleconf import ProfileConfig
conf = ProfileConfig.load(
{'default': {'a': 1, 'b': 2}, 'dev': {'a': 3}, 'prod': {'a': 4}}
)
# conf.a == 1; conf.b == 2
# ProfileConfig.profiles(conf) == ['default', 'dev', 'prod']
# ProfileConfig.pool(conf) == {'default': {'a': 1, 'b': 2}, 'dev': {'a': 3}, 'prod': {'a': 4}}
# ProfileConfig.current_profile(conf) == 'default'
# ProfileConfig.base_profile(conf) == 'default'
ProfileConfig.use_profile(conf, 'dev')
# conf.a == 3; conf.b == 2
# ProfileConfig.current_profile(conf) == 'dev'
# ProfileConfig.base_profile(conf) == 'default'
# use a different base profile
ProfileConfig.use_profile(conf, 'prod', base='dev')
# conf.a == 4 # No 'b' in conf
# ProfileConfig.current_profile(conf) == 'prod'
# ProfileConfig.base_profile(conf) == 'dev'
# Copy configuration instead of inplace modification
conf2 = ProfileConfig.use_profile(conf, 'dev', copy=True)
# conf2 is not conf
# conf2.a == 3; conf2.b == 2
# Use a context manager
with ProfileConfig.use_profile(conf2, 'default'):
conf2.a == 3
conf2.b == 2
# conf2.a == 3; conf2.b == 2
For configuration formats with type support, including dictionary, no type casting is done by this library, except that for TOML files.
TOML does not support None
value in python. We use rtoml
library to parse TOML files, which dumps None
as "null"
. So a null_caster
is used to cast "null"
to None
.
A none_caster
is also enabled for TOML files, a pure string of "@none"
is casted to None
.
For other formats, following casters are supported:
from os import environ
from simpleconf import Config
environ['XXX_A'] = '@int:1'
conf = Config.load('XXX.osenv')
# conf.a == 1 # int
@float:1.0
-> 1.0
@bool:true
-> True
@bool:false
-> False
Values are casted by ast.literal_eval()
.
"@python:1" => 1 # or
"@py:1" => 1
"@py:1.0` -> `1.0`
"@py:[1, 2, 3]" => [1, 2, 3]
@json:{"a": 1}
-> {"a": 1}
@toml:a = 1
-> {"a": 1}