XConfig¶
All Choixe functionalities can be accessed with the XConfig class. You can construct an XConfig from any python mapping, by simply passing it to the constructor:
from choixe import XConfig
# A dictionary containing stuff
data = {
"alpha": {
"a": 10,
"b": -2,
},
"beta": {
"a": "hello",
"b": "world",
},
}
# Instance an XConfig
cfg = XConfig(data)
Interaction¶
An XConfig is also a python Mapping and has all the methods you would expect from a plain python dict.
In addition, you can get/set its contents with the dot notation (if you know the keys at code time) like:
cfg.alpha.b
# -2
cfg.alpha.new_key = 42
cfg.alpha
# {"a": 10, "b": -2, "new_key": 42}
You can also use deep_get and deep_set to get/set deep content using pydash keys, useful if you don’t know the keys at code time. The deep_set method also have a flag that disables the setting of the new value if this involves creating a new key.
cfg.deep_get("alpha.b")
# -2
cfg.deep_set("alpha.new_key", 42)
cfg.deep_get("alpha")
# {"a": 10, "b": -2, "new_key": 42}
# This should be a NoOp, since "another_new_key" was not already present.
cfg.deep_set("alpha.another_new_key", 43, only_valid_keys=True)
cfg.deep_get("alpha")
# {"a": 10, "b": -2, "new_key": 42}
There is also a deep_update method to merge two configurations into one. The full_merge flag enables the setting on new keys.
data = XConfig({
"a": {"b": 100},
"b": {"a": 1, "b": [{"a": -1, "b": -2}, "a"]},
})
other = XConfig({"b": {"b": [{"a": 42}], "c": {"a": 18, "b": 20}}})
data.deep_update(other)
# {
# "a": {"b": 100},
# "b": {"a": 1, "b": [{"a": 42, "b": -2}, "a"]},
# }
data.deep_update(other, full_merge=True)
# {
# "a": {"b": 100},
# "b": {"a": 1, "b": [{"a": 42, "b": -2}, "a"], "c": {"a": 18, "b": 20}}
# }
At any moment, you can convert the XConfig back to a dictionary by calling to_dict.
plain_dict = cfg.to_dict()
type(plain_dict)
# dict
I/O¶
XConfig provides a simplified interface to load/save from/to a file. The format is automatically inferred from the file extension.
cfg = XConfig.from_file("path/to/my_cfg.yml")
cfg.save_to("another/path/to/my_cfg.json")
Processing¶
At the moment of creation, the XConfig content will be an exact copy of the plain python dictionary used to create it, no check or operation is performed on the directives, they are treated just like any other string.
To “activate” them, you need to process the XConfig, by calling either process or process_all, passing an appropriate context dictionary.
process will compile and run the configuration without branching (i.e. sweeps nodes are disabled), and return the processed XConfig.
process_all will compile and run the configuration with branching and return a list of all the processed XConfig.
cfg = XConfig.from_file("config.yml")
output = cfg.process()
outputs = cfg.process_all()
Inspection¶
What if you just loaded an XConfig and are about to process it, only, you don’t know what to pass as context, what environment variables are required, or what files are going to be imported. You can use the inspect method, to get some info on the XConfig that you are about to process.
The result of inspect is an Inspection, containing the following fields:
imports- Asetof all the absolute paths imported from the inspectedXConfig.variables- An uninitialized structure that can be used as context, containing all variables and loop iterables, and their default value if present (Noneotherwise).environ- An uninitialized structure containing all environment variables and their default value if present (Noneotherwise).symbols- Thesetof all dynamically imported python files/modules.processed- Aboolvalue that is true if theXConfigcontains any Choixe directive and thus needs processing.
Validation¶
At the moment of creation - whether from file or from a plain dictionary, you can specify an optional Schema object used for validation. More details here.
Validation is enabled only when a schema is set.
To validate an XConfig you can use is_valid to know if the configuration validates its schema. You can also use validate to perform full validation (enabling side effects).