Exosphere configuration

The configuration module in Exosphere is wildly flexible, allowing you to essentially provide your configuration structure in any format you’d like.

At runtime, the effective, current configuration structure is accessible through exosphere.app_config, which will always contain (at the very least) the default values defined in the Configuration.DEFAULTS dict.

class exosphere.config.Configuration

Bases: dict

Hold configuration values for the application. Extends a native dict to store the global options section of the inventory toml file.

Has the following peculiarities vs a native dict:

  • Has many from_* methods to populate itself from various sources such as environment variables, files of various formats

  • Enforces a set of default values for the nested options dict

  • Enforces unicity for name keys in the hosts dict.

  • Has a deep_update() method to recursively update nested dicts without replacing them entirely.

This configuration structure is strongly inspired by the one used by Flask, because good things are worth replicating.

DEFAULTS = {...}

Default configuration values This dict contains the default configuration and is always used as a base for what the configuration object contains. This can be accessed to get the default values for any config key

deep_update(d: dict, u: dict) dict

Recursively update a dictionary with another dictionary. Ensures nested dicts are updated rather than replaced.

Parameters:
  • d – The dictionary to update

  • u – The dictionary with updates

Returns:

The updated dictionary

from_env(prefix: str = 'EXOSPHERE_OPTIONS', parser: ~collections.abc.Callable[[str], ~typing.Any] = <function loads>) bool

Populate the configuration structure from environment variables.

Any environment variable that starts with the specified prefix (e.g., EXOSPHERE_OPTIONS_*) will be considered for updating the configuration.

Note that this is, currently, limited to the options section of the configuration. The inventory cannot be updated this way.

If there are any nested dictionaries in the configuration, you can specify them using a double underscore (__) to separate the keys.

The values for the keys are parsed as JSON types by default, but you can specify a custom loader function to parse the values, as long as it operates on strings.

Parameters:
  • prefix – The prefix to look for in environment variables

  • parser – A callable that takes a string and returns a parsed value

Returns:

True if the configuration was successfully updated

from_file(filepath: str, loader: Callable[[BinaryIO], dict], silent: bool = False) bool

Populate the configuration structure from a file, with a specified loader function callable.

The loader must be a reference to a callable that takes a file handle and returns a mapping of the data contained within.

For instance, tomllib.load() is a valid loader for toml files

This allows for the format of the configuration file to be essentially decoupled from the validation and internal representation of the data.

Parameters:
  • filepath – Path to the file to load

  • loader – A callable that takes a file handle and returns a dict

  • silent – If True, suppress IOError exceptions for missing files

Returns:

True if the configuration was successfully updated

from_json(filepath: str, silent: bool = False) bool

Populate the configuration structure from a json file

This method is a convenience wrapper used for shorthand for the from_file method, with json.load() as the loader.

see from_file() for details.

Parameters:
  • filepath – Path to the json file to load

  • silent – If True, suppress IOError exceptions for missing files

Returns:

True if the configuration was successfully updated, False if the file was not found

from_toml(filepath: str, silent: bool = False) bool

Populate the configuration structure from a toml file

This method is a convenience wrapper used for shorthand for the from_file method, with tomllib.load() as the loader.

see from_file() for details.

Parameters:
  • filepath – Path to the toml file to load

  • silent – If True, suppress IOError exceptions for missing files

Returns:

True if the configuration was successfully updated, False if the file was not found

from_yaml(filepath: str, silent: bool = False) bool

Populate the configuration structure from a yaml file

This method is a convenience wrapper used for shorthand for the from_file method, with yaml.safe_load() as the loader.

see from_file() for details.

Parameters:
  • filepath – Path to the yaml file to load

  • silent – If True, suppress IOError exceptions for missing files

Returns:

True if the configuration was successfully updated, False if the file was not found

update_from_mapping(*mapping: dict, **kwargs: dict) bool

Populate values like the native dict.update() method, but only if the key is a valid root configuration key.

This will also deep merge the values from the mapping if they are also dicts.

Parameters:
  • mapping – A single mapping to update the configuration with

  • kwargs – Additional keyword arguments to update the configuration with

Returns:

True if the configuration was successfully updated