add name option for route building

This commit is contained in:
lixxu
2017-08-21 18:05:34 +08:00
parent 826f1b4713
commit eab809d410
5 changed files with 517 additions and 70 deletions

View File

@@ -112,7 +112,7 @@ class Sanic:
# Decorator
def route(self, uri, methods=frozenset({'GET'}), host=None,
strict_slashes=None, stream=False, version=None):
strict_slashes=None, stream=False, version=None, name=None):
"""Decorate a function to be registered as a route
:param uri: path of the URL
@@ -120,6 +120,8 @@ class Sanic:
:param host:
:param strict_slashes:
:param stream:
:param version:
:param name: user defined route name for url_for
:return: decorated function
"""
@@ -139,48 +141,56 @@ class Sanic:
handler.is_stream = stream
self.router.add(uri=uri, methods=methods, handler=handler,
host=host, strict_slashes=strict_slashes,
version=version)
version=version, name=name)
return handler
return response
# Shorthand method decorators
def get(self, uri, host=None, strict_slashes=None, version=None):
def get(self, uri, host=None, strict_slashes=None, version=None,
name=None):
return self.route(uri, methods=frozenset({"GET"}), host=host,
strict_slashes=strict_slashes, version=version)
strict_slashes=strict_slashes, version=version,
name=name)
def post(self, uri, host=None, strict_slashes=None, stream=False,
version=None):
version=None, name=None):
return self.route(uri, methods=frozenset({"POST"}), host=host,
strict_slashes=strict_slashes, stream=stream,
version=version)
version=version, name=name)
def put(self, uri, host=None, strict_slashes=None, stream=False,
version=None):
version=None, name=None):
return self.route(uri, methods=frozenset({"PUT"}), host=host,
strict_slashes=strict_slashes, stream=stream,
version=version)
version=version, name=name)
def head(self, uri, host=None, strict_slashes=None, version=None):
def head(self, uri, host=None, strict_slashes=None, version=None,
name=None):
return self.route(uri, methods=frozenset({"HEAD"}), host=host,
strict_slashes=strict_slashes, version=version)
strict_slashes=strict_slashes, version=version,
name=name)
def options(self, uri, host=None, strict_slashes=None, version=None):
def options(self, uri, host=None, strict_slashes=None, version=None,
name=None):
return self.route(uri, methods=frozenset({"OPTIONS"}), host=host,
strict_slashes=strict_slashes, version=version)
strict_slashes=strict_slashes, version=version,
name=name)
def patch(self, uri, host=None, strict_slashes=None, stream=False,
version=None):
version=None, name=None):
return self.route(uri, methods=frozenset({"PATCH"}), host=host,
strict_slashes=strict_slashes, stream=stream,
version=version)
version=version, name=name)
def delete(self, uri, host=None, strict_slashes=None, version=None):
def delete(self, uri, host=None, strict_slashes=None, version=None,
name=None):
return self.route(uri, methods=frozenset({"DELETE"}), host=host,
strict_slashes=strict_slashes, version=version)
strict_slashes=strict_slashes, version=version,
name=name)
def add_route(self, handler, uri, methods=frozenset({'GET'}), host=None,
strict_slashes=None, version=None):
strict_slashes=None, version=None, name=None):
"""A helper method to register class instance or
functions as a handler to the application url
routes.
@@ -190,6 +200,9 @@ class Sanic:
:param methods: list or tuple of methods allowed, these are overridden
if using a HTTPMethodView
:param host:
:param strict_slashes:
:param version:
:param name: user defined route name for url_for
:return: function or class instance
"""
stream = False
@@ -217,12 +230,12 @@ class Sanic:
self.route(uri=uri, methods=methods, host=host,
strict_slashes=strict_slashes, stream=stream,
version=version)(handler)
version=version, name=name)(handler)
return handler
# Decorator
def websocket(self, uri, host=None, strict_slashes=None,
subprotocols=None):
subprotocols=None, name=None):
"""Decorate a function to be registered as a websocket route
:param uri: path of the URL
:param subprotocols: optional list of strings with the supported
@@ -265,19 +278,19 @@ class Sanic:
self.router.add(uri=uri, handler=websocket_handler,
methods=frozenset({'GET'}), host=host,
strict_slashes=strict_slashes)
strict_slashes=strict_slashes, name=name)
return handler
return response
def add_websocket_route(self, handler, uri, host=None,
strict_slashes=None):
strict_slashes=None, name=None):
"""A helper method to register a function as a websocket route."""
if strict_slashes is None:
strict_slashes = self.strict_slashes
return self.websocket(uri, host=host,
strict_slashes=strict_slashes)(handler)
return self.websocket(uri, host=host, strict_slashes=strict_slashes,
name=name)(handler)
def enable_websocket(self, enable=True):
"""Enable or disable the support for websocket.
@@ -400,9 +413,8 @@ class Sanic:
uri, route = self.router.find_route_by_view_name(view_name)
if not uri or not route:
raise URLBuildError(
'Endpoint with name `{}` was not found'.format(
view_name))
raise URLBuildError('Endpoint with name `{}` was not found'.format(
view_name))
if uri != '/' and uri.endswith('/'):
uri = uri[:-1]

