Add simple uri hash to lookup
This commit is contained in:
parent
f4b45deb7f
commit
fc4c192237
|
@ -1,5 +1,5 @@
|
||||||
import re
|
import re
|
||||||
from collections import namedtuple
|
from collections import defaultdict, namedtuple
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from .config import Config
|
from .config import Config
|
||||||
from .exceptions import NotFound, InvalidUsage
|
from .exceptions import NotFound, InvalidUsage
|
||||||
|
@ -15,6 +15,10 @@ REGEX_TYPES = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def url_hash(url):
|
||||||
|
return '/'.join(':' for s in url.split('/'))
|
||||||
|
|
||||||
|
|
||||||
class Router:
|
class Router:
|
||||||
"""
|
"""
|
||||||
Router supports basic routing with parameters and method checks
|
Router supports basic routing with parameters and method checks
|
||||||
|
@ -36,7 +40,7 @@ class Router:
|
||||||
routes = None
|
routes = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.routes = []
|
self.routes = defaultdict(list)
|
||||||
|
|
||||||
def add(self, uri, methods, handler):
|
def add(self, uri, methods, handler):
|
||||||
"""
|
"""
|
||||||
|
@ -74,7 +78,10 @@ class Router:
|
||||||
route = Route(
|
route = Route(
|
||||||
handler=handler, methods=methods, pattern=pattern,
|
handler=handler, methods=methods, pattern=pattern,
|
||||||
parameters=parameters)
|
parameters=parameters)
|
||||||
self.routes.append(route)
|
|
||||||
|
if parameters:
|
||||||
|
uri = url_hash(uri)
|
||||||
|
self.routes[uri].append(route)
|
||||||
|
|
||||||
@lru_cache(maxsize=Config.ROUTER_CACHE_SIZE)
|
@lru_cache(maxsize=Config.ROUTER_CACHE_SIZE)
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
@ -85,17 +92,22 @@ class Router:
|
||||||
:return: handler, arguments, keyword arguments
|
:return: handler, arguments, keyword arguments
|
||||||
"""
|
"""
|
||||||
route = None
|
route = None
|
||||||
for route in self.routes:
|
url = request.url
|
||||||
match = route.pattern.match(request.url)
|
if url in self.routes:
|
||||||
if match:
|
route = self.routes[url][0]
|
||||||
break
|
match = route.pattern.match(url)
|
||||||
else:
|
else:
|
||||||
raise NotFound('Requested URL {} not found'.format(request.url))
|
for route in self.routes[url_hash(url)]:
|
||||||
|
match = route.pattern.match(url)
|
||||||
|
if match:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise NotFound('Requested URL {} not found'.format(url))
|
||||||
|
|
||||||
if route.methods and request.method not in route.methods:
|
if route.methods and request.method not in route.methods:
|
||||||
raise InvalidUsage(
|
raise InvalidUsage(
|
||||||
'Method {} not allowed for URL {}'.format(
|
'Method {} not allowed for URL {}'.format(
|
||||||
request.method, request.url), status_code=405)
|
request.method, url), status_code=405)
|
||||||
|
|
||||||
kwargs = {p.name: p.cast(value) for value, p in zip(match.groups(1), route.parameters)}
|
kwargs = {p.name: p.cast(value) for value, p in zip(match.groups(1), route.parameters)}
|
||||||
return route.handler, [], kwargs
|
return route.handler, [], kwargs
|
||||||
|
|
Loading…
Reference in New Issue
Block a user