The Config Tree

A configuration structure which supports cascading layers.

In vivarium it allows base configurations to be overridden by component level configurations which are in turn overridden by model level configuration which can be overridden by user supplied overrides. From the perspective of normal client code the cascading is hidden and configuration values are presented as attributes of the configuration object the values of which are the value of that key in the outermost layer of configuration where it appears.

For example:

>>> config = ConfigTree(layers=['inner_layer', 'middle_layer', 'outer_layer', 'user_overrides'])
>>> config.update({'section_a': {'item1': 'value1', 'item2': 'value2'}, 'section_b': {'item1': 'value3'}}, layer='inner_layer')
>>> config.update({'section_a': {'item1': 'value4'}, 'section_b': {'item1': 'value5'}}, layer='middle_layer')
>>> config.update({'section_b': {'item1': 'value6'}}, layer='outer_layer')
>>> config.section_a.item1
>>> config.section_a.item2
>>> config.section_b.item1
exception vivarium.config_tree.ConfigurationError(message, value_name)[source]

Base class for configuration errors.

exception vivarium.config_tree.ConfigurationKeyError(message, value_name)[source]

Error raised when a configuration lookup fails.

exception vivarium.config_tree.DuplicatedConfigurationError(message, name, layer, source, value)[source]

Error raised when a configuration value is set more than once.


The configuration layer at which the value is being set.


The original source of the configuration value.


The original configuration value.

class vivarium.config_tree.ConfigNode(layers, name)[source]

A priority based configuration value.

A ConfigNode represents a single configuration value with priority-based layers. The intent is to allow a value to be set from sources with different priorities and to record what the value was set to and from where.

For example, a simulation may need certain values to always exist, and so it will set them up at a “base” layer. Components in the simulation may have a different set of priorities and so override the “base” value at a “component” level. Finally a user may want to override the simulation and component defaults with values at the command line or interactively, and so those values will be set in a final “user” layer.

A ConfigNode may only have a value set at each layer once. Attempts to set a value at the same layer multiple times will result in a DuplicatedConfigurationError.

The ConfigNode will record all values set and the source they are set from. This sort of provenance with configuration data greatly eases debugging and analysis of simulation code.

This class should not be instantiated directly. All interaction should take place by manipulating a ConfigTree object.

property name: str

The name of this configuration value.

property accessed: bool

Returns whether this node has been accessed.

property metadata: List[Dict[str, Any]]

Returns all values and associated metadata for this node.


Causes the ConfigNode node to become read only.

This can be used to create a contract around when the configuration is modifiable.


Returns the value at the specified layer.

If no layer is specified, the outermost (highest priority) layer at which a value has been set will be used.


layer (Optional[str]) – Name of the layer to retrieve the value from.


KeyError – If no value has been set at any layer.

Return type


update(value, layer, source)[source]

Set a value for a layer with optional metadata about source.

  • value (Any) – Data to store in the node.

  • layer (Optional[str]) – Name of the layer to use. If no layer is provided, the value will be set in the outermost (highest priority) layer.

  • source (Optional[str]) – Metadata indicating the source of this value.

class vivarium.config_tree.ConfigTree(data=None, layers=None, name='')[source]

A container for configuration information.

Each configuration value is exposed as an attribute the value of which is determined by the outermost layer which has the key defined.


Causes the ConfigTree to become read only.

This is useful for loading and then freezing configurations that should not be modified at runtime.


Return an iterable of all (child_name, child) pairs.

Return type

Iterable[Tuple[str, Union[ConfigTree, ConfigNode]]]


Return an Iterable of all child names.

Return type



Return an Iterable of all children.

Return type



Lists all values in the ConfigTree that haven’t been accessed.

Return type



Converts the ConfigTree into a nested dictionary.

All metadata is lost in this conversion.

Return type


get_from_layer(name, layer=None)[source]

Get a configuration value from the provided layer.

If no layer is specified, the outermost (highest priority) layer at which a value has been set will be used.

  • name (str) – The name of the value to retrieve

  • layer (Optional[str]) – The name of the layer to retrieve the value from.

Return type


update(data, layer=None, source=None)[source]

Adds additional data into the ConfigTree.

  • data (Optional[Union[Dict, str, Path, ConfigTree]]) –

    update() accepts many types of data.

    • dict : Flat or nested dictionaries may be provided. Keys of dictionaries at all levels must be strings.

    • ConfigTree : Another ConfigTree can be used. All source information will be ignored and the provided layer and source will be used to set the metadata.

    • str : Strings provided can be yaml formatted strings, which will be parsed into a dictionary using standard yaml parsing. Alternatively, a path to a yaml file may be provided and the file will be read in and parsed.

    • pathlib.Path : A path object to a yaml file will be interpreted the same as a string representation.

  • layer (Optional[str]) – The name of the layer to store the value in. If no layer is provided, the value will be set in the outermost (highest priority) layer.

  • source (Optional[str]) – The source to attribute the value to.


name (str) –

Return type

List[Dict[str, Any]]