MCPcopy Create free account
hub / github.com/datapane/datapane / Router

Class Router

python-client/src/datapane/_vendor/bottle.py:288–487  ·  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

286
287
288class Router(object):
289 """ A Router is an ordered collection of route->target pairs. It is used to
290 efficiently match WSGI requests against a number of routes and return
291 the first target that satisfies the request. The target may be anything,
292 usually a string, ID or callable object. A route consists of a path-rule
293 and a HTTP method.
294
295 The path-rule is either a static path (e.g. `/contact`) or a dynamic
296 path that contains wildcards (e.g. `/wiki/<page>`). The wildcard syntax
297 and details on the matching order are described in docs:`routing`.
298 """
299
300 default_pattern = '[^/]+'
301 default_filter = 're'
302
303 #: The current CPython regexp implementation does not allow more
304 #: than 99 matching groups per regular expression.
305 _MAX_GROUPS_PER_PATTERN = 99
306
307 def __init__(self, strict=False):
308 self.rules = [] # All rules in order
309 self._groups = {} # index of regexes to find them in dyna_routes
310 self.builder = {} # Data structure for the url builder
311 self.static = {} # Search structure for static routes
312 self.dyna_routes = {}
313 self.dyna_regexes = {} # Search structure for dynamic routes
314 #: If true, static routes are no longer checked first.
315 self.strict_order = strict
316 self.filters = {
317 're': lambda conf: (_re_flatten(conf or self.default_pattern),
318 None, None),
319 'int': lambda conf: (r'-?\d+', int, lambda x: str(int(x))),
320 'float': lambda conf: (r'-?[\d.]+', float, lambda x: str(float(x))),
321 'path': lambda conf: (r'.+?', None, None)
322 }
323
324 def add_filter(self, name, func):
325 """ Add a filter. The provided function is called with the configuration
326 string as parameter and must return a (regexp, to_python, to_url) tuple.
327 The first element is a string, the last two are callables or None. """
328 self.filters[name] = func
329
330 rule_syntax = re.compile('(\\\\*)'
331 '(?:(?::([a-zA-Z_][a-zA-Z_0-9]*)?()(?:#(.*?)#)?)'
332 '|(?:<([a-zA-Z_][a-zA-Z_0-9]*)?(?::([a-zA-Z_]*)'
333 '(?::((?:\\\\.|[^\\\\>])+)?)?)?>))')
334
335 def _itertokens(self, rule):
336 offset, prefix = 0, ''
337 for match in self.rule_syntax.finditer(rule):
338 prefix += rule[offset:match.start()]
339 g = match.groups()
340 if g[2] is not None:
341 depr(0, 13, "Use of old route syntax.",
342 "Use <name> instead of :name in routes.")
343 if len(g[0]) % 2: # Escaped wildcard
344 prefix += match.group(0)[len(g[0]):]
345 offset = match.end()

Callers 1

__init__Method · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected