MCPcopy Index your code
hub / github.com/fluentpython/example-code-2e / Router

Class Router

21-async/mojifinder/bottle.py:261–454  ·  view source on GitHub ↗

A Router is an ordered collection of route->target pairs. It is used to efficiently match WSGI requests against a number of routes and return the first target that satisfies the request. The target may be anything, usually a string, ID or callable object. A route consists of

Source from the content-addressed store, hash-verified

259
260
261class Router(object):
262 ''' A Router is an ordered collection of route->target pairs. It is used to
263 efficiently match WSGI requests against a number of routes and return
264 the first target that satisfies the request. The target may be anything,
265 usually a string, ID or callable object. A route consists of a path-rule
266 and a HTTP method.
267
268 The path-rule is either a static path (e.g. `/contact`) or a dynamic
269 path that contains wildcards (e.g. `/wiki/<page>`). The wildcard syntax
270 and details on the matching order are described in docs:`routing`.
271 ''&#x27;
272
273 default_pattern = '[^/]+'
274 default_filter = 're'
275
276 #: The current CPython regexp implementation does not allow more
277 #: than 99 matching groups per regular expression.
278 _MAX_GROUPS_PER_PATTERN = 99
279
280 def __init__(self, strict=False):
281 self.rules = [] # All rules in order
282 self._groups = {} # index of regexes to find them in dyna_routes
283 self.builder = {} # Data structure for the url builder
284 self.static = {} # Search structure for static routes
285 self.dyna_routes = {}
286 self.dyna_regexes = {} # Search structure for dynamic routes
287 #: If true, static routes are no longer checked first.
288 self.strict_order = strict
289 self.filters = {
290 're': lambda conf:
291 (_re_flatten(conf or self.default_pattern), None, None),
292 'int': lambda conf: (r'-?\d+', int, lambda x: str(int(x))),
293 'float': lambda conf: (r'-?[\d.]+', float, lambda x: str(float(x))),
294 'path': lambda conf: (r'.+?', None, None)}
295
296 def add_filter(self, name, func):
297 ''&#x27; Add a filter. The provided function is called with the configuration
298 string as parameter and must return a (regexp, to_python, to_url) tuple.
299 The first element is a string, the last two are callables or None. ''&#x27;
300 self.filters[name] = func
301
302 rule_syntax = re.compile('(\\\\*)'\
303 '(?:(?::([a-zA-Z_][a-zA-Z_0-9]*)?()(?:#(.*?)#)?)'\
304 '|(?:<([a-zA-Z_][a-zA-Z_0-9]*)?(?::([a-zA-Z_]*)'\
305 '(?::((?:\\\\.|[^\\\\>]+)+)?)?)?>))')
306
307 def _itertokens(self, rule):
308 offset, prefix = 0, ''
309 for match in self.rule_syntax.finditer(rule):
310 prefix += rule[offset:match.start()]
311 g = match.groups()
312 if len(g[0])%2: # Escaped wildcard
313 prefix += match.group(0)[len(g[0]):]
314 offset = match.end()
315 continue
316 if prefix:
317 yield prefix, None, None
318 name, filtr, conf = g[4:7] if g[2] is None else g[1:4]

Callers 1

__init__Method · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected