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
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""
3uritemplate.template
4====================
6This module contains the essential inner workings of uritemplate.
8What treasures await you:
10- URITemplate class
12You see a treasure chest of knowledge in front of you.
13What do you do?
14>
16"""
17import re
18import typing as t
20from uritemplate import orderedset
21from uritemplate import variable
23template_re = re.compile("{([^}]+)}")
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
37class URITemplate:
39 """This parses the template and will be used to expand it.
41 This is the most important object as the center of the API.
43 Example::
45 from uritemplate import URITemplate
46 import requests
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'])
57 Please note::
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.
65 Also, ``URITemplates`` are hashable so they can be used as keys in
66 dictionaries.
68 """
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)
85 def __repr__(self) -> str:
86 return 'URITemplate("%s")' % self
88 def __str__(self) -> str:
89 return self.uri
91 def __eq__(self, other: object) -> bool:
92 if not isinstance(other, URITemplate):
93 return NotImplemented
94 return self.uri == other.uri
96 def __hash__(self) -> int:
97 return hash(self.uri)
99 def _expand(
100 self, var_dict: variable.VariableValueDict, replace: bool
101 ) -> str:
102 if not self.variables:
103 return self.uri
105 expansion = var_dict
106 expanded: t.Dict[str, str] = {}
107 for v in self.variables:
108 expanded.update(v.expand(expansion))
110 def replace_all(match: "re.Match[str]") -> str:
111 return expanded.get(match.groups()[0], "")
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
118 replace_func = replace_partial if replace else replace_all
120 return template_re.sub(replace_func, self.uri)
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.
129 :param dict var_dict: Optional dictionary with variables and values
130 :param kwargs: Alternative way to pass arguments
131 :returns: str
133 Example::
135 t = URITemplate('https://api.github.com{/end}')
136 t.expand({'end': 'users'})
137 t.expand(end='gists')
139 .. note:: Passing values by both parts, may override values in
140 ``var_dict``. For example::
142 expand('https://{var}', {'var': 'val1'}, var='val2')
144 ``val2`` will be used instead of ``val1``.
146 """
147 return self._expand(_merge(var_dict, kwargs), False)
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.
156 If all of the parameters for the template are not given, return a
157 partially expanded template.
159 :param dict var_dict: Optional dictionary with variables and values
160 :param kwargs: Alternative way to pass arguments
161 :returns: :class:`URITemplate`
163 Example::
165 t = URITemplate('https://api.github.com{/end}')
166 t.partial() # => URITemplate('https://api.github.com{/end}')
168 """
169 return URITemplate(self._expand(_merge(var_dict, kwargs), True))