Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/uritemplate/template.py: 26%

46 statements  

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

1""" 

2 

3uritemplate.template 

4==================== 

5 

6This module contains the essential inner workings of uritemplate. 

7 

8What treasures await you: 

9 

10- URITemplate class 

11 

12You see a treasure chest of knowledge in front of you. 

13What do you do? 

14> 

15 

16""" 

17import re 

18import typing as t 

19 

20from uritemplate import orderedset 

21from uritemplate import variable 

22 

23template_re = re.compile("{([^}]+)}") 

24 

25 

26def _merge( 

27 var_dict: t.Optional[variable.VariableValueDict], 

28 overrides: variable.VariableValueDict, 

29) -> variable.VariableValueDict: 

30 if var_dict: 

31 opts = var_dict.copy() 

32 opts.update(overrides) 

33 return opts 

34 return overrides 

35 

36 

37class URITemplate: 

38 

39 """This parses the template and will be used to expand it. 

40 

41 This is the most important object as the center of the API. 

42 

43 Example:: 

44 

45 from uritemplate import URITemplate 

46 import requests 

47 

48 

49 t = URITemplate( 

50 'https://api.github.com/users/sigmavirus24/gists{/gist_id}' 

51 ) 

52 uri = t.expand(gist_id=123456) 

53 resp = requests.get(uri) 

54 for gist in resp.json(): 

55 print(gist['html_url']) 

56 

57 Please note:: 

58 

59 str(t) 

60 # 'https://api.github.com/users/sigmavirus24/gists{/gistid}' 

61 repr(t) # is equivalent to 

62 # URITemplate(str(t)) 

63 # Where str(t) is interpreted as the URI string. 

64 

65 Also, ``URITemplates`` are hashable so they can be used as keys in 

66 dictionaries. 

67 

68 """ 

69 

70 def __init__(self, uri: str): 

71 #: The original URI to be parsed. 

72 self.uri: str = uri 

73 #: A list of the variables in the URI. They are stored as 

74 #: :class:`~uritemplate.variable.URIVariable`\ s 

75 self.variables: t.List[variable.URIVariable] = [ 

76 variable.URIVariable(m.groups()[0]) 

77 for m in template_re.finditer(self.uri) 

78 ] 

79 #: A set of variable names in the URI. 

80 self.variable_names = orderedset.OrderedSet() 

81 for var in self.variables: 

82 for name in var.variable_names: 

83 self.variable_names.add(name) 

84 

85 def __repr__(self) -> str: 

86 return 'URITemplate("%s")' % self 

87 

88 def __str__(self) -> str: 

89 return self.uri 

90 

91 def __eq__(self, other: object) -> bool: 

92 if not isinstance(other, URITemplate): 

93 return NotImplemented 

94 return self.uri == other.uri 

95 

96 def __hash__(self) -> int: 

97 return hash(self.uri) 

98 

99 def _expand( 

100 self, var_dict: variable.VariableValueDict, replace: bool 

101 ) -> str: 

102 if not self.variables: 

103 return self.uri 

104 

105 expansion = var_dict 

106 expanded: t.Dict[str, str] = {} 

107 for v in self.variables: 

108 expanded.update(v.expand(expansion)) 

109 

110 def replace_all(match: "re.Match[str]") -> str: 

111 return expanded.get(match.groups()[0], "") 

112 

113 def replace_partial(match: "re.Match[str]") -> str: 

114 match_group = match.groups()[0] 

115 var = "{%s}" % match_group 

116 return expanded.get(match_group) or var 

117 

118 replace_func = replace_partial if replace else replace_all 

119 

120 return template_re.sub(replace_func, self.uri) 

121 

122 def expand( 

123 self, 

124 var_dict: t.Optional[variable.VariableValueDict] = None, 

125 **kwargs: variable.VariableValue, 

126 ) -> str: 

127 """Expand the template with the given parameters. 

128 

129 :param dict var_dict: Optional dictionary with variables and values 

130 :param kwargs: Alternative way to pass arguments 

131 :returns: str 

132 

133 Example:: 

134 

135 t = URITemplate('https://api.github.com{/end}') 

136 t.expand({'end': 'users'}) 

137 t.expand(end='gists') 

138 

139 .. note:: Passing values by both parts, may override values in 

140 ``var_dict``. For example:: 

141 

142 expand('https://{var}', {'var': 'val1'}, var='val2') 

143 

144 ``val2`` will be used instead of ``val1``. 

145 

146 """ 

147 return self._expand(_merge(var_dict, kwargs), False) 

148 

149 def partial( 

150 self, 

151 var_dict: t.Optional[variable.VariableValueDict] = None, 

152 **kwargs: variable.VariableValue, 

153 ) -> "URITemplate": 

154 """Partially expand the template with the given parameters. 

155 

156 If all of the parameters for the template are not given, return a 

157 partially expanded template. 

158 

159 :param dict var_dict: Optional dictionary with variables and values 

160 :param kwargs: Alternative way to pass arguments 

161 :returns: :class:`URITemplate` 

162 

163 Example:: 

164 

165 t = URITemplate('https://api.github.com{/end}') 

166 t.partial() # => URITemplate('https://api.github.com{/end}') 

167 

168 """ 

169 return URITemplate(self._expand(_merge(var_dict, kwargs), True))