desmod.config

Tools for managing simulation configurations.

Each simulation requires a configuration dictionary that defines various configuration values for both the simulation (desmod) and the user model. The configuration dictionary is flat, but the keys use a dotted notation, similar to Component scopes, that allows for different namespaces to exist within the [flat] configuration dictionary.

Several configuration key/values are required by desmod itself. These configuration keys are prefixed with ‘sim.’; for example: ‘sim.duration’ and ‘sim.seed’.

Models may define their own configuration key/values, but should avoid using the ‘sim.` prefix.

The NamedManager class provides a mechanism for defining named groupings of configuration values. These named configuration groups allow quick configuration of multiple values. Configuration groups are also composable: a configuration group can be defined to depend on several other configuration groups.

Most functions in this module are provided to support building user interfaces for configuring a model.

class desmod.config.ConfigError[source]

Exception raised for a variety of configuration errors.

class desmod.config.NamedConfig[source]

Named configuration group details.

Iterating a NamedManager instance yields NamedConfig instances.

category

Alias for field number 0

name

Alias for field number 1

doc

Alias for field number 2

depend

Alias for field number 3

config

Alias for field number 4

count()

Return number of occurrences of value.

index()

Return first index of value.

Raises ValueError if the value is not present.

class desmod.config.NamedManager[source]

Manage named configuration groups.

Any number of named configuration groups can be specified using the name() method. The resolve() method is used to compose a fully-resolved configuration based on one or more configuration group names.

Iterating a NamedManager instance will yield NamedConfig instances for each registered named configuration.

name(name: str, depend: Optional[List[str]] = None, config: Optional[Dict[str, Any]] = None, category: str = '', doc: str = '') → None[source]

Declare a new configuration group.

A configuration group consists of a name, a list of dependencies, and a dictionary of configuration key/values. This function declares a new configuration group that may be later resolved with resolve().

Parameters:
  • name (str) – Name of new configuration group.
  • depend (list) – List of configuration group dependencies.
  • config (dict) – Configuration key/values.
  • category (str) – Optional category.
  • doc (str) – Optional documentation for named configuration group.
resolve(*names) → Dict[str, Any][source]

Resolve named configs into a new config object.

desmod.config.apply_user_overrides(config: Dict[str, Any], overrides: Iterable[Tuple[str, str]], eval_locals: Optional[Dict[str, Any]] = None) → None[source]

Apply user-provided overrides to a configuration.

The user-provided overrides list are first verified for validity and then applied to the the provided config dictionary.

Each user-provided key must already exist in config. The fuzzy_lookup() function is used to verify that the user-provided key exists unambiguously in config.

The user-provided value expressions are evaluated against a safe local environment using eval(). The type of the resulting value must be type-compatible with the existing (default) value in config.

Parameters:
  • config (dict) – Configuration dictionary to modify.
  • overrides (list) – List of user-provided (key, value expression) tuples.
  • eval_locals (dict) – Optional dictionary of locals to use with eval(). A safe and useful set of locals is provided by default.
desmod.config.parse_user_factors(config: Dict[str, Any], user_factors, eval_locals: Optional[Dict[str, Any]] = None) → List[Tuple[List[str], List[Any]]][source]

Safely parse user-provided configuration factors.

A configuration factor consists of an n-tuple of configuration keys along with a list of corresponding n-tuples of values. Configuration factors are used by simulate_factors() to run multiple simulations to explore a subset of the model’s configuration space.

Parameters:
  • config (dict) – The configuration dictionary is used to check the keys and values of the user-provided factors. The dictionary is not modified.
  • user_factors – Sequence of (user_keys, user_expressions) tuples. See parse_user_factor() for more detail on user keys and expressions.
  • eval_locals (dict) – Optional dictionary of locals used when eval()-ing user expressions.
Returns:

List of keys, values pairs. The returned list of factors is suitable for passing to simulate_factors().

Raises:

ConfigError – For invalid user keys or expressions.

desmod.config.parse_user_factor(config: Dict[str, Any], user_keys: str, user_exprs: str, eval_locals: Optional[Dict[str, Any]] = None) → Tuple[List[str], List[Any]][source]

Safely parse a user-provided configuration factor.

Example:

>>> config = {'a.b.x': 0,
              'a.b.y': True,
              'a.b.z': 'something'}
>>> parse_user_factor(config, 'x,y', '(1,True), (2,False), (3,True)')
[['a.b.x', 'a.b.y'], [[1, True], [2, False], [3, True]]]
Parameters:
  • config (dict) – The configuration dictionary is used to check the keys and values of the user-provided factors. The dictionary is not modified.
  • user_keys (str) – String of comma-separated configuration keys of the factor. The keys may be fuzzy (i.e. valid for use with fuzzy_lookup()), but note that the returned keys will always be fully-qualified (non-fuzzy).
  • user_exprs (str) – User-provided Python expressions string. The expressions string is evaluated using eval() with, by default, a safe locals dictionary. The expressions string must evaluate to a sequence of n-tuples where n is the number of keys provided in user_keys. Further, the elements of each n-tuple must be type-compatible with the existing (default) values in the config dict.
  • eval_locals (dict) – Optional dictionary of locals used when eval()-ing user expressions.
Returns:

A config factor: a pair (2-list) of keys and values lists.

Note

All sequences in the returned factor are expressed as lists, not tuples. This is done to improve YAML serialization.

Raises:

ConfigError – For invalid keys or value expressions.

desmod.config.factorial_config(base_config: Dict[str, Any], factors: Iterable[Tuple[List[str], List[Any]]], special_key: Optional[str] = None) → Iterator[Dict[str, Any]][source]

Generate configurations from base config and config factors.

Parameters:
  • base_config (dict) – Configuration dictionary that the generated configuration dictionaries are based on. This dict is not modified; generated config dicts are created with copy.deepcopy().
  • factors (list) – Sequence of one or more configuration factors. Each configuration factor is a 2-tuple of keys and values lists.
  • special_key (str) – When specified, a key/value will be inserted into the generated configuration dicts that identifies the “special” (unique) key/value combinations of the specified factors used in the config dict.
Yields:

Configuration dictionaries with the cartesian product of the provided factors applied. I.e. each yielded config dict will have a unique combination of the factors.

desmod.config.fuzzy_match(keys: Iterable[str], fuzzy_key: str) → str[source]

Match a fuzzy key against sequence of canonical key names.

Parameters:
  • keys – Sequence of canonical key names.
  • fuzzy_key (str) – Fuzzy key to match against canonical keys.
Returns:

Canonical matching key name.

Raises:

KeyError – If fuzzy key does not match.

desmod.config.fuzzy_lookup(config: Dict[str, Any], fuzzy_key: str) → Tuple[str, Any][source]

Lookup a config key/value using a partially specified (fuzzy) key.

The lookup will succeed iff the provided fuzzy_key unambiguously matches the tail of a [fully-qualified] key in the config dict.

Parameters:
  • config (dict) – Configuration dict in which to lookup fuzzy_key.
  • fuzzy_key (str) – Partially specified key to lookup in config.
Returns:

(key, value) tuple. The returned key is the regular, fully-qualified key name, not the provided fuzzy_key.

Raises:

ConfigError – For non-matching fuzzy_key.