config_io is a Python package for advanced config reading/parsing/writing. config_io currently supports json and yaml formats.
You can install config_io via pip:
pip install config_ioconfig_io runs on Python 3, and every build is tested towards Python 3.6, 3.7, 3.8, 3.9, 3.10 on ubuntu, macOS, and windows.
First, load the library by
>>> from config_io import ConfigConfig is a class for storing configs. Config is similar Python dictionary but with powerful reading/writing/parsing functions.
config_io supports reading configs from yaml and json files, as well as from python dictionaries or through keyword arguments.
Suppose we have a json file config.json with content
{"key": "value"}and a yaml file config.yaml with content
key: valueBelow are five equivalent ways to create the same config object:
>>> config = Config.load_from_file('config.json')>>> config = Config.load_from_file('config.yaml')>>> config = Config({'key': 'value'})>>> config = Config(key='value')>>> config = Config()
>>> config.key = 'value'The config object is
>>> config
{'key': 'value'}
>>> type(config)
<class 'config_io.config.Config'>Config objects (of type config_io.config.Config) can be dumped to json and yaml files easily by
>>> config.dump_to_file('config.json')or
>>> config.dump_to_file('config.yaml')In many use cases, we may want to specify a default config (e.g., default parameters for a program). Other configs (e.g., user-specified parameters) can modify on top of it. config_io provides an easy way to do this.
Suppose we have default.yaml with content
k1: v1
k2: v2
k3: v3Now, suppose that we want to specify a config that adds a new key k4, and changes the value of k3 to new_v3. We can simply write config.yaml with content
k4: v4
k3: new_v3
default: default.yamlconfig_io will automatically load the config file specified by default as the default parameters:
>>> Config.load_from_file('config.yaml')
{'k1': 'v1', 'k2': 'v2', 'k3': 'new_v3', 'k4': 'v4', 'default': 'default.yaml'}- Instead of specifying
default: default.yamlinconfig.yaml, an alternative way is to specify it when loading the config:Config.load_from_file('config.yaml', default='default.yaml'). - Default configs can be chained in any order. For example,
config1.yamlcan setconfig2.yamlas the default config, andconfig2.yamlcan set anotherconfig3.yamlas the default config.
In many scenarios, we may want to interact with a set of configs that are created by enumerating all possible combinations of values. config_io provides an easy way to do this.
For example, assume that config.json has the content:
{"k1": [1, 2],
"k2": [3, 4],
"k1_expand": true,
"k2_expand": true}Loading it would give a list of 4 configs
>>> Config.load_from_file('config.json', expand=True)
[{'k1': 1, 'k2': 3, 'k1_expand': True, 'k2_expand': True},
{'k1': 1, 'k2': 4, 'k1_expand': True, 'k2_expand': True},
{'k1': 2, 'k2': 3, 'k1_expand': True, 'k2_expand': True},
{'k1': 2, 'k2': 4, 'k1_expand': True, 'k2_expand': True}]Basically, for the keys such that {KEY_NAME}_expand is set to true, config_io treats their values as a list of candidate values, and will enumerate all possible combinations of them to generate the list of configs. Note that this feature is turned on only when expand is set to true either through the parameter of load_from_file or inside the config file.
Expansion can also happen after the config is loaded:
>>> config = Config({'k1': {'k2': [1, 2], 'k2_expand': True}})
>>> config.expand()
[{'k1': {'k2': 1, 'k2_expand': True}}, {'k1': {'k2': 2, 'k2_expand': True}}]or be applied only for a sub-tree of the config:
>>> config.k1.expand()
[{'k2': 1, 'k2_expand': True}, {'k2': 2, 'k2_expand': True}]The keys to expand can be on different levels of the config tree. For example, if config.json is
{"k1": [1, 2],
"k1_expand": true,
"k2": {"k3": [3, 4],
"k3_expand": true}}Config.load_from_file('config.json', expand=True) would give
[{'k1': 1, 'k1_expand': True, 'k2': {'k3': 3, 'k3_expand': True}},
{'k1': 1, 'k1_expand': True, 'k2': {'k3': 4, 'k3_expand': True}},
{'k1': 2, 'k1_expand': True, 'k2': {'k3': 3, 'k3_expand': True}},
{'k1': 2, 'k1_expand': True, 'k2': {'k3': 4, 'k3_expand': True}}]config_io.config.Config is extended from the powerful addict library, which supports retrieving config values using either attributes or the standard dictionary item syntax:
>>> config = Config(a=1,b={'c':2})
>>> config.a
1
>>> config.b.c
2
>>> config['b'].c
2For more advanced options, please refer to addict doc.
If you find bugs/problems or want to add more features to this library, feel free to submit issues or make pull requests.