API Reference#

This is the full list of all public classes and functions.

Core#

Core functions for loading and working with settings.

Functions#

typed_settings.load(cls: Type[ST], appname: str, config_files: Iterable[str | Path] = (), *, config_file_section: str | _Auto = AUTO, config_files_var: None | str | _Auto = AUTO, env_prefix: None | str | _Auto = AUTO, env_nested_delimiter: str = '_', base_dir: Path = PosixPath('.')) ST[source]#

Load settings for appname and return an instance of cls.

This function is a shortcut for load_settings() with default_loaders().

Settings are loaded from config_files and from the files specified via the config_files_var environment variable. Settings can also be overridden via environment variables named like the corresponding setting and prefixed with env_prefix.

Settings precedence (from lowest to highest priority):

  • Default value from cls

  • First file from config_files

  • Last file from config_files

  • First file from config_files_var

  • Last file from config_files_var

  • Environment variable {env_prefix}_{SETTING}

Config files (both, explicitly specified, and loaded from an environment variable) are optional by default. You can prepend an ! to their path to mark them as mandatory (e.g., !/etc/credentials.toml). An error is raised if a mandatory file does not exist.

Parameters:
  • cls – Attrs class with default settings.

  • appname – Your application’s name. Used to derive defaults for the remaining args.

  • config_files – Load settings from these files.

  • config_file_section – Name of your app’s section in the config file. By default, use appname (in lower case and with “_” replaced by “-“.

  • config_files_var

    Load list of settings files from this environment variable. By default, use {APPNAME}_SETTINGS. Multiple paths have to be separated by “:”. The last file has the highest precedence. All files listed in this var have higher precedence than files from config_files.

    Set to None to disable this feature.

  • env_prefix

    Load settings from environment variables with this prefix. By default, use APPNAME_.

    Set to None to disable loading env vars.

  • env_nested_delimiter – Delimiter for concatenating attribute names of nested classes in env. var. names.

  • base_dir – Base directory for resolving relative paths in default option values.

Returns:

An instance of cls populated with settings from settings files and environment variables.

Raises:

Changed in version 23.1.0: Added the base_dir argument

typed_settings.load_settings(cls: Type[ST], loaders: Sequence[Loader], *, processors: Sequence[Processor] = (), converter: Converter | None = None, base_dir: Path = PosixPath('.')) ST[source]#

Load settings defined by the class cls and return an instance of it.

Parameters:
  • cls – Attrs class with options (and default values).

  • loaders – A list of settings Loader’s.

  • processors – A list of settings Processor’s.

  • converter

    An optional Converter used for converting option values to the required type.

    By default, default_converter() is used.

  • base_dir – Base directory for resolving relative paths in default option values.

Returns:

An instance of cls populated with settings from the defined loaders.

Raises:

TsError – Depending on the configured loaders, any subclass of this exception.

Changed in version 23.0.0: Made converter a keyword-only argument

Changed in version 23.0.0: Added the processors argument

Changed in version 23.1.0: Added the base_dir argument

typed_settings.default_loaders(appname: str, config_files: Iterable[str | Path] = (), *, config_file_section: str | _Auto = AUTO, config_files_var: None | str | _Auto = AUTO, env_prefix: None | str | _Auto = AUTO, env_nested_delimiter: str = '_') List[Loader][source]#

Return a list of default settings loaders that are used by load().

These loaders are:

  1. A FileLoader loader configured with the TomlFormat

  2. An EnvLoader

The FileLoader will load files from config_files and from the environment variable config_files_var.

Parameters:
  • appname – Your application’s name – used to derive defaults for the remaining args.

  • config_files – Load settings from these files. The last one has the highest precedence.

  • config_file_section – Name of your app’s section in the config file. By default, use appname (in lower case and with “_” replaced by “-“.

  • config_files_var

    Load list of settings files from this environment variable. By default, use {APPNAME}_SETTINGS. Multiple paths have to be separated by “:”. The last file has the highest precedence. All files listed in this var have higher precedence than files from config_files.

    Set to None to disable this feature.

  • env_prefix

    Load settings from environment variables with this prefix. By default, use APPNAME_.

    Set to None to disable loading env vars.

  • env_nested_delimiter – Delimiter for concatenating attribute names of nested classes in env. var. names.

Returns:

A list of Loader instances.

typed_settings.find(filename: str, stop_dir: str | Path = '/', stop_files: Iterable[str] = ('.git', '.hg'), *, start_dir: Path | None = None) Path[source]#

Search for a file in the current directory and its parents and return its path.

If the file cannot be found until stop_dir is reached or a directory contains stop_file, return the input filename.

Parameters:
  • filename – The name of the file to find.

  • stop_dir – Stop searching if the current search dir equals this one.

  • stop_files – Stop searching if the current search dir contains this file.

  • start_dir – Start directory for the search, defaults to the current directory.

Returns:

The resolved path to filename if found, else Path(filename).

Examples

Find settings.toml until the root of the current directory is reached:

find("settings.py")

Find pyproject.toml only in the current Git project:

find("pyproject.toml", stop_file=".git")

Changed in version 23.1.0: Added the start_dir parameter.

typed_settings.convert(merged_settings: Dict[str, LoadedValue], state: SettingsState[ST]) ST[source]#

Create an instance of cls from the settings in merged_settings.

Parameters:
  • merged_settings – The loaded and merged settings by settings name.

  • state – The state and configuration for this run.

Returns:

An instance of cls.

Raises:

InvalidSettingsError – If an instance of cls cannot be created for the given settings.

Classes#

class typed_settings.SettingsState(settings_cls: Type[ST], loaders: Sequence[Loader], processors: Sequence[Processor], converter: Converter, base_dir: Path)[source]#

A representation of Typed Settings’ internal state and configuration.

Aliases#

Aliases for more convenient imports.

class typed_settings.Secret[source]#

Alias for typed_settings.types.Secret

class typed_settings.SecretStr[source]#

Alias for typed_settings.types.SecretStr

typed_settings.settings()#

Alias for typed_settings.cls_attrs.settings()

typed_settings.option()[source]#

Alias for typed_settings.cls_attrs.option()

typed_settings.secret()[source]#

Alias for typed_settings.cls_attrs.secret()

typed_settings.evolve()[source]#

Alias for typed_settings.cls_attrs.evolve()

typed_settings.combine()[source]#

Alias for typed_settings.cls_attrs.combine()

typed_settings.default_converter()[source]#

Alias for typed_settings.converters.default_converter()

typed_settings.register_strlist_hook()[source]#

Alias for typed_settings.converters.register_strlist_hook()

typed_settings.cli()[source]#

Alias for typed_settings.cli_argparse.cli().

typed_settings.click_options()[source]#

Alias for typed_settings.cli_click.click_options().

typed_settings.pass_settings()[source]#

Alias for typed_settings.cli_click.pass_settings().

Dict Utils#

Utility functions for working settings dicts and serilizing nested settings.

typed_settings.dict_utils.iter_settings(dct: Dict[str, Any | Dict[str, Any | SettingsDict]], options: Tuple[OptionInfo, ...]) Generator[Tuple[str, Any], None, None][source]#

Iterate over the (possibly nested) options dict dct and yield (option_path, value) tuples.

Parameters:
  • dct – The dict of settings as returned by a loader.

  • options – The list of all available options for a settings class.

Returns:

A generator yield (opton_path, value) tuples.

typed_settings.dict_utils.get_path(dct: Dict[str, Any | Dict[str, Any | SettingsDict]], path: str) Any[source]#

Performs a nested dict lookup for path and returns the result.

Calling get_path(dct, "a.b") is equivalent to dict["a"]["b"].

Parameters:
  • dct – The source dict

  • path – The path to look up. It consists of the dot-separated nested keys.

Returns:

The looked up value.

Raises:

KeyError – if a key in path does not exist.

typed_settings.dict_utils.set_path(dct: Dict[str, Any | Dict[str, Any | SettingsDict]], path: str, val: Any) None[source]#

Sets a value to a nested dict and automatically creates missing dicts should they not exist.

Calling set_path(dct, "a.b", 3) is equivalent to dict["a"]["b"] = 3.

Parameters:
  • dct – The dict that should contain the value

  • path – The (nested) path, a dot-separated concatenation of keys.

  • val – The value to set

typed_settings.dict_utils.merge_settings(options: Tuple[OptionInfo, ...], settings: Sequence[LoadedSettings]) Dict[str, LoadedValue][source]#

Merge a sequence of settings dicts to a flat dict that maps option paths to the corresponding option values.

Parameters:
  • options – The list of all available options.

  • settings – A sequence of loaded settings.

Returns:

A dict that maps option paths to LoadedValue instances.

The simplified input settings look like this:

[
    ("loader a", {"spam": 1, "eggs": True}),
    ("loader b", {"spam": 2, "nested": {"x": "test"}}),
]

The simpliefied output looks like this:

{
    "spam": ("loader b", 2),
    "eggs": ("loader a", True),
    "nested.x": ("loader b", "test"),
}
typed_settings.dict_utils.update_settings(merged_settings: Dict[str, LoadedValue], settings: Dict[str, Any | Dict[str, Any | SettingsDict]]) Dict[str, LoadedValue][source]#

Return a copy of merged_settings updated with the values from settings.

The loader meta data is not changed.

Parameters:
  • merged_settings – The merged settnigs dict to be updated.

  • settings – The settings dict with additional values.

Returns:

A copy of the input merged settings updated with the values from settings.

typed_settings.dict_utils.flat2nested(merged_settings: Dict[str, LoadedValue]) Dict[str, Any | Dict[str, Any | SettingsDict]][source]#

Convert the flat merged_settings to a nested settings dict.

Exceptions#

Exceptions raised by Typed Settings.

exception typed_settings.exceptions.TsError[source]#

Basse class for all typed settings exceptions.

exception typed_settings.exceptions.UnknownFormatError[source]#

Raised when no file format loader is configured for a given config file.

exception typed_settings.exceptions.ConfigFileNotFoundError[source]#

Raised when a mandatory config file does not exist.

exception typed_settings.exceptions.ConfigFileLoadError[source]#

Raised when a config file exists but cannot be read or parsed/loaded.

exception typed_settings.exceptions.InvalidOptionsError[source]#

Raised when loaded settings contain an option that is not defined in the settings class.

exception typed_settings.exceptions.InvalidValueError[source]#

Raised the value of an option cannot be converted to the correct type.

exception typed_settings.exceptions.InvalidSettingsError[source]#

Raised when the loaded settings cannot be converted to an instances of the settings class.

Loaders#

This module contains the settings loaders provided by Typed Settings and the protocol specification that they must implement.

class typed_settings.loaders.Loader(*args, **kwargs)[source]#

Protocol that settings loaders must implement.

Loaders must be callables (e.g., functions) with the specified signature.

Changed in version 1.0.0: Renamed load() to __call__() and also pass the settings class.

__call__(settings_cls: type, options: Tuple[OptionInfo, ...]) LoadedSettings | Iterable[LoadedSettings][source]#

Load settings for the given options.

Parameters:
  • settings_cls – The base settings class for all options.

  • options – The list of available settings.

Returns:

A dict with the loaded settings.

class typed_settings.loaders.DictLoader(settings: dict)[source]#

Load settings from a dict of values.

This is mainly for testing purposes.

Parameters:

settings – A (nested) dict of settings

New in version 23.1.0.

__call__(settings_cls: type, options: Tuple[OptionInfo, ...]) LoadedSettings[source]#

Load settings for the given options.

Parameters:
  • options – The list of available settings.

  • settings_cls – The base settings class for all options.

Returns:

A dict with the loaded settings.

class typed_settings.loaders.InstanceLoader(instance: object)[source]#

Load settings from an instance of the settings class.

Parameters:

instance – The settings instance from which to load option values.

New in version 1.0.0.

__call__(settings_cls: type, options: Tuple[OptionInfo, ...]) LoadedSettings[source]#

Load settings for the given options.

Parameters:
  • options – The list of available settings.

  • settings_cls – The base settings class for all options.

Returns:

A dict with the loaded settings.

class typed_settings.loaders.EnvLoader(prefix: str, nested_delimiter: str = '_')[source]#

Load settings from environment variables.

Parameters:
  • prefix – Prefix for environment variables, e.g., MYAPP_.

  • nested_delimiter – Delimiter for attribute names of nested classes.

__call__(settings_cls: type, options: Tuple[OptionInfo, ...]) LoadedSettings[source]#

Load settings for the given options.

Parameters:
  • options – The list of available settings.

  • settings_cls – The base settings class for all options.

Returns:

A dict with the loaded settings.

get_envvar(option: OptionInfo) str[source]#

Return the envvar name for the he given option.

class typed_settings.loaders.FileLoader(formats: Dict[str, FileFormat], files: Iterable[str | Path], env_var: str | None = None)[source]#

Load settings from config files.

Settings of multiple files will be merged. The last file has the highest precedence. Files specified via an environment variable are loaded after the files passed to this class, i.e.:

  • First file from files

  • Last file from files

  • First file from env_var

  • Last file from env_var

Mandatory files can be prefixed with !. Optional files will be ignored if they don’t exist.

Parameters:
  • formats – A dict mapping glob patterns to FileFormat instances.

  • files – A list of filenames to try to load.

  • env_var – Name of the environment variable that may hold additional file paths. If it is None, only files from files will be loaded.

__call__(settings_cls: type, options: Tuple[OptionInfo, ...]) List[LoadedSettings][source]#

Load settings for the given options.

Parameters:
  • options – The list of available settings.

  • settings_cls – The base settings class for all options.

Returns:

A dict with the loaded settings.

Raises:
class typed_settings.loaders.FileFormat(*args, **kwargs)[source]#

Protoco that file format loaders for FileLoader must implement.

File format loaders must be callables (e.g., functions) with the specified signature.

Changed in version 1.0.0: Renamed load_file() to __call__() and also pass the settings class.

__call__(path: Path, settings_cls: type, options: Tuple[OptionInfo, ...]) Dict[str, Any | Dict[str, Any | SettingsDict]][source]#

Load settings from a given file and return them as a dict.

Parameters:
  • path – The path to the config file.

  • settings_cls – The base settings class for all options.

  • options – The list of available settings.

Returns:

A dict with the loaded settings.

Raises:
class typed_settings.loaders.PythonFormat(cls_name: str | None, key_transformer: ~typing.Callable[[str], str] = <function PythonFormat.<lambda>>, flat: bool = False)[source]#

Support for Python files. Read settings from the given section.

Parameters:

section – The config file section to load settings from.

static to_lower(text: str) str[source]#

Transform text to lower case.

__call__(path: Path, settings_cls: type, options: Tuple[OptionInfo, ...]) Dict[str, Any | Dict[str, Any | SettingsDict]][source]#

Load settings from a Python file and return them as a dict.

Parameters:
  • path – The path to the config file.

  • options – The list of available settings.

  • settings_cls – The base settings class for all options. If None, load directly from the module instead.

Returns:

A dict with the loaded settings.

Raises:
class typed_settings.loaders.TomlFormat(section: str | None)[source]#

Support for TOML files. Read settings from the given section.

Parameters:

section – The config file section to load settings from.

__call__(path: Path, settings_cls: type, options: Tuple[OptionInfo, ...]) Dict[str, Any | Dict[str, Any | SettingsDict]][source]#

Load settings from a TOML file and return them as a dict.

Parameters:
  • path – The path to the config file.

  • options – The list of available settings.

  • settings_cls – The base settings class for all options. If None, load top level settings.

Returns:

A dict with the loaded settings.

Raises:
class typed_settings.loaders.OnePasswordLoader(item: str, vault: str | None = None)[source]#

Load settings from an item stored in a 1Password vault.

You must must have installed and set up the 1Password CLI in order for this loader to work.

Parameters:
  • item – The item to load

  • vault – The vault in which to look for item. By default, search all vaults.

__call__(settings_cls: type, options: Tuple[OptionInfo, ...]) LoadedSettings[source]#

Load settings for the given options.

Parameters:
  • options – The list of available settings.

  • settings_cls – The base settings class for all options.

Returns:

A dict with the loaded settings.

typed_settings.loaders.clean_settings(settings: Dict[str, Any | Dict[str, Any | SettingsDict]], options: Tuple[OptionInfo, ...], source: Any) Dict[str, Any | Dict[str, Any | SettingsDict]][source]#

Recursively check settings for invalid entries and raise an error.

An error is not raised until all options have been checked. It then lists all invalid options that have been found.

Parameters:
  • settings – The settings to be cleaned.

  • options – The list of available settings.

  • source – Source of the settings (e.g., path to a config file). It should have a useful string representation.

Returns:

The cleaned settings.

Raises:

InvalidOptionsError – If invalid settings have been found.

Processors#

This module contains the settings processors provided by Typed Settings and the protocol specification that they must implement.

class typed_settings.processors.Protocol[source]#

Base class for protocol classes.

Protocol classes are defined as:

class Proto(Protocol):
    def meth(self) -> int:
        ...

Such classes are primarily used with static type checkers that recognize structural subtyping (static duck-typing).

For example:

class C:
    def meth(self) -> int:
        return 0

def func(x: Proto) -> int:
    return x.meth()

func(C())  # Passes static type check

See PEP 544 for details. Protocol classes decorated with @typing.runtime_checkable act as simple-minded runtime protocols that check only the presence of given attributes, ignoring their type signatures. Protocol classes can be generic, they are defined as:

class GenProto(Protocol[T]):
    def meth(self) -> T:
        ...
class typed_settings.processors.UrlHandler(*args, **kwargs)[source]#

Protocol that handlers for UrlProcessor must implement.

Handlers must be callables (e.g., functions) with the specified signature.

New in version 23.0.0.

__call__(value: str, scheme: str) str[source]#

Handle the URL resource value and return the result.

Parameters:
  • value – The URL without the scheme (the v in s://v).

  • scheme – The URL scheme (the s://` in ``s://v).

Returns:

The result of the operation.

Raises:

ValueError – If the URL is invalid or another error occurs while handling the URL.

class typed_settings.processors.Processor(*args, **kwargs)[source]#

Protocol that settings processors must implement.

Processors must be callables (e.g., functions) with the specified signature.

New in version 23.0.0.

__call__(settings_dict: Dict[str, Any | Dict[str, Any | SettingsDict]], settings_cls: type, options: Tuple[OptionInfo, ...]) Dict[str, Any | Dict[str, Any | SettingsDict]][source]#

Modify or update values in settings_dict and return an updated version.

You may modify settings_dict in place - you don’t need to return a copy of it.

You should not add additional keys.

Parameters:
  • settings_dict – The dict of loaded settings. Values are not yet converted to the target type (e.g., int values loaded from an env var are still a string).

  • settings_cls – The base settings class for all options.

  • options – The list of available settings.

Returns:

The updated settings dict.

class typed_settings.processors.UrlProcessor(handlers: Dict[str, UrlHandler])[source]#

Modify values that match one of the configured URL schemes.

Parameters:

handlers – A dictionary mapping URL schemes to handler functions.

New in version 23.0.0.

handlers#

Registered URL scheme handlers.

You can modify this dict after an instance of this class has been created.

__call__(settings_dict: Dict[str, Any | Dict[str, Any | SettingsDict]], settings_cls: type, options: Tuple[OptionInfo, ...]) Dict[str, Any | Dict[str, Any | SettingsDict]][source]#

Modify or update values in settings_dict and return an updated version.

You may modify settings_dict in place - you don’t need to return a copy of it.

You should not add additional keys.

Parameters:
  • settings_dict – The dict of loaded settings. Values are not yet converted to the target type (e.g., int values loaded from an env var are still a string).

  • settings_cls – The base settings class for all options.

  • options – The list of available settings.

Returns:

The updated settings dict.

typed_settings.processors.handle_raw(value: str, scheme: str) str[source]#

URL handler: Return value unchanged.

New in version 23.0.0.

typed_settings.processors.handle_script(value: str, scheme: str) str[source]#

URL handler: Run value as shell script and return its output.

New in version 23.0.0.

typed_settings.processors.handle_op(value: str, scheme: str) str[source]#

URL handler: Retrieve the resource value from the 1Password CLI.

You must must have installed it and set it up in order for this to work.

New in version 23.0.0.

class typed_settings.processors.FormatProcessor[source]#

Perform value interpolation / templating via Python format strings.

Formatting is performed recursively as long as the value is a valid format string.

No exceptions are raised. If format strings are invalid or refer to non existing values, they are returned unchanged.

New in version 23.0.0.

__call__(settings_dict: Dict[str, Any | Dict[str, Any | SettingsDict]], settings_cls: type, options: Tuple[OptionInfo, ...]) Dict[str, Any | Dict[str, Any | SettingsDict]][source]#

Invoke the processor to render all values in the settings dict.

class typed_settings.processors.JinjaProcessor(environment: Environment | None = None)[source]#

Perform value templating with Jinja.

Rendering is performed recursively as long as the value is a valid Jinja template.

No exceptions are raised. If templates are invalid or refer to non existing values, they are returned unchanged.

Raises:

ModuleNotFoundError – If jinja2 is not installed.

New in version 23.0.0.

__call__(settings_dict: Dict[str, Any | Dict[str, Any | SettingsDict]], settings_cls: type, options: Tuple[OptionInfo, ...]) Dict[str, Any | Dict[str, Any | SettingsDict]][source]#

Invoke the processor to render all values in the settings dict.

render(value: Any, settings_dict: Dict[str, Any | Dict[str, Any | SettingsDict]]) Any[source]#

Recursively render value.

is_possibly_template(value: Any) bool[source]#

Guess if value may be format string.

It only detectecs if value is certainly not a format string and returns False in that case. If it returns True, it may or may not be a valid format string.

Converters#

Converters and structure hooks for various data types.

class typed_settings.converters.Converter(*args, **kwargs)[source]#

Protocol that converters must implement.

Only a structure() method similar to the one from cattrs is required.

New in version 23.1.0.

structure(value: Any, cls: Type[T]) T[source]#

Convert value to an instance of cls and return it.

Parameters:
  • value – The data to be converted.

  • cls – The type to convert value to.

Returns:

An instance of cls for value.

class typed_settings.converters.TSConverter(resolve_paths: bool = True, strlist_sep: str | Callable[[str], list] | None = ':')[source]#

A simple converter that can replace cattrs if you want to use Typed Settings without dependencies.

It supports the same types as the default cattrs converter.

structure(value: Any, cls: Type[T]) T[source]#

Convert value to an instance of cls and return it.

Parameters:
  • value – The data to be converted.

  • cls – The type to convert value to.

Returns:

An instance of cls for value.

maybe_apply_strlist_hook(value: T) list | T[source]#

Apply the string list hook to value if one is defined and if value is a string.

typed_settings.converters.default_converter(*, resolve_paths: bool = True) Converter[source]#

Get a default instances of a converter which will be used to convert/structured the loaded settings.

Parameters:

resolve_paths – Whether or not to resolve relative paths.

Returns:

If cattrs is installed, a cattrs.Converter. Else, a TSConverter. The converters are configured to handle the following types:

list, tuple, set, and frozenset set can also be converted from strings. By default, strings are split by :. See TSConverter or register_strlist_hook() for details.

This converter can also be used as a base for converters with custom structure hooks.

Changed in version 23.1.0: Return a cattrs converter if it is installed or else a Typed Settings converter.

typed_settings.converters.get_default_ts_converter(resolve_paths: bool = True) TSConverter[source]#

Return a TSConverter with default settings (see default_converter() for argument and return value description).

Parameters:

resolve_paths – Whether or not to resolve relative paths.

Returns:

A TSConverter instance with default configuration.

typed_settings.converters.get_default_cattrs_converter(resolve_paths: bool = True) cattrs.Converter[source]#

Return a cattrs.Converter with default settings (see default_converter() for argument and return value description).

Parameters:

resolve_paths – Whether or not to resolve relative paths.

Returns:

A cattrs.Converter instance with default configuration.

Raises:

ModuleNotFoundError – if cattrs is not installed.

typed_settings.converters.get_default_structure_hooks(*, resolve_paths: bool = True) List[Tuple[type, Callable[[Any, type], Any]]][source]#

Return a list of default structure hooks for cattrs.

Parameters:

resolve_paths – Whether or not to resolve relative paths.

Returns:

A list of tuples that can be used as args for cattrs.BaseConverter.register_structure_hook().

typed_settings.converters.register_attrs_hook_factory(converter: cattrs.Converter) None[source]#

Register a hook factory that allows using instances of attrs classes where cattrs would normally expect a dictionary.

These instances are then returned as-is and without further processing.

Parameters:

converter – The cattrs.Converter to register the hook at.

typed_settings.converters.register_dataclasses_hook_factory(converter: cattrs.Converter) None[source]#

Register a hook factory that allows using instances of dataclasses classes where cattrs would normally expect a dictionary.

These instances are then returned as-is and without further processing.

Parameters:

converter – The cattrs.Converter to register the hook at.

typed_settings.converters.register_pydantic_hook_factory(converter: cattrs.Converter) None[source]#

Register a hook factory that allows using instances of dataclasses classes where cattrs would normally expect a dictionary.

These instances are then returned as-is and without further processing.

Parameters:

converter – The cattrs.Converter to register the hook at.

typed_settings.converters.register_mappingproxy_hook(converter: cattrs.Converter) None[source]#

Register a hook factory for converting data to types.MappingProxyType instances.

Parameters:

converter – The cattrs.Converter to register the hook at.

typed_settings.converters.register_strlist_hook(converter: cattrs.Converter, sep: str | None = None, fn: Callable[[str], list] | None = None) None[source]#

Register a hook factory with converter that allows structuring lists, (frozen) sets and tuples from strings (which may, e.g., come from environment variables).

Parameters:
  • converter – The cattrs.Converter to register the hook at.

  • sep – A separator used for splitting strings (see str.split()). Cannot be used together with fn.

  • fn – A function that takes a string and returns a list, e.g., json.loads(). Cannot be used together with sep.

Example

>>> from typing import List
>>>
>>> converter = default_converter()
>>> register_strlist_hook(converter, sep=":")
>>> converter.structure("1:2:3", List[int])
[1, 2, 3]
>>>
>>> import json
>>>
>>> converter = default_converter()
>>> register_strlist_hook(converter, fn=json.loads)
>>> converter.structure("[1,2,3]", List[int])
[1, 2, 3]
typed_settings.converters.to_any(value: Any, _cls: type) Any[source]#

Return value as-is.

typed_settings.converters.to_bool(value: ~typing.Any, _cls: type = <class 'bool'>) bool[source]#

Convert “boolean” strings (e.g., from env. vars.) to real booleans.

Values mapping to True:

  • True

  • "true" / "t" (case insensitive)

  • "yes" / "y" (case insensitive)

  • "on" (case insensitive)

  • "1"

  • 1

Values mapping to False:

  • False

  • "false" / "f" (case insensitive)

  • "no" / "n" (case insensitive)

  • "off" (case insensitive)

  • "0"

  • 0

Parameters:
  • value – The value to parse.

  • _cls – (ignored)

Returns:

A bool for the input value.

Raises:

ValueError – If value is any other value than stated above.

typed_settings.converters.to_dt(value: ~datetime.datetime | str, _cls: type = <class 'datetime.datetime'>) datetime[source]#

Convert an ISO formatted string to datetime.datetime. Leave the input untouched if it is already a datetime.

See: datetime.datetime.fromisoformat()

The Z suffix is also supported and will be replaced with +00:00.

Parameters:
  • value – The input data

  • _cls – (ignored)

Returns:

The converted datetime instance

Raises:

TypeError – If val is neither a string nor a datetime

typed_settings.converters.to_enum(value: Any, cls: Type[ET]) ET[source]#

Return an instance of the enum cls for value.

If the to be converted value is not already an enum, the converter will create one by name (MyEnum[val]).

Parameters:
  • value – The input data

  • cls – The enum type

Returns:

An instance of cls

Raises:

KeyError – If value is not a valid member of cls

typed_settings.converters.to_path(value: Path | str, _cls: type) Path[source]#

Convert value to Path.

Parameters:
  • value – The input data

  • _cls – (ignored)

Returns:

An instance of Path

Raises:

TypeError – If value cannot be converted to a path.

typed_settings.converters.to_resolved_path(value: Path | str, _cls: type) Path[source]#

Convert value to Path and resolve it.

Parameters:
  • value – The input data

  • _cls – (ignored)

Returns:

A resolved instance of Path

Raises:

TypeError – If value cannot be converted to a path.

typed_settings.converters.to_type(value: Any, cls: Type[T]) T[source]#

Convert value to cls.

Parameters:
  • value – The input data

  • cls – A class that takes a single argument, e.g., int, float, or str.

Returns:

An instance of cls.

Raises:

ValueError – if value cannot be converted to cls.

typed_settings.converters.to_pydantic_secretbytes(value: Any, _cls: Type[pydantic.SecretBytes]) pydantic.SecretBytes[source]#

Convert value to pydantic.SecretStr.

Parameters:
  • value – The input data

  • _cls – (ignored)

Returns:

An instance of cls.

typed_settings.converters.to_pydantic_secretstr(value: Any, _cls: Type[pydantic.SecretStr]) pydantic.SecretStr[source]#

Convert value to pydantic.SecretStr.

Parameters:
  • value – The input data

  • cls – A pydantic SecretStr class or any subclass

  • _cls – (ignored)

Returns:

An instance of cls.

class typed_settings.converters.HookFactory(*args, **kwargs)[source]#

Protocol for TSConverter hook factories.

Hook factories have a match() functions that decides whether they can handle given type/class. In addition, they can generate a structure hook for that type.

static match(cls: type, origin: Any | None, args: Tuple[Any, ...]) bool[source]#

Check whether this class can handle the given type cls.

Parameters:
Returns:

True if this class can convert the given type, or else False.

static get_structure_hook(converter: TSConverter, cls: type, origin: Any | None, args: Tuple[Any, ...]) Callable[[Any, Type[T]], T][source]#

Return a structure hook for the given type/class.

Parameters:
  • converter – The TSConverter that the returned hook will be registered at. The structure hook can use the converter to recursively convert sub elements of composite types.

  • cls – The type/class to convert to.

  • origin – The type’s origin as returned by typing.get_origin().

  • args – The type’s args as retuned by typing.get_args().

Returns:

A structure hook, which is a function hook(value: Any, cls: Type[T]) -> T.

class typed_settings.converters.AttrsHookFactory[source]#

A HookFactory that returns attrs classes from dicts. Instances are of the given class are accepted as well and returned as-is (without further processing of their attributes).

class typed_settings.converters.DataclassesHookFactory[source]#

A HookFactory that returns dataclasses from dicts. Instances are of the given class are accepted as well and returned as-is (without further processing of their attributes).

class typed_settings.converters.PydanticHookFactory[source]#

A HookFactory that returns dataclasses from dicts. Instances are of the given class are accepted as well and returned as-is (without further processing of their attributes).

class typed_settings.converters.ListHookFactory[source]#

A HookFactory for list and typing.List.

class typed_settings.converters.TupleHookFactory[source]#

A HookFactory for tuple and typing.Tuple.

class typed_settings.converters.DictHookFactory[source]#

A HookFactory for dict and typing.Dict.

class typed_settings.converters.MappingProxyTypeHookFactory[source]#

A HookFactory for types.MappingProxyType (a read-only dict proxy).

class typed_settings.converters.SetHookFactory[source]#

A HookFactory for set and typing.Set.

class typed_settings.converters.FrozenSetHookFactory[source]#

A HookFactory for frozenset and typing.FrozenSet.

class typed_settings.converters.UnionHookFactory[source]#

A HookFactory for typing.Optional and typing.Union.

If the input data already has one of the uniton types, it will be returned without further processing. Otherwise, converters for all union types will be tried until one works (i.e., raises no exception).

Constants#

Global constants shared by different modules.

typed_settings.constants.SECRET_REPR: Final[str] = '*******'#

Representation for redacted secrets

typed_settings.constants.METADATA_KEY: Final[str] = 'typed-settings'#

Key used in the field metadata

typed_settings.constants.ARGPARSE_METADATA_KEY: Final[str] = 'argparse'#

Key for argparse option within Typed Settings’ metadata

typed_settings.constants.CLICK_METADATA_KEY: Final[str] = 'click'#

Key for click option within Typed Settings’ metadata

Types#

Internal data structures.

typed_settings.types.AUTO = AUTO#

Sentinel to indicate the lack of a value when None is ambiguous.

class typed_settings.types.T#

A generic TypeVar

alias of TypeVar(‘T’)

class typed_settings.types.ET#

A TypeVar for Enum types

alias of TypeVar(‘ET’, bound=Enum)

class typed_settings.types.ST#

A TypeVar for settings instances

alias of TypeVar(‘ST’)

typed_settings.types.SettingsInstance#

alias of Any

typed_settings.types.SettingsDict#

A dictionary with all loaded settings.

Values are not converted to their final type yet.

alias of Dict[str, Union[Any, SettingsDict]]

typed_settings.types.OptionName#

alias of str

typed_settings.types.OptionPath#

alias of str

class typed_settings.types.OptionInfo(parent_cls: type, path: str, cls: type, default: ~typing.Any, has_no_default: bool, default_is_factory: bool, is_secret: bool = False, converter: ~typing.Callable[[~typing.Any], ~typing.Any] | None = None, metadata: ~typing.Dict[~typing.Any, ~typing.Any] = <factory>)[source]#

Information about (possibly nested) option attributes.

Each instance represents a single attribute of an apps’s settings class.

parent_cls: type#

The option’s settings class. This is either the root settings class or a nested one.

path: str#

Dotted path to the option name relative to the root settings class.

typed_settings.types.OptionList#

A flat list of all available options, including those from nested settings.

alias of Tuple[OptionInfo, …]

class typed_settings.types.LoaderMeta(name: str | Any, base_dir: Path | None = None)[source]#

Meta data about the loader that loaded a set of option values.

That data is used to improve error reporting and for converting loaded values to the target type.

property name: str#

The loader’s name. Can be a string or the loader class itself (it’s class name is will then be used).

property base_dir: Path#

The loader’s base directory.

It is used to resolve relative paths in loaded option values in the proper context.

For most loaders, this should be the cwd (which is also the default). For file loaders, the parent directory of a loaded file might be a better alternative.

class typed_settings.types.LoadedValue(value: Any, loader_meta: LoaderMeta)[source]#

A container for a loaded option value and the meta data of the originating loader.

value: Any#

The loaded option value.

loader_meta: LoaderMeta#

Meta data of the loader that loaded the corresponding value.

class typed_settings.types.LoadedSettings(settings: Dict[str, Any | Dict[str, Any | SettingsDict]], meta: LoaderMeta)[source]#

A container for the settings loaded by a single loader, and the meta data of that loader.

settings: Dict[str, Any | Dict[str, Any | SettingsDict]]#

The loaded settings values.

meta: LoaderMeta#

Meta data of the loader that loaded the settings.

typed_settings.types.MergedSettings#

A dict that maps a dotted option path to a loaded option value.

The values may come from different loaders, so each option values stores the meta data of it’s loader.

alias of Dict[str, LoadedValue]

class typed_settings.types.Secret(secret_value: T)[source]#

A secret wrapper around any value.

It makes it very hard to accidentally leak the secret, even when printing or logging it.

You need to explicitly call get_secret_value() to get the wrapped value. Thus, it is no drop-in replacement for the wrapped data.

See SecretStr if you need a drop-in replacement for strings, even if it is not quite as safe.

You can use bool to get the boolean value of the wrapped secret. Other protocol methods (e.g., for length or comparison operators) are not implemented.

New in version 2.0.0.

get_secret_value() T[source]#

Return the wrapped secret value.

class typed_settings.types.SecretStr[source]#

A subclass of str that masks the output of repr().

It is less secure than Secret but is a drop-in replacement for normal strings.

The main use case is avoiding accidental secrets leakage via tracebacks. It also helps to enforce secret usage via Typing.

It does not help when you:

  • print() it

  • str it

  • Log it

  • Use it in an f-string (f"{val}")

New in version 2.0.0.

typed_settings.types.SECRETS_TYPES = (<class 'typed_settings.types.Secret'>, <class 'typed_settings.types.SecretStr'>)#

Types that mask the repr of their values.

typed_settings.types.is_new_type(obj: Any) TypeGuard[NewTypeLike][source]#

Return True if obj is a NewType.

Settings Classes: attrs#

Helpers for and additions to attrs.

Classes and Fields#

Helpers for creating attrs classes and fields with sensible defaults for Typed Settings. They are all also available directly from the typed_settings module.

typed_settings.cls_attrs.settings(maybe_cls=None, *, these=None, repr=None, unsafe_hash=None, hash=None, init=None, slots=True, frozen=False, weakref_slot=True, str=False, auto_attribs=None, kw_only=False, cache_hash=False, auto_exc=True, eq=None, order=False, auto_detect=True, getstate_setstate=None, on_setattr=None, field_transformer=None, match_args=True)#

An alias to attrs.define().

typed_settings.cls_attrs.option(*, default=NOTHING, validator=None, repr=True, hash=None, init=True, metadata=None, converter=None, factory=None, kw_only=False, eq=None, order=None, on_setattr=None, help=None, click=None, argparse=None)[source]#

A wrapper for attrs.field() that makes it easier to pass Typed Settings specific metadata to it.

Additional Parameters:
  • help (str | None): The help string for Click or argparse options.

  • click (dict | None): Additional keyword arguments to pass to click.option(). They can override everything that Typed Settings automatically generated for you. If that dict contains a help, it overrides the value of the help argument. In addition, it can contain the key param_decls: str | Sequence(str) to override the automatically generated ones.

  • argparse (dict | None): Additional keyword arguments to pass to add_argument(). They can override everything that Typed Settings automatically generated for you. If that dict contains a help, it overrides the value of the help argument. In addition, it can contain the key param_decls: str | Sequence(str) to override the automatically generated ones.

typed_settings.cls_attrs.secret(*, default=NOTHING, validator=None, repr=True, hash=None, init=True, metadata=None, converter=None, factory=None, kw_only=False, eq=None, order=None, on_setattr=None, help=None, click=None, argparse=None)[source]#

An alias to option() but with a default repr that hides secrets.

When printing a settings instances, secret settings will represented with ******* instead of their actual value.

See option() for help on the additional parameters.

Example:

>>> from typed_settings import settings, secret
>>>
>>> @settings
... class Settings:
...     password: str = secret()
...
>>> Settings(password="1234")
Settings(password='*******')

Helpers#

typed_settings.cls_attrs.combine(name: str, base_cls: Type[AttrsInstance], nested: Dict[str, AttrsInstance]) Type[AttrsInstance][source]#

Create a new class called name based on base_class with additional attributes for nested classes.

The same effect can be achieved by manually composing settings classes. A use case for this method is to combine settings classes from dynamically loaded plugins with the base settings of the main program.

Parameters:
  • name – The name for the new class.

  • base_cls – The base class from which to copy all attributes.

  • nested – A mapping of attribute names to (settings) class instances for which to generated additional attributes. The attribute’s type is the instance’s type and its default value is the instance itself. Keys in this dict must not overlap with the attributes of base_cls.

Returns:

The created class name.

Raises:

ValueError – If nested contains a key for which base_cls already defines an attribute.

Example

>>> import typed_settings as ts
>>>
>>> @ts.settings
... class Nested1:
...     a: str = ""
>>>
>>> @ts.settings
... class Nested2:
...     a: str = ""
>>>
>>> # Static composition
>>> @ts.settings
... class Composed1:
...     a: str = ""
...     n1: Nested1 = Nested1()
...     n2: Nested2 = Nested2()
...
>>> Composed1()
Composed1(a='', n1=Nested1(a=''), n2=Nested2(a=''))
>>>
>>> # Dynamic composition
>>> @ts.settings
... class BaseSettings:
...     a: str = ""
>>>
>>> Composed2 = ts.combine(
...     "Composed2",
...     BaseSettings,
...     {"n1": Nested1(), "n2": Nested2()},
... )
>>> Composed2()
Composed2(a='', n1=Nested1(a=''), n2=Nested2(a=''))

New in version 1.1.0.

typed_settings.cls_attrs.evolve(inst: AttrsInstance, **changes: Any) AttrsInstance[source]#

Create a new instance, based on inst with changes applied.

If the old value of an attribute is an attrs class and the new value is a dict, the old value is updated recursively.

Warning

This function is very similar to attrs.evolve(), but the attrs version is not updating values recursively. Instead, it will just replace attrs instances with a dict.

Parameters:
  • inst – Instance of a class with attrs attributes.

  • changes – Keyword changes in the new copy.

Returns:

A copy of inst with changes incorporated.

Raises:

New in version 1.0.0.

Settings Classes: Utils#

Helpers and wrappers for settings class backends.

Supported backends are:

class typed_settings.cls_utils.ClsHandler(*args, **kwargs)[source]#

Protocol that class handlers must implement.

New in version 23.1.0.

static check(cls: type) bool[source]#

Return a bool indicating whether cls belongs to the handler’s class lib.

static iter_fields(cls: type) Tuple[OptionInfo, ...][source]#

Recursively iterate the the fields of cls and return the types.OptionInfo instances for them.

Fields of nested classes are only converted to types.OptionInfo if they were created by the same class lib. For example, if the parent class is an attrs class, the attributes of nested dataclasses are not added to the list of options.

static fields_to_parent_classes(cls: type) Dict[str, type][source]#

Map a class’ attribute names to a “parent class”.

This parent class is used to create CLI option groups. Thus, if a field’s type is another (nested) settings class, that class should be used. Else, the class itself should be used.

static asdict(inst: Any) Dict[str, Any | SettingsDict][source]#

Return the instances attributes as dict, recurse into nested classes of the same kind.

class typed_settings.cls_utils.Attrs[source]#

Handler for “attrs” classes.

class typed_settings.cls_utils.Dataclasses[source]#

Handler for dataclasses classes.

static resolve_types(cls: Type[T], globalns: Dict[str, Any] | None = None, localns: Dict[str, Any] | None = None, include_extras: bool = True) Type[T][source]#

Resolve any strings and forward annotations in type annotations.

This is only required if you need concrete types in fields’ type field. In other words, you don’t need to resolve your types if you only use them for static type checking.

With no arguments, names will be looked up in the module in which the class was created. If this is not what you want, e.g. if the name only exists inside a method, you may pass globalns or localns to specify other dictionaries in which to look up these names. See the docs of typing.get_type_hints for more details.

Parameters:
  • cls – Class to resolve.

  • globalns – Dictionary containing global variables.

  • localns – Dictionary containing local variables.

  • include_extras – Resolve more accurately, if possible. Pass include_extras to typing.get_hints, if supported by the typing module. On supported Python versions (3.9+), this resolves the types more accurately.

Returns:

cls so you can use this function also as a class decorator. Please note that you have to apply it after attrs.define. That means the decorator has to come in the line before attrs.define.

class typed_settings.cls_utils.Pydantic[source]#

Handler for “Pydantic” classes.

typed_settings.cls_utils.find_handler(cls: type) Type[ClsHandler][source]#

Return the proper class handler for cls.

Parameters:

cls – The settings class to find a handler for.

Returns:

A ClsHandler that works with cls.

Raises:

TypeError – If no class handler can be found for cls.

typed_settings.cls_utils.deep_options(cls: type) Tuple[OptionInfo, ...][source]#

Recursively iterates cls and nested attrs classes and returns a flat list of (path, Attribute, type) tuples.

Parameters:

cls – The class whose attributes will be listed.

Returns:

The flat list of attributes of cls and possibly nested attrs classes. path is a dot (.) separted path to the attribute, e.g. "parent_attr.child_attr.grand_child_attr.

Raises:
  • NameError – if the type annotations can not be resolved. This is, e.g., the

  • case when recursive classes are being used.

typed_settings.cls_utils.group_options(cls: type, options: Tuple[OptionInfo, ...]) List[Tuple[type, Tuple[OptionInfo, ...]]][source]#

Group (nested) options by parent class.

If cls does not contain nested settings classes, return a single group for cls with all its options.

If cls only contains nested subclasses, return one group per class containing all of that classes (posibly nested) options.

If cls has multiple attributtes with the same nested settings class, create one group per attribute.

If cls contains a mix of scalar options and nested options, return a mix of both. Scalar options schould be grouped (on top or bottom) or else multiple groups for the main settings class will be created.

See the tests for details.

Parameters:
  • cls – The settings class

  • options – The list of all options of the settings class.

Returns:

A list of tuples matching a grouper class to all settings within that group.

CLI: Argparse#

Utilities for generating an argparse based CLI.

New in version 2.0.0.

Decorators and Functions#

Decorators and functions for creating argparse options from Typed Settings options.

typed_settings.cli_argparse.cli(settings_cls: Type[ST], loaders: str | Sequence[Loader], *, processors: Sequence[Processor] = (), converter: Converter | None = None, base_dir: Path = PosixPath('.'), type_args_maker: TypeArgsMaker | None = None, **parser_kwargs: Any) Callable[[Callable[[ST], Any]], Callable[[], int | None]][source]#

Decorator: Generate an argument parser for the options of the given settings class and pass an instance of that class to the decorated function.

Parameters:
  • settings_cls – The settings class to generate options for.

  • loaders – Either a string with your app name or a list of Loaders. If it’s a string, use it with default_loaders() to get the default loaders.

  • processors – A list of settings Processor’s.

  • converter

    An optional Converter used for converting option values to the required type.

    By default, typed_settings.default_converter() is used.

  • base_dir – Base directory for resolving relative paths in default option values.

  • type_args_maker – The type args maker that is used to generate keyword arguments for click.option(). By default, use TypeArgsMaker with ArgparseHandler.

  • **parser_kwargs – Additional keyword arguments to pass to the argparse.ArgumentParser.

Returns:

A decorator for an argparse CLI function.

Raises:

InvalidSettingsError – If an instance of cls cannot be created for the given settings.

Example

import typed_settings as ts

@ts.settings
class Settings: ...

@ts.cli(Settings, "example")
def cli(settings: Settings) -> None:
    print(settings)

Changed in version 23.0.0: Made converter and type_args_maker a keyword-only argument

Changed in version 23.0.0: Added the processors argument

Changed in version 23.1.0: Added the base_dir argument

typed_settings.cli_argparse.make_parser(settings_cls: Type[ST], loaders: str | Sequence[Loader], *, processors: Sequence[Processor] = (), converter: Converter | None = None, base_dir: Path = PosixPath('.'), type_args_maker: TypeArgsMaker | None = None, **parser_kwargs: Any) Tuple[ArgumentParser, Dict[str, LoadedValue]][source]#

Return an argument parser for the options of the given settings class.

Use namespace2settings() to convert the parser’s namespace to an instance of the settings class.

Parameters:
  • settings_cls – The settings class to generate options for.

  • loaders – Either a string with your app name or a list of Loaders. If it’s a string, use it with default_loaders() to get the default loaders.

  • processors – A list of settings Processor’s.

  • converter

    An optional Converter used for converting option values to the required type.

    By default, typed_settings.default_converter() is used.

  • base_dir – Base directory for resolving relative paths in default option values.

  • type_args_maker – The type args maker that is used to generate keyword arguments for click.option(). By default, use TypeArgsMaker with ArgparseHandler.

  • **parser_kwargs – Additional keyword arguments to pass to the argparse.ArgumentParser.

Returns:

An argument parser configured with with an argument for each option of settings_cls.

Raises:

InvalidSettingsError – If an instance of cls cannot be created for the given settings.

Changed in version 23.0.0: Made converter and type_args_maker a keyword-only argument

Changed in version 23.0.0: Added the processors argument

Changed in version 23.1.0: Added the base_dir argument

typed_settings.cli_argparse.namespace2settings(settings_cls: Type[ST], namespace: Namespace, *, merged_settings: Dict[str, LoadedValue], converter: Converter | None = None, base_dir: Path = PosixPath('.')) ST[source]#

Create a settings instance from an argparse namespace.

To be used together with make_parser().

Parameters:
  • settings_cls – The settings class to instantiate.

  • namespace – The namespace returned by the argument parser.

  • merged_settings – The loaded and merged settings by settings name.

  • converter – An optional Converter used for converting option values to the required type. By default, typed_settings.default_converter() is used.

  • base_dir – Base directory for resolving relative paths in default option values.

Raises:

InvalidSettingsError – If an instance of cls cannot be created for the given settings.

Return: An instance of settings_cls.

Changed in version 23.1.0: Added the base_dir argument

Type handling#

Argparse type handling for the TypeArgsMaker.

typed_settings.cli_argparse.handle_datetime(type: type, default: Any | None | NoDefaultType, is_optional: bool) Dict[str, Any][source]#

Handle isoformatted datetimes.

typed_settings.cli_argparse.handle_enum(type: Type[Enum], default: Any | None | NoDefaultType, is_optional: bool) Dict[str, Any][source]#

Use choices as option type and use the enum value’s name as default.

typed_settings.cli_argparse.handle_path(type: Type[Path], default: Any | None | NoDefaultType, is_optional: bool) Dict[str, Any][source]#

Handle pathlib.Path and also use proper metavar.

typed_settings.cli_argparse.DEFAULT_TYPES: Dict[type, TypeHandlerFunc] = {<class 'datetime.datetime'>: <function handle_datetime>, <class 'pathlib.Path'>: <function handle_path>, <enum 'Enum'>: <function handle_enum>}#

Default handlers for argparse option types.

class typed_settings.cli_argparse.ArgparseHandler(extra_types: Dict[type, TypeHandlerFunc] | None = None)[source]#

Implementation of the TypeHandler protocol for Click.

Parameters:

extra_types – A dict mapping types to specialized handler functions. Use DEFAULT_TYPES by default.

CLI: Click#

Utilities for generating Click options.

Decorators#

Decorators for creating click options from Typed Settings options.

typed_settings.cli_click.click_options(settings_cls: Type[ST], loaders: str | Sequence[Loader], *, processors: Sequence[Processor] = (), converter: Converter | None = None, base_dir: Path = PosixPath('.'), type_args_maker: TypeArgsMaker | None = None, argname: str | None = None, decorator_factory: DecoratorFactory | None = None, show_envvars_in_help: bool = False) Callable[[F], F][source]#

Decorator: Generate click options for a CLI which override settings loaded via load_settings().

Parameters:
  • settings_cls – The settings class to generate options for.

  • loaders – Either a string with your app name or a list of Loaders. If it’s a string, use it with default_loaders() to get the default loaders.

  • processors – A list of settings Processor’s.

  • converter

    An optional Converter used for converting option values to the required type.

    By default, typed_settings.default_converter() is used.

  • base_dir – Base directory for resolving relative paths in default option values.

  • type_args_maker – The type args maker that is used to generate keyword arguments for click.option(). By default, use TypeArgsMaker with ClickHandler.

  • argname

    An optional argument name for the settings instance that is passed to the CLI. If it is set, the settings instances is no longer passed as positional argument but as key word argument.

    This allows a CLI function to be decorated with this function multiple times.

  • decorator_factory

    A class that generates Click decorators for options and settings classes. This allows you to, e.g., use option groups via OptionGroupFactory. The default generates normal Click options via ClickOptionFactory.

  • show_envvars_in_help – If True and if the EnvLoader is being used, show the names of the environment variable a value is loaded from.

Returns:

A decorator for a click command.

Raises:

InvalidSettingsError – If an instance of cls cannot be created for the given settings.

Example

import click
import typed_settings as ts

@ts.settings
class Settings: ...

@click.command()
@ts.click_options(Settings, "example")
def cli(settings: Settings) -> None:
    print(settings)

Changed in version 1.0.0: Instead of a list of loaders, you can also just pass an application name.

Changed in version 1.1.0: Added the argname parameter.

Changed in version 1.1.0: Added the decorator_factory parameter.

Changed in version 2.0.0: Renamed type_handler to type_args_maker and changed it’s type to TypeArgsMaker.

Changed in version 23.0.0: Made converter, type_args_maker, argname, and decorator_factory a keyword-only argument

Changed in version 23.0.0: Added the processors argument

Changed in version 23.1.0: Added the base_dir argument

typed_settings.cli_click.pass_settings(f: None = None, *, argname: str | None = None) Callable[[F], F][source]#
typed_settings.cli_click.pass_settings(f: F, *, argname: str | None = None) F

Decorator: Mark a callback as wanting to receive the innermost settings instance as first argument.

If you specify an argname in click_options(), you must specify the same name here in order to get the correct settings instance. The settings instance is then passed as keyword argument.

Parameters:
  • f – If this decorator is applied without any arguments, this is the to be decrorated function. If you pass any keyword arguments, this is None.

  • argname – An optional argument name. If it is set, the settings instance is no longer passed as positional argument but as key word argument.

Returns:

A decorator for a click command.

Example

import click
import typed_settings as ts

@ts.settings
class Settings: ...

@click.group()
@click_options(Settings, "example", argname="my_settings")
def cli(my_settings):
    pass

@cli.command()
# Use the same "argname" as above!
@pass_settings(argname="my_settings")
def sub_cmd(*, my_settings):
    print(my_settings)

Changed in version 1.1.0: Add the argname parameter.

Generating Click options and option groups#

Classes for customizing how Cli options are created and grouped.

class typed_settings.cli_click.DecoratorFactory(*args, **kwargs)[source]#

Protocol: Methods that a Click decorator factory must implement.

The decorators returned by the procol methods are used to construct the Click options and possibly option groups.

New in version 1.1.0.

get_option_decorator() Callable[[...], Callable[[F], F]][source]#

Return the decorator that is used for creating Click options.

It must be compatible with click.option().

get_group_decorator(settings_cls: type) Callable[[F], F][source]#

Return a decorator for the current settings class.

This can, e.g., be used to group option by settings class.

class typed_settings.cli_click.ClickOptionFactory[source]#

Factory for default Click decorators.

get_option_decorator() Callable[[...], Callable[[F], F]][source]#

Return click.option().

get_group_decorator(settings_cls: type) Callable[[F], F][source]#

Return a no-op decorator that leaves the decorated function unchanged.

class typed_settings.cli_click.OptionGroupFactory[source]#

Factory got generating Click option groups via https://click-option-group.readthedocs.io.

get_option_decorator() Callable[[...], Callable[[F], F]][source]#

Return click_option_group.optgroup option.

get_group_decorator(settings_cls: type) Callable[[F], F][source]#

Return a click_option_group.optgroup group instantiated with the first line of settings_cls’s docstring.

Type handling#

Click type handling for the TypeArgsMaker.

typed_settings.cli_click.handle_datetime(type: type, default: Any | None | NoDefaultType, is_optional: bool) Dict[str, Any][source]#

Use click.DateTime as option type and convert the default value to an ISO string.

typed_settings.cli_click.handle_enum(type: Type[Enum], default: Any | None | NoDefaultType, is_optional: bool) Dict[str, Any][source]#

Use click.Choice as option type and use the enum value’s name as default.

typed_settings.cli_click.DEFAULT_TYPES: Dict[type, TypeHandlerFunc] = {<class 'datetime.datetime'>: <function handle_datetime>, <enum 'Enum'>: <function handle_enum>}#

Default handlers for click option types.

class typed_settings.cli_click.ClickHandler(extra_types: Dict[type, TypeHandlerFunc] | None = None)[source]#

Implementation of the TypeHandler protocol for Click.

Parameters:

extra_types – A dict mapping types to specialized handler functions. Use DEFAULT_TYPES by default.

New in version 2.0.0.

CLI: Utils#

Framework agnostic utilities for generating CLI options from Typed Settings options.

typed_settings.cli_utils.NO_DEFAULT = NO_DEFAULT#

Sentinel that indicates the lack of a default value for an option.

class typed_settings.cli_utils.NoDefaultType[source]#

Sentinel class to indicate the lack of a default value for an option when None is ambiguous.

NoDefaultType is a singleton. There is only ever one of it.

class typed_settings.cli_utils.TypeHandlerFunc(*args, **kwargs)[source]#

Protocol: A function that returns keyword arguments for a CLI option for a specific type.

__call__(type: type, default: Any | None | NoDefaultType, is_optional: bool) Dict[str, Any][source]#

Return keyword arguments for creating an option for type.

Parameters:
  • type – The type to create the option for.

  • default – The default value for the option. May be None or NO_DEFAULT.

  • is_optional – Whether the original type was an Optional.

class typed_settings.cli_utils.TypeHandler(*args, **kwargs)[source]#

Protocol: Callbacks for the TypeArgsMaker that provide framework specific arguments for various classes of CLI options.

New in version 2.0.0.

get_scalar_handlers() Dict[type, TypeHandlerFunc][source]#

Return a dict that maps specialized handlers for certain types (e.g., enums or datetimes.

Such a handler can look like this:

def handle_mytype(
    type: type,
    default: Default,
    is_optional: bool,
) -> Dict[str, Any]:
    kwargs = {
        "type": MyCliType(...)
    }
    if default not in (None, NO_DEFAULT):
        kwargs["default"] = default.stringify()
    elif is_optional:
        kwargs["default"] = None
    return kwargs
Returns:

A dict mapping types to the corresponding type handler function.

handle_scalar(type: type | None, default: Any | None | NoDefaultType, is_optional: bool) Dict[str, Any][source]#

Handle all scalars for which get_scalar_handlers() does not provide a specific handler.

Parameters:
  • type – The type to create an option for. Can be none if the option is untyped.

  • default – The default value for the option. My be None or NO_DEFAULT.

  • is_optional – Whether or not the option type was marked as option or not.

Returns:

A dictionary with keyword arguments for creating an option for the given type.

handle_tuple(type_args_maker: TypeArgsMaker, types: Tuple[Any, ...], default: Tuple | None, is_optional: bool) Dict[str, Any][source]#

Handle options for structured tuples (i.e., not list-like tuples).

Parameters:
  • type_args_maker – The TypeArgsMaker that called this function.

  • types – The types of all tuple items.

  • default – Either a tuple of default values or None.

  • is_optional – Whether or not the option type was marked as option or not.

Returns:

A dictionary with keyword arguments for creating an option for the tuple.

handle_collection(type_args_maker: TypeArgsMaker, types: Tuple[Any, ...], default: List[Any] | None, is_optional: bool) Dict[str, Any][source]#

Handle collections, add options to allow multiple values and to collect them in a list/collection.

Parameters:
  • type_args_maker – The TypeArgsMaker that called this function.

  • types – The types of the list items.

  • default – Either a collection of default values or None.

  • is_optional – Whether or not the option type was marked as option or not.

Returns:

A dictionary with keyword arguments for creating an option for the list type.

handle_mapping(type_args_maker: TypeArgsMaker, types: Tuple[Any, ...], default: Any | None | NoDefaultType, is_optional: bool) Dict[str, Any][source]#

Handle dictionaries.

Parameters:
  • type_args_maker – The TypeArgsMaker that called this function.

  • types – The types of keys and values.

  • default – Either a mapping of default values, None or NO_DEFAULT.

  • is_optional – Whether or not the option type was marked as option or not.

Returns:

A dictionary with keyword arguments for creating an option for the tuple.

class typed_settings.cli_utils.TypeArgsMaker(type_handler: TypeHandler)[source]#

This class derives type information (in the form of keyword arguments) for CLI options from attributes of a settings class.

For example, it could return a dict {"type": int, "default": 3} for an option val: int = 3.

It is agnostic of the CLI framework being used. The specifics for each framework are implemented in a TypeHandler that is passed to this class.

The TypeArgsMaker differentitates between scalar and collection types (e.g., int vs. list[int]. It inspects each option (field) of a settings class and calls the appropriate method of the TypeHandler:

Changed in version 2.0.0: Complete refactoring and renamed from TypeHandler to TypeArgsMaker.

get_kwargs(otype: Any, default: Any | None | NoDefaultType) Dict[str, Any][source]#

Analyse the option type and return keyword arguments for creating a CLI option for it.

Parameters:
  • otype – The option’s type. It can be None if the user uses an untyped class.

  • default – The default value for the option. It can be anything, but the values None (possible default for optional types) and NO_DEFAULT (no default set) should be handled explicitly.

Returns:

A dictionary with keyword arguments for creating a CLI option in for a given framework.

Raises:

TypeError – If the otype has an unsupported type (e.g., a union type).

typed_settings.cli_utils.get_default(option_info: OptionInfo, settings: Dict[str, LoadedValue], converter: Converter) Any[source]#

Return the proper default value for an attribute.

If possible, the default is taken from loaded settings. Else, use the field’s default value.

Parameters:
  • option_info – The option description for the attribute.

  • settings – A (nested) dict with the loaded settings.

  • converter – The converter to be used.

Returns:

The default value to be used for the option. This can also be None or a “nothing” value (e.g., attrs.NOTHING).

typed_settings.cli_utils.check_if_optional(otype: type | None, default: Any | None | NoDefaultType, origin: Any, args: Tuple[Any, ...]) Tuple[type | None, Any, Any, Tuple[Any, ...], bool][source]#

Check if otype is an optional (Optional[...] or Union[None, ...]) and return the actual type for it and a flag indicating the optionality.

If it is optional and a default value is not set, use None as new default.

Parameters:
  • otype – The Python type of the option.

  • default – The option’s default value.

  • origin – The generic origin as returned by typing.get_origin().

  • args – The generic args as returned by typing.get_args().

Returns:

otype:

is either the original or the unwrapped optional type.

default:

is the possibly updated default value.

origin:

is the possibly updated origin for the unwrapped otype.

args:

are the possibly updated args for the unwrapped otype.

is_optional:

indicates whether otype was an optional or not.

Return type:

A tuple (otype, default, origin, args, is_optional)

MyPy#

A simple mypy plugin that makes the Typed Settings attrs aliases and wrappers recognized by it.

You can activate the plugin via your pyproject.toml or mypy.ini:

# pyproject.toml
[tool.mypy]
plugins = ["typed_settings.mypy"]
# mypy.ini
[mypy]
plugins=typed_settings.mypy