Documenting configuration

It’s hard to keep configuration documentation up-to-date as projects change over time.

Everett comes with a Sphinx extension for documenting configuration. It has autocomponentconfig and automoduleconfig directives for automatically generating documentation. It also has everett:component and everett:option directives for manually documenting configuration. It also comes with :everett:option: and :everett:component: roles letting you create links to specific configuration things in your documentation.

Configuration options are added to the index and have unique links making it easier to find and point people to specific configuration documentation.

Changed in version 3.0.0: Complete rewrite of Sphinx directives.

Directives

.. automoduleconfig::

Requires Python 3.8 or higher.

Automatically documents the configuration options set in a Python module using the specified everett.manager.ConfigManager.

The argument is the Python dotted path to the everett.manager.ConfigManager instance.

Note

The automoduleconfig directive works by parsing the Python module as an AST and then traverses the AST.

It does not execute the module, so it doesn’t evaluate any values.

Note

automoduleconfig requires Python 3.8 or higher.

If you’re using ReadTheDocs, it defaults to Python 3.7. You’ll need to configure the version of Python to use by adding a configuration file.

See ReadTheDocs configuration file documentation for more details.

Options

.. autocomponentconfig::

Automatically documents the configuration options for the specified class and its superclasses.

The argument is the Python dotted path to the class.

Warning

autocomponentconfig imports the code to be documented. If any of the imported modules have side-effects at import, they will be executed when building the documentation.

Options

.. everett:component::

Defines an Everett component which is any Python class that has an inner class named Config which defines configuration options.

The argument is the Python dotted path to the class.

Add everett:option as part of the description.

.. everett:option::

Defines an Everett configuration option.

The argument is the option key.

Options

Examples

Documenting component configuration

Here’s an example Everett component:

# recipes_appconfig.py

import logging

from everett.manager import ConfigManager, Option


TEXT_TO_LOGGING_LEVEL = {
    "CRITICAL": 50,
    "ERROR": 40,
    "WARNING": 30,
    "INFO": 20,
    "DEBUG": 10,
}


def parse_loglevel(value):
    try:
        return TEXT_TO_LOGGING_LEVEL[value.upper()]
    except KeyError:
        raise ValueError(
            f'"{value}" is not a valid logging level. Try CRITICAL, ERROR, '
            "WARNING, INFO, DEBUG"
        )


class AppConfig:
    class Config:
        debug = Option(
            parser=bool,
            default="false",
            doc="Turns on debug mode for the application",
        )
        loglevel = Option(
            parser=parse_loglevel,
            default="INFO",
            doc=(
                "Log level for the application; CRITICAL, ERROR, WARNING, INFO, "
                "DEBUG"
            ),
        )


def init_app():
    manager = ConfigManager.from_dict({})
    config = manager.with_options(AppConfig())

    logging.basicConfig(level=config("loglevel"))

    if config("debug"):
        logging.info("debug mode!")


if __name__ == "__main__":
    init_app()

You can use the autocomponentconfig directive to extract the configuration information from the AppConfig class and document it:

.. autocomponentconfig:: recipes_appconfig.AppConfig
   :case: upper
   :show-table:

That gives you something that looks like this:

component recipes_appconfig.AppConfig

Configuration summary:

Setting Parser Required?
DEBUG bool  
LOGLEVEL recipes_appconfig.parse_loglevel  

Configuration options:

DEBUG

Turns on debug mode for the application

LOGLEVEL

Log level for the application; CRITICAL, ERROR, WARNING, INFO, DEBUG

You can link to components with the :everett:component: role and options using the :everett:option: role.

Example component link:

Component link: :everett:component:`recipes_appconfig.AppConfig`

Component link: recipes_appconfig.AppConfig

Example option link:

Option link: :everett:option:`recipes_appconfig.AppConfig.DEBUG`

Option link: recipes_appconfig.AppConfig.DEBUG

Documenting module configuration

You can use automoduleconfig to document configuration that’s set at module import. This is helpful for Django settings modules.

Example configuration code that sets up a everett.manager.ConfigManager and calls it _config:

# recipes_djangosettings.py

from everett.manager import ConfigManager


_config = ConfigManager.basic_config()


DEBUG = _config(
    "debug", parser=bool, default="False", doc="Whether or not DEBUG mode is enabled."
)

Example documentation directive:

.. automoduleconfig:: recipes_djangosettings._config
   :hide-name:
   :case: upper
   :show-table:

That gives you this:

Configuration

Configuration summary:

Setting Parser Required?
DEBUG bool  

Configuration options:

DEBUG

Whether or not DEBUG mode is enabled.