Stefan Scherfke

Typed Settings

There are already several settings libraries like Dynaconf, Environ Config, or Pydantic – just to name a few. I have written a new one: Typed Settings.

What makes it different?

Settings are defined as type-hinted, immutable (frozen) attrs classes. Values are automatically converted to the proper type when they are loaded. Apart from simple data types, Typed Settings supports datetimes, enums, nested attrs classes and various container types (like lists). The auto-converter can be extended to handle additional types.

Settings can be loaded from multiple config files. Config files can contain settings for multiple apps (like pyproject.toml). Different deployment environments use different config files (this is in contrast to Dynaconf, where a single config file specifies the settings for all environments in different sections). Currently, only TOML is supported. Support for YAML or .env may follow later.

Value interpolation as in Dynaconf is not yet supported, but planned.

Search paths for config files have to be explicitly stated – either directly in the app or via an environment variable.

Environment variables can also be used to override settings. The prefix is customizable and this feature can also be disabled.

Finally, Typed Settings can generate Click options for command line applications. You CLI function will receive all options nicely packed together as a single instance of your settings class.

Specialized secrets stores like HashiCorp Vault are not (yet?) supported.

Invalid values or undefined options in config files raise an error instead of being silently ignored. Config files can optionally be marked as mandatory and an error will be raised if such a file cannot be found.

To aid with debugging, Typed Settings uses Python’s logging module to log config files that are being loaded (or that cannot be found) as well as looked up env vars.

Everything is thoroughly tested, the test coverage is at 100%.

An Example

Here is a very simple example that demonstrates how you can load settings from a statically defined config file and from environment variables:

# example.py
import typed_settings as ts

@ts.settings
class Settings:
    option_one: str
    option_two: int

settings = ts.load_settings(
    cls=Settings,
    appname="example",
    config_files=["settings.py"],  # Paths can also be set via env var
)
print(settings)
# settings.toml
[example]
option_one = "value"
$ EXAMPLE_OPTION_TWO=2 python example.py
Settings(option_one="value", option_two=2)

The README and documentation contain more examples.

Project Status

The recently released version 0.9 contains all features that are planed for version 1.0.0. Additional features are already on the roadmap.

What’s missing for the first stable release is mainly documentation as well as more real life testing. I already use Typed Settings for a few projects in our company and will perspectively try to replace our old settings system with it.