Skip to main content

Typed Settings

Load and merge settings from multiple different sources and present them in a structured, typed, and validated way!

Why?

There are many different config file formats and libraries. Many of them have a narrow scope, don't integrate well with other libs, or lack in typing support.

Typed Settings' goal is to enable you to load settings from any source (e.g., env vars, config files, vaults) and can convert values to anything you need.

You can extend Typed Settings to support config sources that aren't supported yet and its extensive documentation will help you on your way.

What can it be used for?

You can use Typed Settings in any context, e.g.:

  • server processes
  • containerized apps
  • command line applications
  • scripts and tools for scientific experiments and data analysis

What does it do?

  • It loads settings from multiple sources (e.g., env vars, config files, secret vaults) in a unified way and merges the loaded values. You can add loaders for sources we cannot imagine yet.

  • It can post-process loaded values. This allows value interpolation/templating or calling helpers that retrieve secrets from vaults. You can create and add any processors you can image if the built-in ones are not enough.

  • You can add a CLI on top to let users update the loaded settings via command line arguments. Click and argparse are currently supported.

  • Settings are cleanly structured and typed. The type annotations are used to convert the loaded settings to the proper types. This also includes higher level structures like dates, paths and various collections (lists, dicts, …). You can use attrs, dataclasses, or Pydantic to write settings classes.

    Types Settings uses the powerful and fast cattrs) by default and falls back to an internal converter if cattrs is not installed.

  • No mandatory requirements. Typed Settings works out-of-the box with dataclasses, argparse and its own converter.

The documentation contains a full list of all features.

Installation

Install and update using pip:

$ python -m pip install typed-settings

Typed Settings as no required dependencies (except for tomli on older Python versions). You can install dependencies for optional features via

$ python -m pip install typed-settings[<feature>,...]

Available features:

  • typed-settings[attrs]: Enable settings classes via attrs.
  • typed-settings[pydantic]: Enable settings classes via Pydantic.
  • typed-settings[cattrs]: Enable usage of the powerful and fast cattrs converter.
  • typed-settings[click]: Enable support for Click options.
  • typed-settings[option-groups]: Enable support for Click and Click option groups.
  • typed-settings[dotenv]: Enable support for reading .env files via python-dotenv.
  • typed-settings[orjson]: Use orjson instead of the built-in json module for loading JSON files.
  • typed-settings[yaml]: Enable support for loading YAML files.
  • typed-settings[jinja]: Enable support for value interpolation with Jinja templates.
  • typed-settings[all]: Install all optional requirements.

Examples

Hello, World!, with env. vars.

This is a very simple example that demonstrates how you can load settings from environment variables.

# example.py
import attrs
import typed_settings as ts

@attrs.frozen
class Settings:
    option: str

settings = ts.load(cls=Settings, appname="example")
print(settings)
$ EXAMPLE_OPTION="Hello, World!" python example.py
Settings(option='Hello, World!')

Nested classes and config files

Settings classes can be nested. Config files define a different section for each class.

# example.py
import attrs
import click

import typed_settings as ts

@attrs.frozen
class Host:
    name: str
    port: int

@attrs.frozen
class Settings:
    host: Host
    endpoint: str
    retries: int = 3

settings = ts.load(
    cls=Settings, appname="example", config_files=["settings.toml"]
)
print(settings)
# settings.toml
[example]
endpoint = "/spam"

[example.host]
name = "example.com"
port = 443
$ python example.py
Settings(host=Host(name='example.com', port=443), endpoint='/spam', retries=3)

Configurable settings loaders

The first example used a convenience shortcut with pre-configured settings loaders. However, Typed Settings lets you explicitly configure which loaders are used and how they work:

# example.py
import attrs
import typed_settings as ts

@attrs.frozen
class Settings:
    option: str

settings = ts.load_settings(
    cls=Settings,
    loaders=[
        ts.FileLoader(
            files=[],
            env_var="EXAMPLE_SETTINGS",
            formats={
                "*.toml": ts.TomlFormat("example"),
            },
        ),
        ts.EnvLoader(prefix="EXAMPLE_"),
      ],
)
print(settings)
$ EXAMPLE_OPTION="Hello, World!" python example.py
Settings(option='Hello, World!')

In order to write your own loaders or support new file formats, you need to implement the Loader or FileFormat protocols.

You can also pass a custom cattrs converter to add support for additional Python types.

Command Line Interfaces

Typed Settings can generate a command line interfaces (CLI) based on your settings. These CLIs will load settings as described above and let users override the loades settings with command line argumments.

Typed Settings supports argparse and click.

Argparse

# example.py
import attrs
import typed_settings as ts

@attrs.frozen
class Settings:
    a_str: str = ts.option(default="default", help="A string")
    an_int: int = ts.option(default=3, help="An int")

@ts.cli(Settings, "example")
def main(settings):
    print(settings)

if __name__ == "__main__":
    main()
$ python example.py --help
usage: example.py [-h] [--a-str TEXT] [--an-int INT]

options:
  -h, --help    show this help message and exit

Settings:
  Settings options

  --a-str TEXT  A string [default: default]
  --an-int INT  An int [default: 3]
$ python example.py --a-str=spam --an-int=1
Settings(a_str='spam', an_int=1)

Click

# example.py
import attrs
import click
import typed_settings as ts

@attrs.frozen
class Settings:
    a_str: str = ts.option(default="default", help="A string")
    an_int: int = ts.option(default=3, help="An int")

@click.command()
@ts.click_options(Settings, "example")
def main(settings):
    print(settings)

if __name__ == "__main__":
    main()
$ python example.py --help
Usage: example.py [OPTIONS]

Options:
  --a-str TEXT      A string  [default: default]
  --an-int INTEGER  An int  [default: 3]
  --help            Show this message and exit.
$ python example.py --a-str=spam --an-int=1
Settings(a_str='spam', an_int=1)

Project Links

Metadata

Release files for typed-settings 26.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for typed-settings 26.0.0
File Size Uploaded
typed_settings-26.0.0.tar.gz 3.5 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for typed-settings 26.0.0
File Interpreter ABI Platform
typed_settings-26.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 3.6 MB

Release files / typed_settings-26.0.0.tar.gz

Download URL typed_settings-26.0.0.tar.gz
Size 3.5 MB
Tags Source
SHA-256 checksum
How to use checksums
88d0da33e440a0419f194e24b92ecce4c12e7c165b5b96697fe4140c83d386ea
BLAKE2b-256 checksum
How to use checksums
f0e0e218ac603b238b8860f4282abbb74a842a9c645fe1138283c2ca3115b86b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / typed_settings-26.0.0-py3-none-any.whl

Download URL typed_settings-26.0.0-py3-none-any.whl
Size 66.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5ab31409af33d7912f02df51b38d66738e0dc990c042ce1b45a6b30dc9caba04
BLAKE2b-256 checksum
How to use checksums
e952c293cdd51731f23ddbc1764974934f6ac2ae4575e594fd9d8edcfb35b892
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

26.0.0 This release

2 release files

25.3.0

2 release files

25.2.0

2 release files

25.1.0

2 release files

25.0.0

2 release files

24.2.0

2 release files

24.1.0

2 release files

24.0.1

2 release files

24.0.0

2 release files

23.1.1

2 release files

23.1.0

2 release files

23.0.1

2 release files

2.0.2

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.10.0

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9

2 release files

0.8

2 release files

0.7

2 release files

0.6

2 release files

0.5

2 release files

0.4

2 release files

0.3

2 release files

0.2

2 release files

0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page