Quick start
Create yaml file(s) that contains your default configurations. All the parameters should be listed (see later to organize them simply in case of big config files).
# default1.yaml
param1: 1
param2: 1
letters:
letter1: a
letter2: b
# default2.yaml
param1: 1
param2: 2 # will override param2 from default1.yaml
letters.letter3: c # add a new parameter
Get your config in your python code:
# main.py
from cliconfig import make_config
config = make_config('default1.yaml', 'default2.yaml')
Add additional config file(s) that represent your experiments. They will override the default values. Please note that new parameters that are not present in the default configs are not allowed. This restriction is in place to prevent potential typos in the config files from going unnoticed. It also enhances the readability of the default config files and ensures retro-compatibility (see later to circumnavigate it for particular cases). This restriction apart, the package allows a complete liberty of config manipulation.
# first.yaml
letters:
letter3: C # equivalent to "letters.letter3: 'C'"
# second.yaml
param1: -1
letters.letter1: A
Run your code with the additional config files AND eventually some other parameters from command line. Please respect the exact syntax for spaces and equal signs.
python main.py --config first.yaml,second.yaml --param2=-2 --letters.letter2='B'
If you have multiple config files it is possible to pass a list with bracket.
Be careful, using --config=first.yaml
will NOT be recognized as an additional config
file (space is important) but as a parameter called “config” with value “first.yaml”
(it then raises an error if no “config” parameter is on the default config).
Now the config look like this:
Config:
param1: -1 # (overridden by second.yaml)
param2: -2 # (overridden by command line args)
letters:
letter1: A # (overridden by second.yaml)
letter2: B # (overridden by command line args)
letter3: C # (overridden by first.yaml)
You can also manipulate your config with the following functions:
from cliconfig import load_config, save_config, show_config, update_config
show_config(config) # print it
config.dict # config as native dict
config.dict['letters']['letter1'] # access parameter via dict
config.letters.letter1 # access parameter via dots
config.letters.letter1 = 'G' # modify parameter
del config.letters.letter1 # delete parameter
# Update config with a dict or another config
config = update_config(config, {'letters': {'letter1': 'H'}})
# Save the config as a yaml file
save_config(config, 'myconfig.yaml')
# Load the config and merge with the default configs if provided
# (useful if default configs were updated)
config = load_config('myconfig.yaml', default_config_paths=['default1.yaml', 'default2.yaml'])
The config object is just a wrapper around the config dict that allows to access the parameters via dots (and containing the list of processings, see Processing section for details). That’s all! Therefore, the config object is very light and simple to use.
While the config object is simple, the possibilities to manipulate the config are endless. See the next section for some default features. One of the core idea of this package is to make it easy to add your own features for your specific needs.