# API reference

## `cfig.config`

This module defines the `Configuration` class.

class cfig.config.Configuration(*, sources: list[Source] | None = None)

  A collection of proxies with methods to easily define more.

  DEFAULT_SOURCES: list[Source] = [<cfig.sources.env.EnvironmentSource object>, <cfig.sources.envfile.EnvironmentFileSource object>]

    The sources used in `__init__()` if no other source is specified.

  class ProxyDict(dict=None, /, **kwargs)

    An extended `dict` with methods to perform some actions on the contained proxies.

    resolve() → dict[str, Any]

      Resolve all values of the proxies inside this dictionary.

      Raises:

        .errors.BatchResolutionFailure – If it was not possible to resolve at least one value.

      Returns:

        A `dict` containing all the resolved, unproxied, values.

    resolve_failfast() → dict[str, Any]

      Resolve all values of the proxies inside this dictionary, failing immediately if an error occurs during a resolution, and raising the error itself.

      Raises:

        Exception – The error occurred during the resolution.

      Returns:

        A `dict` containing all the resolved, unproxied, values.

    unresolve() → None

      Unresolve all values of the proxies inside this dictionary.

  sources: list[Source]

    Collection of sources to use for values of this configuration.

  proxies: ProxyDict

    Dictionary mapping configuration keys belonging to this `Configuration` to the proxy caching their values.

    Typed with `typing.Any` so that proxies can be typed as the object they cache.

  docs: dict[str, str]

    Dictionary mapping configuration keys belonging to this `Configuration` to a description of what they should contain.

  optional(key: str | None = None, doc: str | None = None) → Callable[[Callable[[str | None], TYPE]], TYPE]

    Mark a function as a resolver for a required configuration value.

    It is a decorator factory, and therefore should be used like so:

        @config.optional()
        def MY_KEY(val: str) -> str:
            return val

    Key can be overridden manually with the `key` parameter.

    Docstring can be overridden manually with the `doc` parameter.

  required(key: str | None = None, doc: str | None = None) → Callable[[Callable[[str], TYPE]], TYPE]

    Mark a function as a resolver for a required configuration value.

    It is a decorator factory, and therefore should be used like so:

        @config.required()
        def MY_KEY(val: str) -> str:
            return val

    Key can be overridden manually with the `key` parameter.

    Docstring can be overridden manually with the `doc` parameter.

  register(key, proxy, doc)

    Register a new proxy in this Configuration.

    Parameters:

      - key – The configuration key to register the proxy to.

      - proxy – The proxy to register in `proxies`.

      - doc – The docstring to register in `docs`.

    Raises:

      .errors.DuplicateProxyNameError` – if the key already exists in either `proxies` or `docs`.

  cli()

    Run the command-line interface.

## `cfig.errors`

This module contains all possible exceptions occurring related to `cfig`.

exception cfig.errors.CfigError

  Bases: `Exception`

  Base class for all `cfig` errors.

exception cfig.errors.DeveloperError

  Bases: `CfigError`

  A developer-side error: the user has no way to solve it.

exception cfig.errors.DefinitionError

  Bases: `DeveloperError`

  An error is present in the definition of a `cfig.Configuration`.

exception cfig.errors.UnknownResolverNameError

  Bases: `DefinitionError`

  It was not possible to get the name of the resolver.

  Perhaps a call to `functools.wraps()` is missing?

exception cfig.errors.ProxyRegistrationError

  Bases: `DefinitionError`

  An error occurred during the proxy registration step.

exception cfig.errors.DuplicateProxyNameError

  Bases: `ProxyRegistrationError`

  Another proxy with the same name is already registered.

exception cfig.errors.UserError

  Bases: `CfigError`

  A user-side error: the developer of the application has no way to fix it.

exception cfig.errors.ConfigurationError

  Bases: `UserError`

  An error is present in the configuration specified by the user.

exception cfig.errors.MissingValueError

  Bases: `ConfigurationError`

  A required configuration key has no value.

exception cfig.errors.InvalidValueError

  Bases: `ConfigurationError`

  A configuration key has an invalid value.

  This error should be raised by the developer in resolvers if the developer knows that a invalid value has been passed, for example:

      @config.required()
      def INTEGER(val):
          try:
              return int(val)
          except ValueError:
              raise InvalidValueError("Not an int.")

  It is not raised automatically, as certain errors might be caused by a mistake in the programming of the resolver.

exception cfig.errors.BatchResolutionFailure(errors: dict[str, Exception])

  Bases: `BaseException`

  A cumulative error which sums the errors occurred while resolving proxied configuration values.

  It inherits from `BaseException` to be distinguishable from regular :class:`Exception`s occouring inside the resolvers.

  It uses some formatting tricks to display the missing keys in the configuration error message:

      $ python -m cfig.sample.usage
      Traceback (most recent call last):
        ...
        File "./cfig/sample/usage.py", line 7, in <module>
          config.proxies.resolve()
        File "./cfig/config.py", line 59, in resolve
          raise errors.BatchResolutionFailure(errors=errors_dict)
      cfig.errors.BatchResolutionFailure: 4 errors occurred during the resolution of the config:
      * EXAMPLE_NUMBER        → InvalidValueError: Not an int.
      * TELEGRAM_BOT_TOKEN    → MissingValueError: TELEGRAM_BOT_TOKEN
      * DISCORD_CLIENT_SECRET → MissingValueError: DISCORD_CLIENT_SECRET
      * DATABASE_URI          → MissingValueError: DATABASE_URI

exception cfig.errors.MissingDependencyError

  Bases: `CfigError`

  An optional dependency has not been installed, but it is required by a called function.

## `cfig.sources.base`

This module defines the `Source` abstract class.

class cfig.sources.base.Source

  A source of values to be tapped by configurations.

  Abstract class. Cannot be instantiated. Should be inherited from other source classes.

  Other packages can add more sources directly to the `cfig.sources` namespace package.

  abstractmethod get(key: str) → str | None

    Get the value with the given key from the source.

## `cfig.sources.env`

This module defines the `EnvironmentSource` `Source`.

class cfig.sources.env.EnvironmentSource(*, prefix: str = '', suffix: str = '', environment=None)

  Bases: `Source`

  A source which gets values from environment variables.

  prefix: str

    The prefix to be prepended to all environment variable names.

    For example, `PROD_` for production environment variables.

  suffix: str

    The suffix to be appended to all environment variable names.

    For example, `_VAL` for raw values.

  environment

    The environment to retrieve variable values from.

    Defaults to `os.environ`.

  get(key: str) → str | None

    Get the value with the given key from the source.

## `cfig.sources.envfile`

This module defines the `EnvironmentFileSource` `Source`.

class cfig.sources.envfile.EnvironmentFileSource(*, prefix: str = '', suffix: str = '_FILE', environment=None)

  Bases: `EnvironmentSource`

  A source which gets values from files at paths specified in environment variables.

  Useful for example with Docker Secrets.

  get(key: str) → str | None

    Get the value with the given key from the source.