Coverage for /var/devmt/py/utils4_1.7.0/utils4/config.py: 100%

22 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-21 17:18 +0000

1# -*- coding: utf-8 -*- 

2""" 

3:Purpose: Small helper module designed to load a program's JSON-based 

4 config file. 

5 

6:Platform: Linux/Windows | Python 3.7+ 

7:Developer: J Berendt 

8:Email: support@s3dev.uk 

9 

10:Comments: n/a 

11 

12:Example: 

13 To load a program's JSON-based config file:: 

14 

15 >>> from utils4 import config 

16 

17 >>> cfg = config.loadconfig() 

18 >>> my_param = cfg['my_param'] 

19 

20""" 

21 

22import os 

23import sys 

24import json 

25from utils4.dict2obj import Dict2Obj 

26 

27 

28def loadconfig(filename: str='config.json', return_as_obj: bool=False): 

29 """Load a program's JSON config file and return it as a dict or object. 

30 

31 Args: 

32 filename (str, optional): File name or (preferably) the 

33 **explicit** full file path path of the JSON config file to 

34 be loaded. Defaults to 'config.json'. 

35 return_as_object (bool, optional): If True, the dictionary is 

36 converted into an object, where the dictionary key/values 

37 are object attribute/values. Defaults to False. 

38 

39 :Design: 

40 By default, this function will search the program's directory 

41 for a file named ``config.json``. If the config file lives 

42 somewhere else, or you're using an IDE to develop, the safest 

43 option is to **explicitly define the path to the config file**. 

44 

45 If a path is found in the passed parameter, this path is used, 

46 and the function does not have to try and work out where the 

47 config file lives. 

48 

49 The ``return_as_obj`` parameter tells the function to convert 

50 and return the JSON file into an object, rather than a 

51 dictionary. This enables you to access the values from object 

52 attributes, rather than from dictionary keys. See use option 2. 

53 

54 :Assumptions: 

55 * The config file is a JSON file. 

56 * The config file lives in the program directory. 

57 

58 :Examples: 

59 

60 Option 1: Return the config file as a **dict**:: 

61 

62 >>> from utils4 import config 

63 

64 >>> cfg = config.loadconfig() 

65 >>> my_param = cfg['my_param'] 

66 

67 

68 Option 2: Return the config file as an **object**:: 

69 

70 >>> from utils4 import config 

71 

72 >>> cfg = config.loadconfig(return_as_object=True) 

73 >>> my_param = cfg.my_param 

74 

75 """ 

76 # Filename only. 

77 if os.path.dirname(filename) == '': 

78 progdir = os.path.dirname(os.path.realpath(sys.argv[0])) 

79 path_base = progdir if sys.argv[0] != '' else os.getcwd() 

80 fullpath = os.path.join(path_base, filename) 

81 # Full path. 

82 else: 

83 fullpath = filename 

84 if _file_exists(fullpath=fullpath): 

85 if return_as_obj: 

86 return Dict2Obj(source='json', filepath=fullpath) 

87 return _fromjson(filepath=fullpath) 

88 return None # pragma: nocover (unreachable due to raised IOError) 

89 

90def _file_exists(fullpath: str) -> bool: 

91 """Test if the requested config file exists. 

92 

93 Args: 

94 fullpath (str): Full path to the file being tested. 

95 

96 Raises: 

97 IOError: If the file does not exist. 

98 

99 Returns: 

100 bool: True of the file exists, otherwise False. 

101 

102 """ 

103 exists = os.path.exists(fullpath) 

104 if not exists: 

105 raise IOError(f'The config file ({fullpath}) could not be found.') 

106 return exists 

107 

108def _fromjson(filepath: str) -> dict: 

109 """Extract values from the JSON file. 

110 

111 Args: 

112 filepath (str): Full path to the file to be read. 

113 

114 Returns: 

115 dict: JSON file content as a dictionary. 

116 

117 """ 

118 with open(filepath, 'r', encoding='utf-8') as f: 

119 return json.load(f)