Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/environ/fileaware_mapping.py: 21%

46 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1# This file is part of the django-environ. 

2# 

3# Copyright (c) 2021-2022, Serghei Iakovlev <egrep@protonmail.ch> 

4# Copyright (c) 2013-2021, Daniele Faraglia <daniele.faraglia@gmail.com> 

5# 

6# For the full copyright and license information, please view 

7# the LICENSE.txt file that was distributed with this source code. 

8 

9"""Docker-style file variable support module.""" 

10 

11import os 

12from collections.abc import MutableMapping 

13 

14 

15class FileAwareMapping(MutableMapping): 

16 """ 

17 A mapping that wraps os.environ, first checking for the existence of a key 

18 appended with ``_FILE`` whenever reading a value. If a matching file key is 

19 found then the value is instead read from the file system at this location. 

20 

21 By default, values read from the file system are cached so future lookups 

22 do not hit the disk again. 

23 

24 A ``_FILE`` key has higher precedence than a value is set directly in the 

25 environment, and an exception is raised if the file can not be found. 

26 """ 

27 

28 def __init__(self, env=None, cache=True): 

29 """ 

30 Initialize the mapping. 

31 

32 :param env: 

33 where to read environment variables from (defaults to 

34 ``os.environ``) 

35 :param cache: 

36 cache environment variables read from the file system (defaults to 

37 ``True``) 

38 """ 

39 self.env = env if env is not None else os.environ 

40 self.cache = cache 

41 self.files_cache = {} 

42 

43 def __getitem__(self, key): 

44 if self.cache and key in self.files_cache: 

45 return self.files_cache[key] 

46 key_file = self.env.get(key + "_FILE") 

47 if key_file: 

48 with open(key_file) as f: 

49 value = f.read() 

50 if self.cache: 

51 self.files_cache[key] = value 

52 return value 

53 return self.env[key] 

54 

55 def __iter__(self): 

56 """ 

57 Iterate all keys, also always including the shortened key if ``_FILE`` 

58 keys are found. 

59 """ 

60 for key in self.env: 

61 yield key 

62 if key.endswith("_FILE"): 

63 no_file_key = key[:-5] 

64 if no_file_key and no_file_key not in self.env: 

65 yield no_file_key 

66 

67 def __len__(self): 

68 """ 

69 Return the length of the file, also always counting shortened keys for 

70 any ``_FILE`` key found. 

71 """ 

72 return len(tuple(iter(self))) 

73 

74 def __setitem__(self, key, value): 

75 self.env[key] = value 

76 if self.cache and key.endswith("_FILE"): 

77 no_file_key = key[:-5] 

78 if no_file_key and no_file_key in self.files_cache: 

79 del self.files_cache[no_file_key] 

80 

81 def __delitem__(self, key): 

82 file_key = key + "_FILE" 

83 if file_key in self.env: 

84 del self[file_key] 

85 if key in self.env: 

86 del self.env[key] 

87 return 

88 if self.cache and key.endswith("_FILE"): 

89 no_file_key = key[:-5] 

90 if no_file_key and no_file_key in self.files_cache: 

91 del self.files_cache[no_file_key] 

92 del self.env[key]