Package: typed-settings
Typed SettingsLoad 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 processescontainerized appscommand line applicationsscripts and tools for scientific experiments and data analysisWhat 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.Clickandargparseare 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 useattrs,dataclasses, orPydanticto write settings classes.Types Settings uses the powerful and fastcattrs) by default and falls back to an internal converter ifcattrsis not installed.No mandatory requirements.  Typed Settings works out-of-the box with dataclasses, argparse and its own converter.The documentation contains afull listof all features.InstallationInstall and update usingpip:$python-mpipinstalltyped-settingsTyped Settings asno required dependencies(except for tomli on older Python versions).
You can install dependencies for optional features via$python-mpipinstalltyped-settings[<feature>,...]Available features:typed-settings[attrs]: Enable settings classes viaattrs.typed-settings[pydantic]: Enable settings classes viaPydantic.typed-settings[cattrs]: Enable usage of the powerful and fastcattrsconverter.typed-settings[click]: Enable support forClickoptions.typed-settings[option-groups]: Enable support forClickandClick option groups.typed-settings[jinja]: Enable support for value interpolation withJinjatemplates.typed-settings[all]: Install all optional requirements.ExamplesHello, World!, with env. vars.This is a very simple example that demonstrates how you can load settings from environment variables.# example.pyimportattrsimporttyped_settingsasts@attrs.frozenclassSettings:option:strsettings=ts.load(cls=Settings,appname="example")print(settings)$EXAMPLE_OPTION="Hello, World!"pythonexample.pySettings(option='Hello, World!')Nested classes and config filesSettings classes can be nested.
Config files define a different section for each class.# example.pyimportattrsimportclickimporttyped_settingsasts@attrs.frozenclassHost:name:strport:int@attrs.frozenclassSettings:host:Hostendpoint:strretries:int=3settings=ts.load(cls=Settings,appname="example",config_files=["settings.toml"])print(settings)# settings.toml[example]endpoint="/spam"[example.host]name="example.com"port=443$pythonexample.pySettings(host=Host(name='example.com', port=443), endpoint='/spam', retries=3)Configurable settings loadersThe 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.pyimportattrsimporttyped_settingsasts@attrs.frozenclassSettings:option:strsettings=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!"pythonexample.pySettings(option='Hello, World!')In order to write your own loaders or support new file formats, you need to implement theLoaderorFileFormatprotocols.You can also pass a customcattrs converterto add support for additional Python types.Command Line InterfacesTyped 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 supportsargparseandclick.Argparse# example.pyimportattrsimporttyped_settingsasts@attrs.frozenclassSettings:a_str:str=ts.option(default="default",help="A string")an_int:int=ts.option(default=3,help="An int")@ts.cli(Settings,"example")defmain(settings):print(settings)if__name__=="__main__":main()$pythonexample.py--helpusage: example.py [-h] [--a-str TEXT] [--an-int INT]options:-h, --help    show this help message and exitSettings:Settings options--a-str TEXT  A string [default: default]--an-int INT  An int [default: 3]$pythonexample.py--a-str=spam--an-int=1Settings(a_str='spam', an_int=1)Click# example.pyimportattrsimportclickimporttyped_settingsasts@attrs.frozenclassSettings: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")defmain(settings):print(settings)if__name__=="__main__":main()$pythonexample.py--helpUsage: example.py [OPTIONS]Options:--a-str TEXT      A string  [default: default]--an-int INTEGER  An int  [default: 3]--help            Show this message and exit.$pythonexample.py--a-str=spam--an-int=1Settings(a_str='spam', an_int=1)Project LinksChangelogDocumentationGitLabIssues and BugsPyPI