View File

@@ -5,7 +5,7 @@ from sanic.views import CompositionView
FutureRoute = namedtuple('Route',
['handler', 'uri', 'methods', 'host',
'strict_slashes', 'stream', 'version'])
'strict_slashes', 'stream', 'version', 'name'])
FutureListener = namedtuple('Listener', ['handler', 'uri', 'methods', 'host'])
FutureMiddleware = namedtuple('Route', ['middleware', 'args', 'kwargs'])
FutureException = namedtuple('Route', ['handler', 'args', 'kwargs'])
@@ -53,14 +53,14 @@ class Blueprint:
version = future.version or self.version
app.route(
uri=uri[1:] if uri.startswith('//') else uri,
methods=future.methods,
host=future.host or self.host,
strict_slashes=future.strict_slashes,
stream=future.stream,
version=version
)(future.handler)
app.route(uri=uri[1:] if uri.startswith('//') else uri,
methods=future.methods,
host=future.host or self.host,
strict_slashes=future.strict_slashes,
stream=future.stream,
version=version,
name=future.name,
)(future.handler)
for future in self.websocket_routes:
# attach the blueprint name to the handler so that it can be
@@ -68,11 +68,11 @@ class Blueprint:
future.handler.__blueprintname__ = self.name
# Prepend the blueprint URI prefix if available
uri = url_prefix + future.uri if url_prefix else future.uri
app.websocket(
uri=uri,
host=future.host or self.host,
strict_slashes=future.strict_slashes
)(future.handler)
app.websocket(uri=uri,
host=future.host or self.host,
strict_slashes=future.strict_slashes,
name=future.name,
)(future.handler)
# Middleware
for future in self.middlewares:
@@ -100,7 +100,7 @@ class Blueprint:
app.listener(event)(listener)
def route(self, uri, methods=frozenset({'GET'}), host=None,
strict_slashes=None, stream=False, version=None):
strict_slashes=None, stream=False, version=None, name=None):
"""Create a blueprint route from a decorated function.
:param uri: endpoint at which the route will be accessible.
@@ -111,19 +111,24 @@ class Blueprint:
def decorator(handler):
route = FutureRoute(
handler, uri, methods, host, strict_slashes, stream, version)
handler, uri, methods, host, strict_slashes, stream, version,
name)
self.routes.append(route)
return handler
return decorator
def add_route(self, handler, uri, methods=frozenset({'GET'}), host=None,
strict_slashes=None, version=None):
strict_slashes=None, version=None, name=None):
"""Create a blueprint route from a function.
:param handler: function for handling uri requests. Accepts function,
or class instance with a view_class method.
:param uri: endpoint at which the route will be accessible.
:param methods: list of acceptable HTTP methods.
:param host:
:param strict_slashes:
:param version:
:param name: user defined route name for url_for
:return: function or class instance
"""
# Handle HTTPMethodView differently
@@ -142,10 +147,12 @@ class Blueprint:
methods = handler.handlers.keys()
self.route(uri=uri, methods=methods, host=host,
strict_slashes=strict_slashes, version=version)(handler)
strict_slashes=strict_slashes, version=version,
name=name)(handler)
return handler
def websocket(self, uri, host=None, strict_slashes=None, version=None):
def websocket(self, uri, host=None, strict_slashes=None, version=None,
name=None):
"""Create a blueprint websocket route from a decorated function.
:param uri: endpoint at which the route will be accessible.
@@ -155,12 +162,13 @@ class Blueprint:
def decorator(handler):
route = FutureRoute(handler, uri, [], host, strict_slashes,
False, version)
False, version, name)
self.websocket_routes.append(route)
return handler
return decorator
def add_websocket_route(self, handler, uri, host=None, version=None):
def add_websocket_route(self, handler, uri, host=None, version=None,
name=None):
"""Create a blueprint websocket route from a function.
:param handler: function for handling uri requests. Accepts function,
@@ -168,7 +176,7 @@ class Blueprint:
:param uri: endpoint at which the route will be accessible.
:return: function or class instance
"""
self.websocket(uri=uri, host=host, version=version)(handler)
self.websocket(uri=uri, host=host, version=version, name=name)(handler)
return handler
def listener(self, event):
@@ -214,36 +222,44 @@ class Blueprint:
self.statics.append(static)
# Shorthand method decorators
def get(self, uri, host=None, strict_slashes=None, version=None):
def get(self, uri, host=None, strict_slashes=None, version=None,
name=None):
return self.route(uri, methods=["GET"], host=host,
strict_slashes=strict_slashes, version=version)
strict_slashes=strict_slashes, version=version,
name=name)
def post(self, uri, host=None, strict_slashes=None, stream=False,
version=None):
version=None, name=None):
return self.route(uri, methods=["POST"], host=host,
strict_slashes=strict_slashes, stream=stream,
version=version)
version=version, name=name)
def put(self, uri, host=None, strict_slashes=None, stream=False,
version=None):
version=None, name=None):
return self.route(uri, methods=["PUT"], host=host,
strict_slashes=strict_slashes, stream=stream,
version=version)
version=version, name=name)
def head(self, uri, host=None, strict_slashes=None, version=None):
def head(self, uri, host=None, strict_slashes=None, version=None,
name=None):
return self.route(uri, methods=["HEAD"], host=host,
strict_slashes=strict_slashes, version=version)
strict_slashes=strict_slashes, version=version,
name=name)
def options(self, uri, host=None, strict_slashes=None, version=None):
def options(self, uri, host=None, strict_slashes=None, version=None,
name=None):
return self.route(uri, methods=["OPTIONS"], host=host,
strict_slashes=strict_slashes, version=version)
strict_slashes=strict_slashes, version=version,
name=name)
def patch(self, uri, host=None, strict_slashes=None, stream=False,
version=None):
version=None, name=None):
return self.route(uri, methods=["PATCH"], host=host,
strict_slashes=strict_slashes, stream=stream,
version=version)
version=version, name=name)
def delete(self, uri, host=None, strict_slashes=None, version=None):
def delete(self, uri, host=None, strict_slashes=None, version=None,
name=None):
return self.route(uri, methods=["DELETE"], host=host,
strict_slashes=strict_slashes, version=version)
strict_slashes=strict_slashes, version=version,
name=name)

