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

27 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-12-04 18:06 +0100

1""" 

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

3""" 

4import os 

5import types 

6import typing 

7from pathlib import Path 

8 

9import dotenv 

10from dotenv import find_dotenv 

11 

12# T is a reusable typevar 

13T = typing.TypeVar("T") 

14# t_typelike is anything that can be type hinted 

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

16# t_data is anything that can be fed to _load_data 

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

18T_data = T_data_types | list[T_data_types] 

19 

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

21C = typing.TypeVar("C") 

22# type c is a config class 

23Type_C = typing.Type[C] 

24 

25AnyType: typing.TypeAlias = typing.Type[typing.Any] 

26T_Type = typing.TypeVar("T_Type", bound=AnyType) 

27 

28 

29class AbstractTypedConfig: 

30 """ 

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

32 """ 

33 

34 @classmethod 

35 def load( 

36 cls: typing.Type[C], 

37 data: T_data = None, 

38 key: str = None, 

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

40 strict: bool = True, 

41 lower_keys: bool = False, 

42 convert_types: bool = False, 

43 ) -> C: 

44 """ 

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

46 

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

48 """ 

49 from .core import load_into 

50 

51 return load_into( 

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

53 ) 

54 

55 @classmethod 

56 def from_env( 

57 cls: typing.Type[C], 

58 load_dotenv: str | bool = False, 

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

60 strict: bool = True, 

61 convert_types: bool = True, 

62 ) -> C: 

63 """ 

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

65 object attributes based on those values. 

66 

67 Args: 

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

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

70 in the object creation. Defaults to None. 

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

72 is missing. Defaults to True. 

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

74 to the appropriate Python types. Defaults to False. 

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

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

77 

78 Returns: 

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

80 """ 

81 from .core import load_into 

82 

83 if load_dotenv: 

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

85 dotenv.load_dotenv(dotenv_path) 

86 

87 data = {**os.environ} 

88 

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