make strict_slashes default value configurable

This commit is contained in:
Yun Xu 2017-08-20 23:11:38 -07:00
parent 747c21da70
commit ef81a9f547
2 changed files with 50 additions and 23 deletions

View File

@ -28,7 +28,7 @@ class Sanic:
def __init__(self, name=None, router=None, error_handler=None, def __init__(self, name=None, router=None, error_handler=None,
load_env=True, request_class=None, load_env=True, request_class=None,
log_config=LOGGING): log_config=LOGGING, strict_slashes=False):
if log_config: if log_config:
logging.config.dictConfig(log_config) logging.config.dictConfig(log_config)
# Only set up a default log handler if the # Only set up a default log handler if the
@ -58,6 +58,7 @@ class Sanic:
self._blueprint_order = [] self._blueprint_order = []
self.debug = None self.debug = None
self.sock = None self.sock = None
self.strict_slashes = strict_slashes
self.listeners = defaultdict(list) self.listeners = defaultdict(list)
self.is_running = False self.is_running = False
self.is_request_stream = False self.is_request_stream = False
@ -111,7 +112,7 @@ class Sanic:
# Decorator # Decorator
def route(self, uri, methods=frozenset({'GET'}), host=None, def route(self, uri, methods=frozenset({'GET'}), host=None,
strict_slashes=False, stream=False, version=None): strict_slashes=None, stream=False, version=None):
"""Decorate a function to be registered as a route """Decorate a function to be registered as a route
:param uri: path of the URL :param uri: path of the URL
@ -130,6 +131,9 @@ class Sanic:
if stream: if stream:
self.is_request_stream = True self.is_request_stream = True
if strict_slashes is None:
strict_slashes = self.strict_slashes
def response(handler): def response(handler):
if stream: if stream:
handler.is_stream = stream handler.is_stream = stream
@ -141,42 +145,42 @@ class Sanic:
return response return response
# Shorthand method decorators # Shorthand method decorators
def get(self, uri, host=None, strict_slashes=False, version=None): def get(self, uri, host=None, strict_slashes=None, version=None):
return self.route(uri, methods=frozenset({"GET"}), host=host, return self.route(uri, methods=frozenset({"GET"}), host=host,
strict_slashes=strict_slashes, version=version) 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=None, stream=False,
version=None): version=None):
return self.route(uri, methods=frozenset({"POST"}), host=host, return self.route(uri, methods=frozenset({"POST"}), host=host,
strict_slashes=strict_slashes, stream=stream, strict_slashes=strict_slashes, stream=stream,
version=version) version=version)
def put(self, uri, host=None, strict_slashes=False, stream=False, def put(self, uri, host=None, strict_slashes=None, stream=False,
version=None): version=None):
return self.route(uri, methods=frozenset({"PUT"}), host=host, return self.route(uri, methods=frozenset({"PUT"}), host=host,
strict_slashes=strict_slashes, stream=stream, strict_slashes=strict_slashes, stream=stream,
version=version) version=version)
def head(self, uri, host=None, strict_slashes=False, version=None): def head(self, uri, host=None, strict_slashes=None, version=None):
return self.route(uri, methods=frozenset({"HEAD"}), host=host, return self.route(uri, methods=frozenset({"HEAD"}), host=host,
strict_slashes=strict_slashes, version=version) strict_slashes=strict_slashes, version=version)
def options(self, uri, host=None, strict_slashes=False, version=None): def options(self, uri, host=None, strict_slashes=None, version=None):
return self.route(uri, methods=frozenset({"OPTIONS"}), host=host, return self.route(uri, methods=frozenset({"OPTIONS"}), host=host,
strict_slashes=strict_slashes, version=version) 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=None, stream=False,
version=None): version=None):
return self.route(uri, methods=frozenset({"PATCH"}), host=host, return self.route(uri, methods=frozenset({"PATCH"}), host=host,
strict_slashes=strict_slashes, stream=stream, strict_slashes=strict_slashes, stream=stream,
version=version) version=version)
def delete(self, uri, host=None, strict_slashes=False, version=None): def delete(self, uri, host=None, strict_slashes=None, version=None):
return self.route(uri, methods=frozenset({"DELETE"}), host=host, return self.route(uri, methods=frozenset({"DELETE"}), host=host,
strict_slashes=strict_slashes, version=version) strict_slashes=strict_slashes, version=version)
def add_route(self, handler, uri, methods=frozenset({'GET'}), host=None, def add_route(self, handler, uri, methods=frozenset({'GET'}), host=None,
strict_slashes=False, version=None): strict_slashes=None, version=None):
"""A helper method to register class instance or """A helper method to register class instance or
functions as a handler to the application url functions as a handler to the application url
routes. routes.
@ -208,13 +212,16 @@ class Sanic:
stream = True stream = True
break break
if strict_slashes is None:
strict_slashes = self.strict_slashes
self.route(uri=uri, methods=methods, host=host, self.route(uri=uri, methods=methods, host=host,
strict_slashes=strict_slashes, stream=stream, strict_slashes=strict_slashes, stream=stream,
version=version)(handler) version=version)(handler)
return handler return handler
# Decorator # Decorator
def websocket(self, uri, host=None, strict_slashes=False, def websocket(self, uri, host=None, strict_slashes=None,
subprotocols=None): subprotocols=None):
"""Decorate a function to be registered as a websocket route """Decorate a function to be registered as a websocket route
:param uri: path of the URL :param uri: path of the URL
@ -230,6 +237,9 @@ class Sanic:
if not uri.startswith('/'): if not uri.startswith('/'):
uri = '/' + uri uri = '/' + uri
if strict_slashes is None:
strict_slashes = self.strict_slashes
def response(handler): def response(handler):
async def websocket_handler(request, *args, **kwargs): async def websocket_handler(request, *args, **kwargs):
request.app = self request.app = self
@ -261,8 +271,11 @@ class Sanic:
return response return response
def add_websocket_route(self, handler, uri, host=None, def add_websocket_route(self, handler, uri, host=None,
strict_slashes=False): strict_slashes=None):
"""A helper method to register a function as a websocket route.""" """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, return self.websocket(uri, host=host,
strict_slashes=strict_slashes)(handler) strict_slashes=strict_slashes)(handler)

View File

@ -14,7 +14,11 @@ FutureStatic = namedtuple('Route',
class Blueprint: class Blueprint:
def __init__(self, name, url_prefix=None, host=None, version=None):
def __init__(self, name,
url_prefix=None,
host=None, version=None,
strict_slashes=False):
"""Create a new blueprint """Create a new blueprint
:param name: unique name of the blueprint :param name: unique name of the blueprint
@ -31,6 +35,7 @@ class Blueprint:
self.middlewares = [] self.middlewares = []
self.statics = [] self.statics = []
self.version = version self.version = version
self.strict_slashes = strict_slashes
def register(self, app, options): def register(self, app, options):
"""Register the blueprint to the sanic app.""" """Register the blueprint to the sanic app."""
@ -94,12 +99,15 @@ class Blueprint:
app.listener(event)(listener) app.listener(event)(listener)
def route(self, uri, methods=frozenset({'GET'}), host=None, def route(self, uri, methods=frozenset({'GET'}), host=None,
strict_slashes=False, stream=False, version=None): strict_slashes=None, stream=False, version=None):
"""Create a blueprint route from a decorated function. """Create a blueprint route from a decorated function.
:param uri: endpoint at which the route will be accessible. :param uri: endpoint at which the route will be accessible.
:param methods: list of acceptable HTTP methods. :param methods: list of acceptable HTTP methods.
""" """
if strict_slashes is None:
strict_slashes = self.strict_slashes
def decorator(handler): def decorator(handler):
route = FutureRoute( route = FutureRoute(
handler, uri, methods, host, strict_slashes, stream, version) handler, uri, methods, host, strict_slashes, stream, version)
@ -108,7 +116,7 @@ class Blueprint:
return decorator return decorator
def add_route(self, handler, uri, methods=frozenset({'GET'}), host=None, def add_route(self, handler, uri, methods=frozenset({'GET'}), host=None,
strict_slashes=False, version=None): strict_slashes=None, version=None):
"""Create a blueprint route from a function. """Create a blueprint route from a function.
:param handler: function for handling uri requests. Accepts function, :param handler: function for handling uri requests. Accepts function,
@ -125,6 +133,9 @@ class Blueprint:
if getattr(handler.view_class, method.lower(), None): if getattr(handler.view_class, method.lower(), None):
methods.add(method) methods.add(method)
if strict_slashes is None:
strict_slashes = self.strict_slashes
# handle composition view differently # handle composition view differently
if isinstance(handler, CompositionView): if isinstance(handler, CompositionView):
methods = handler.handlers.keys() methods = handler.handlers.keys()
@ -133,11 +144,14 @@ class Blueprint:
strict_slashes=strict_slashes, version=version)(handler) strict_slashes=strict_slashes, version=version)(handler)
return handler return handler
def websocket(self, uri, host=None, strict_slashes=False, version=None): def websocket(self, uri, host=None, strict_slashes=None, version=None):
"""Create a blueprint websocket route from a decorated function. """Create a blueprint websocket route from a decorated function.
:param uri: endpoint at which the route will be accessible. :param uri: endpoint at which the route will be accessible.
""" """
if strict_slashes is None:
strict_slashes = self.strict_slashes
def decorator(handler): def decorator(handler):
route = FutureRoute(handler, uri, [], host, strict_slashes, route = FutureRoute(handler, uri, [], host, strict_slashes,
False, version) False, version)
@ -199,36 +213,36 @@ class Blueprint:
self.statics.append(static) self.statics.append(static)
# Shorthand method decorators # Shorthand method decorators
def get(self, uri, host=None, strict_slashes=False, version=None): def get(self, uri, host=None, strict_slashes=None, version=None):
return self.route(uri, methods=["GET"], host=host, return self.route(uri, methods=["GET"], host=host,
strict_slashes=strict_slashes, version=version) 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=None, stream=False,
version=None): version=None):
return self.route(uri, methods=["POST"], host=host, return self.route(uri, methods=["POST"], host=host,
strict_slashes=strict_slashes, stream=stream, strict_slashes=strict_slashes, stream=stream,
version=version) version=version)
def put(self, uri, host=None, strict_slashes=False, stream=False, def put(self, uri, host=None, strict_slashes=None, stream=False,
version=None): version=None):
return self.route(uri, methods=["PUT"], host=host, return self.route(uri, methods=["PUT"], host=host,
strict_slashes=strict_slashes, stream=stream, strict_slashes=strict_slashes, stream=stream,
version=version) version=version)
def head(self, uri, host=None, strict_slashes=False, version=None): def head(self, uri, host=None, strict_slashes=None, version=None):
return self.route(uri, methods=["HEAD"], host=host, return self.route(uri, methods=["HEAD"], host=host,
strict_slashes=strict_slashes, version=version) strict_slashes=strict_slashes, version=version)
def options(self, uri, host=None, strict_slashes=False, version=None): def options(self, uri, host=None, strict_slashes=None, version=None):
return self.route(uri, methods=["OPTIONS"], host=host, return self.route(uri, methods=["OPTIONS"], host=host,
strict_slashes=strict_slashes, version=version) 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=None, stream=False,
version=None): version=None):
return self.route(uri, methods=["PATCH"], host=host, return self.route(uri, methods=["PATCH"], host=host,
strict_slashes=strict_slashes, stream=stream, strict_slashes=strict_slashes, stream=stream,
version=version) version=version)
def delete(self, uri, host=None, strict_slashes=False, version=None): def delete(self, uri, host=None, strict_slashes=None, version=None):
return self.route(uri, methods=["DELETE"], host=host, return self.route(uri, methods=["DELETE"], host=host,
strict_slashes=strict_slashes, version=version) strict_slashes=strict_slashes, version=version)