Coverage for src/configuraptor/abs.py: 100%

1"""

2 Contains the Abstract config class shared by TypedConfig and BinaryConfig.

3"""

4 import os

5 import types

6 import typing

7 from pathlib import Path

8

9 import dotenv

10 from dotenv import find_dotenv

11

12# T is a reusable typevar

13 T = typing.TypeVar("T")

14# t_typelike is anything that can be type hinted

15 T_typelike: typing.TypeAlias = type | types.UnionType # | typing.Union

16# t_data is anything that can be fed to _load_data

17 T_data_types = str | Path | bytes | dict[str, typing.Any] | None

18 T_data = T_data_types | list[T_data_types]

19

20# c = a config class instance, can be any (user-defined) class

21 C = typing.TypeVar("C")

22# type c is a config class

23 Type_C = typing.Type[C]

24

25

26 class AbstractTypedConfig:

27 """

28 These functions only exist on the class, not on instances.

29 """

30

31 @classmethod

32 def load(

33 cls: typing.Type[C],

34 data: T_data = None,

35 key: str = None,

36 init: dict[str, typing.Any] = None,

37 strict: bool = True,

38 lower_keys: bool = False,

39 convert_types: bool = False,

40 ) -> C:

41 """

42 Load a class' config values from the config file.

43

44 SomeClass.load(data, ...) = load_into(SomeClass, data, ...).

45 """

46 from .core import load_into

47

48 return load_into(

49 cls, data, key=key, init=init, strict=strict, lower_keys=lower_keys, convert_types=convert_types

50 )

51

52 @classmethod

53 def from_env(

54 cls: typing.Type[C],

55 load_dotenv: str | bool = False,

56 init: dict[str, typing.Any] = None,

57 strict: bool = True,

58 convert_types: bool = True,

59 ) -> C:

60 """

61 Create an instance of the typed config class by loading environment variables and initializing \

62 object attributes based on those values.

63

64 Args:

65 cls (typing.Type[C]): The class to create an instance of.

66 init (dict[str, typing.Any], optional): Additional initialization data to be used

67 in the object creation. Defaults to None.

68 strict (bool, optional): If True, raise an error if any required environment variable

69 is missing. Defaults to True.

70 convert_types (bool, optional): If True, attempt to convert environment variable values

71 to the appropriate Python types. Defaults to False.

72 load_dotenv (str | bool, optional): Path to a dotenv file or True to load the default

73 dotenv file. If False, no dotenv file will be loaded. Defaults to False.

74

75 Returns:

76 C: An instance of the class `C` with attributes initialized based on the environment variables.

77 """

78 from .core import load_into

79

80 if load_dotenv:

81 dotenv_path = load_dotenv if isinstance(load_dotenv, str) else find_dotenv(usecwd=True)

82 dotenv.load_dotenv(dotenv_path)

83

84 data = {**os.environ}

85

86 return load_into(cls, data, lower_keys=True, init=init, strict=strict, convert_types=convert_types)