Coverage for src/configuraptor/abs.py: 100%
29 statements
« prev ^ index » next coverage.py v7.2.7, created at 2026-05-01 17:14 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2026-05-01 17:14 +0200
1"""
2Contains the Abstract config class shared by TypedConfig and BinaryConfig.
3"""
5import os
6import types
7import typing
8from pathlib import Path
10import dotenv
11from dotenv import find_dotenv
13# T is a reusable typevar
14T = typing.TypeVar("T")
15# t_typelike is anything that can be type hinted
16T_typelike: typing.TypeAlias = type | types.UnionType # | typing.Union
17# t_data is anything that can be fed to _load_data
18T_data_types = str | Path | bytes | dict[str, typing.Any] | None
19T_data = T_data_types | list[T_data_types]
21# c = a config class instance, can be any (user-defined) class
22C = typing.TypeVar("C")
23# type c is a config class
24Type_C = typing.Type[C]
26AnyType: typing.TypeAlias = typing.Type[typing.Any]
27T_Type = typing.TypeVar("T_Type", bound=AnyType)
29UseEnvSetting = typing.Literal["yes", "inverse", "dotenv", "environ", "no"]
30DEFAULT_ENV_SETTING: UseEnvSetting = "yes"
33class AbstractTypedConfig:
34 """
35 These functions only exist on the class, not on instances.
36 """
38 @classmethod
39 def load(
40 cls: typing.Type[C],
41 data: T_data = None,
42 key: str = None,
43 init: dict[str, typing.Any] = None,
44 strict: bool = True,
45 lower_keys: bool = False,
46 convert_types: bool = False,
47 use_env: UseEnvSetting = DEFAULT_ENV_SETTING,
48 ) -> C:
49 """
50 Load a class' config values from the config file.
52 SomeClass.load(data, ...) = load_into(SomeClass, data, ...).
53 """
54 from .core import load_into
56 return load_into(
57 cls,
58 data,
59 key=key,
60 init=init,
61 strict=strict,
62 lower_keys=lower_keys,
63 convert_types=convert_types,
64 use_env=use_env,
65 )
67 @classmethod
68 def from_env(
69 cls: typing.Type[C],
70 load_dotenv: str | bool = False,
71 init: dict[str, typing.Any] = None,
72 strict: bool = True,
73 convert_types: bool = True,
74 ) -> C:
75 """
76 Create an instance of the typed config class by loading environment variables and initializing \
77 object attributes based on those values.
79 Args:
80 cls (typing.Type[C]): The class to create an instance of.
81 init (dict[str, typing.Any], optional): Additional initialization data to be used
82 in the object creation. Defaults to None.
83 strict (bool, optional): If True, raise an error if any required environment variable
84 is missing. Defaults to True.
85 convert_types (bool, optional): If True, attempt to convert environment variable values
86 to the appropriate Python types. Defaults to False.
87 load_dotenv (str | bool, optional): Path to a dotenv file or True to load the default
88 dotenv file. If False, no dotenv file will be loaded. Defaults to False.
90 Returns:
91 C: An instance of the class `C` with attributes initialized based on the environment variables.
92 """
93 from .core import load_into
95 if load_dotenv:
96 dotenv_path = load_dotenv if isinstance(load_dotenv, str) else find_dotenv(usecwd=True)
97 dotenv.load_dotenv(dotenv_path)
99 data = {**os.environ}
101 return load_into(cls, data, lower_keys=True, init=init, strict=strict, convert_types=convert_types)