View File

@@ -99,7 +99,7 @@ class Router:
return name, _type, pattern
def add(self, uri, methods, handler, host=None, strict_slashes=False,
version=None):
version=None, name=None):
"""Add a handler to the route list
:param uri: path to match
@@ -118,7 +118,7 @@ class Router:
else:
uri = "/".join(["/v{}".format(str(version)), uri])
# add regular version
self._add(uri, methods, handler, host)
self._add(uri, methods, handler, host, name)
if strict_slashes:
return
@@ -135,12 +135,12 @@ class Router:
)
# add version with trailing slash
if slash_is_missing:
self._add(uri + '/', methods, handler, host)
self._add(uri + '/', methods, handler, host, name)
# add version without trailing slash
elif without_slash_is_missing:
self._add(uri[:-1], methods, handler, host)
self._add(uri[:-1], methods, handler, host, name)
def _add(self, uri, methods, handler, host=None):
def _add(self, uri, methods, handler, host=None, name=None):
"""Add a handler to the route list
:param uri: path to match
@@ -161,7 +161,7 @@ class Router:
"host strings, not {!r}".format(host))
for host_ in host:
self.add(uri, methods, handler, host_)
self.add(uri, methods, handler, host_, name)
return
# Dict for faster lookups of if method allowed
@@ -236,9 +236,9 @@ class Router:
# if available
if hasattr(handler, '__blueprintname__'):
handler_name = '{}.{}'.format(
handler.__blueprintname__, handler.__name__)
handler.__blueprintname__, name or handler.__name__)
else:
handler_name = getattr(handler, '__name__', None)
handler_name = name or getattr(handler, '__name__', None)
route = Route(
handler=handler, methods=methods, pattern=pattern,