add versioning
This commit is contained in:
44
sanic/app.py
44
sanic/app.py
@@ -113,7 +113,7 @@ class Sanic:
|
||||
|
||||
# Decorator
|
||||
def route(self, uri, methods=frozenset({'GET'}), host=None,
|
||||
strict_slashes=False, stream=False):
|
||||
strict_slashes=False, stream=False, version=None):
|
||||
"""Decorate a function to be registered as a route
|
||||
|
||||
:param uri: path of the URL
|
||||
@@ -136,42 +136,49 @@ class Sanic:
|
||||
if stream:
|
||||
handler.is_stream = stream
|
||||
self.router.add(uri=uri, methods=methods, handler=handler,
|
||||
host=host, strict_slashes=strict_slashes)
|
||||
host=host, strict_slashes=strict_slashes,
|
||||
version=version)
|
||||
return handler
|
||||
|
||||
return response
|
||||
|
||||
# Shorthand method decorators
|
||||
def get(self, uri, host=None, strict_slashes=False):
|
||||
def get(self, uri, host=None, strict_slashes=False, version=None):
|
||||
return self.route(uri, methods=frozenset({"GET"}), host=host,
|
||||
strict_slashes=strict_slashes)
|
||||
strict_slashes=strict_slashes, version=version)
|
||||
|
||||
def post(self, uri, host=None, strict_slashes=False, stream=False):
|
||||
def post(self, uri, host=None, strict_slashes=False, stream=False,
|
||||
version=None):
|
||||
return self.route(uri, methods=frozenset({"POST"}), host=host,
|
||||
strict_slashes=strict_slashes, stream=stream)
|
||||
strict_slashes=strict_slashes, stream=stream,
|
||||
version=version)
|
||||
|
||||
def put(self, uri, host=None, strict_slashes=False, stream=False):
|
||||
def put(self, uri, host=None, strict_slashes=False, stream=False,
|
||||
version=None):
|
||||
return self.route(uri, methods=frozenset({"PUT"}), host=host,
|
||||
strict_slashes=strict_slashes, stream=stream)
|
||||
strict_slashes=strict_slashes, stream=stream,
|
||||
version=version)
|
||||
|
||||
def head(self, uri, host=None, strict_slashes=False):
|
||||
def head(self, uri, host=None, strict_slashes=False, version=None):
|
||||
return self.route(uri, methods=frozenset({"HEAD"}), host=host,
|
||||
strict_slashes=strict_slashes)
|
||||
strict_slashes=strict_slashes, version=version)
|
||||
|
||||
def options(self, uri, host=None, strict_slashes=False):
|
||||
def options(self, uri, host=None, strict_slashes=False, version=None):
|
||||
return self.route(uri, methods=frozenset({"OPTIONS"}), host=host,
|
||||
strict_slashes=strict_slashes)
|
||||
strict_slashes=strict_slashes, version=version)
|
||||
|
||||
def patch(self, uri, host=None, strict_slashes=False, stream=False):
|
||||
def patch(self, uri, host=None, strict_slashes=False, stream=False,
|
||||
version=None):
|
||||
return self.route(uri, methods=frozenset({"PATCH"}), host=host,
|
||||
strict_slashes=strict_slashes, stream=stream)
|
||||
strict_slashes=strict_slashes, stream=stream,
|
||||
version=version)
|
||||
|
||||
def delete(self, uri, host=None, strict_slashes=False):
|
||||
def delete(self, uri, host=None, strict_slashes=False, version=None):
|
||||
return self.route(uri, methods=frozenset({"DELETE"}), host=host,
|
||||
strict_slashes=strict_slashes)
|
||||
strict_slashes=strict_slashes, version=version)
|
||||
|
||||
def add_route(self, handler, uri, methods=frozenset({'GET'}), host=None,
|
||||
strict_slashes=False):
|
||||
strict_slashes=False, version=None):
|
||||
"""A helper method to register class instance or
|
||||
functions as a handler to the application url
|
||||
routes.
|
||||
@@ -204,7 +211,8 @@ class Sanic:
|
||||
break
|
||||
|
||||
self.route(uri=uri, methods=methods, host=host,
|
||||
strict_slashes=strict_slashes, stream=stream)(handler)
|
||||
strict_slashes=strict_slashes, stream=stream,
|
||||
version=version)(handler)
|
||||
return handler
|
||||
|
||||
# Decorator
|
||||
|
||||
@@ -4,8 +4,8 @@ from sanic.constants import HTTP_METHODS
|
||||
from sanic.views import CompositionView
|
||||
|
||||
FutureRoute = namedtuple('Route',
|
||||
['handler', 'uri', 'methods',
|
||||
'host', 'strict_slashes', 'stream'])
|
||||
['handler', 'uri', 'methods', 'host',
|
||||
'strict_slashes', 'stream', 'version'])
|
||||
FutureListener = namedtuple('Listener', ['handler', 'uri', 'methods', 'host'])
|
||||
FutureMiddleware = namedtuple('Route', ['middleware', 'args', 'kwargs'])
|
||||
FutureException = namedtuple('Route', ['handler', 'args', 'kwargs'])
|
||||
@@ -14,7 +14,7 @@ FutureStatic = namedtuple('Route',
|
||||
|
||||
|
||||
class Blueprint:
|
||||
def __init__(self, name, url_prefix=None, host=None):
|
||||
def __init__(self, name, url_prefix=None, host=None, version=None):
|
||||
"""Create a new blueprint
|
||||
|
||||
:param name: unique name of the blueprint
|
||||
@@ -30,6 +30,7 @@ class Blueprint:
|
||||
self.listeners = defaultdict(list)
|
||||
self.middlewares = []
|
||||
self.statics = []
|
||||
self.version = version
|
||||
|
||||
def register(self, app, options):
|
||||
"""Register the blueprint to the sanic app."""
|
||||
@@ -43,12 +44,16 @@ 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
|
||||
|
||||
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
|
||||
stream=future.stream,
|
||||
version=version
|
||||
)(future.handler)
|
||||
|
||||
for future in self.websocket_routes:
|
||||
@@ -89,7 +94,7 @@ class Blueprint:
|
||||
app.listener(event)(listener)
|
||||
|
||||
def route(self, uri, methods=frozenset({'GET'}), host=None,
|
||||
strict_slashes=False, stream=False):
|
||||
strict_slashes=False, stream=False, version=None):
|
||||
"""Create a blueprint route from a decorated function.
|
||||
|
||||
:param uri: endpoint at which the route will be accessible.
|
||||
@@ -97,13 +102,13 @@ class Blueprint:
|
||||
"""
|
||||
def decorator(handler):
|
||||
route = FutureRoute(
|
||||
handler, uri, methods, host, strict_slashes, stream)
|
||||
handler, uri, methods, host, strict_slashes, stream, version)
|
||||
self.routes.append(route)
|
||||
return handler
|
||||
return decorator
|
||||
|
||||
def add_route(self, handler, uri, methods=frozenset({'GET'}), host=None,
|
||||
strict_slashes=False):
|
||||
strict_slashes=False, version=None):
|
||||
"""Create a blueprint route from a function.
|
||||
|
||||
:param handler: function for handling uri requests. Accepts function,
|
||||
@@ -125,21 +130,22 @@ class Blueprint:
|
||||
methods = handler.handlers.keys()
|
||||
|
||||
self.route(uri=uri, methods=methods, host=host,
|
||||
strict_slashes=strict_slashes)(handler)
|
||||
strict_slashes=strict_slashes, version=version)(handler)
|
||||
return handler
|
||||
|
||||
def websocket(self, uri, host=None, strict_slashes=False):
|
||||
def websocket(self, uri, host=None, strict_slashes=False, version=None):
|
||||
"""Create a blueprint websocket route from a decorated function.
|
||||
|
||||
:param uri: endpoint at which the route will be accessible.
|
||||
"""
|
||||
def decorator(handler):
|
||||
route = FutureRoute(handler, uri, [], host, strict_slashes, False)
|
||||
route = FutureRoute(handler, uri, [], host, strict_slashes,
|
||||
False, version)
|
||||
self.websocket_routes.append(route)
|
||||
return handler
|
||||
return decorator
|
||||
|
||||
def add_websocket_route(self, handler, uri, host=None):
|
||||
def add_websocket_route(self, handler, uri, host=None, version=None):
|
||||
"""Create a blueprint websocket route from a function.
|
||||
|
||||
:param handler: function for handling uri requests. Accepts function,
|
||||
@@ -147,7 +153,7 @@ class Blueprint:
|
||||
:param uri: endpoint at which the route will be accessible.
|
||||
:return: function or class instance
|
||||
"""
|
||||
self.websocket(uri=uri, host=host)(handler)
|
||||
self.websocket(uri=uri, host=host, version=version)(handler)
|
||||
return handler
|
||||
|
||||
def listener(self, event):
|
||||
@@ -193,30 +199,36 @@ class Blueprint:
|
||||
self.statics.append(static)
|
||||
|
||||
# Shorthand method decorators
|
||||
def get(self, uri, host=None, strict_slashes=False):
|
||||
def get(self, uri, host=None, strict_slashes=False, version=None):
|
||||
return self.route(uri, methods=["GET"], host=host,
|
||||
strict_slashes=strict_slashes)
|
||||
strict_slashes=strict_slashes, version=version)
|
||||
|
||||
def post(self, uri, host=None, strict_slashes=False, stream=False):
|
||||
def post(self, uri, host=None, strict_slashes=False, stream=False,
|
||||
version=None):
|
||||
return self.route(uri, methods=["POST"], host=host,
|
||||
strict_slashes=strict_slashes, stream=stream)
|
||||
strict_slashes=strict_slashes, stream=stream,
|
||||
version=version)
|
||||
|
||||
def put(self, uri, host=None, strict_slashes=False, stream=False):
|
||||
def put(self, uri, host=None, strict_slashes=False, stream=False,
|
||||
version=None):
|
||||
return self.route(uri, methods=["PUT"], host=host,
|
||||
strict_slashes=strict_slashes, stream=stream)
|
||||
strict_slashes=strict_slashes, stream=stream,
|
||||
version=version)
|
||||
|
||||
def head(self, uri, host=None, strict_slashes=False):
|
||||
def head(self, uri, host=None, strict_slashes=False, version=None):
|
||||
return self.route(uri, methods=["HEAD"], host=host,
|
||||
strict_slashes=strict_slashes)
|
||||
strict_slashes=strict_slashes, version=version)
|
||||
|
||||
def options(self, uri, host=None, strict_slashes=False):
|
||||
def options(self, uri, host=None, strict_slashes=False, version=None):
|
||||
return self.route(uri, methods=["OPTIONS"], host=host,
|
||||
strict_slashes=strict_slashes)
|
||||
strict_slashes=strict_slashes, version=version)
|
||||
|
||||
def patch(self, uri, host=None, strict_slashes=False, stream=False):
|
||||
def patch(self, uri, host=None, strict_slashes=False, stream=False,
|
||||
version=None):
|
||||
return self.route(uri, methods=["PATCH"], host=host,
|
||||
strict_slashes=strict_slashes, stream=stream)
|
||||
strict_slashes=strict_slashes, stream=stream,
|
||||
version=version)
|
||||
|
||||
def delete(self, uri, host=None, strict_slashes=False):
|
||||
def delete(self, uri, host=None, strict_slashes=False, version=None):
|
||||
return self.route(uri, methods=["DELETE"], host=host,
|
||||
strict_slashes=strict_slashes)
|
||||
strict_slashes=strict_slashes, version=version)
|
||||
|
||||
@@ -98,7 +98,8 @@ class Router:
|
||||
|
||||
return name, _type, pattern
|
||||
|
||||
def add(self, uri, methods, handler, host=None, strict_slashes=False):
|
||||
def add(self, uri, methods, handler, host=None, strict_slashes=False,
|
||||
version=None):
|
||||
"""Add a handler to the route list
|
||||
|
||||
:param uri: path to match
|
||||
@@ -107,8 +108,15 @@ class Router:
|
||||
:param handler: request handler function.
|
||||
When executed, it should provide a response object.
|
||||
:param strict_slashes: strict to trailing slash
|
||||
:param version: current version of the route or blueprint. See
|
||||
docs for further details.
|
||||
:return: Nothing
|
||||
"""
|
||||
if version is not None:
|
||||
if uri.startswith('/'):
|
||||
uri = "/".join(["/v{}".format(str(version)), uri[1:]])
|
||||
else:
|
||||
uri = "/".join(["/v{}".format(str(version)), uri])
|
||||
# add regular version
|
||||
self._add(uri, methods, handler, host)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user