diff --git a/sanic/app.py b/sanic/app.py index 310d9059..a81bb4a8 100644 --- a/sanic/app.py +++ b/sanic/app.py @@ -5,7 +5,7 @@ import warnings from asyncio import get_event_loop, ensure_future, CancelledError from collections import deque, defaultdict from functools import partial -from inspect import isawaitable, stack, getmodulename +from inspect import getmodulename, isawaitable, signature, stack from traceback import format_exc from urllib.parse import urlencode, urlunparse from ssl import create_default_context, Purpose @@ -25,7 +25,6 @@ from sanic.websocket import WebSocketProtocol, ConnectionClosed class Sanic: - def __init__(self, name=None, router=None, error_handler=None, load_env=True, request_class=None, strict_slashes=False, log_config=None, @@ -111,9 +110,11 @@ class Sanic: :param event: event to listen to """ + def decorator(listener): self.listeners[event].append(listener) return listener + return decorator # Decorator @@ -143,12 +144,20 @@ class Sanic: strict_slashes = self.strict_slashes def response(handler): - if stream: - handler.is_stream = stream - self.router.add(uri=uri, methods=methods, handler=handler, - host=host, strict_slashes=strict_slashes, - version=version, name=name) - return handler + args = [key for key in signature(handler).parameters.keys()] + if args: + if stream: + handler.is_stream = stream + + self.router.add(uri=uri, methods=methods, handler=handler, + host=host, strict_slashes=strict_slashes, + version=version, name=name) + return handler + else: + raise ValueError( + 'Required parameter `request` missing' + 'in the {0}() route?'.format( + handler.__name__)) return response @@ -432,7 +441,7 @@ class Sanic: uri, route = self.router.find_route_by_view_name(view_name, **kw) if not (uri and route): raise URLBuildError('Endpoint with name `{}` was not found'.format( - view_name)) + view_name)) if view_name == 'static' or view_name.endswith('.static'): filename = kwargs.pop('filename', None) diff --git a/tests/test_url_building.py b/tests/test_url_building.py index ed41b017..670cafa5 100644 --- a/tests/test_url_building.py +++ b/tests/test_url_building.py @@ -75,7 +75,7 @@ def test_fails_if_endpoint_not_found(): app = Sanic('fail_url_build') @app.route('/fail') - def fail(): + def fail(request): return text('this should fail') with pytest.raises(URLBuildError) as e: @@ -93,7 +93,7 @@ def test_fails_url_build_if_param_not_passed(): app = Sanic('fail_url_build') @app.route(url) - def fail(): + def fail(request): return text('this should fail') fail_args = list(string.ascii_letters) @@ -111,7 +111,7 @@ def test_fails_url_build_if_params_not_passed(): app = Sanic('fail_url_build') @app.route('/fail') - def fail(): + def fail(request): return text('this should fail') with pytest.raises(ValueError) as e: @@ -134,7 +134,7 @@ def test_fails_with_int_message(): app = Sanic('fail_url_build') @app.route(COMPLEX_PARAM_URL) - def fail(): + def fail(request): return text('this should fail') failing_kwargs = dict(PASSING_KWARGS) @@ -153,7 +153,7 @@ def test_fails_with_two_letter_string_message(): app = Sanic('fail_url_build') @app.route(COMPLEX_PARAM_URL) - def fail(): + def fail(request): return text('this should fail') failing_kwargs = dict(PASSING_KWARGS) @@ -173,7 +173,7 @@ def test_fails_with_number_message(): app = Sanic('fail_url_build') @app.route(COMPLEX_PARAM_URL) - def fail(): + def fail(request): return text('this should fail') failing_kwargs = dict(PASSING_KWARGS) @@ -193,7 +193,7 @@ def test_adds_other_supplied_values_as_query_string(): app = Sanic('passes') @app.route(COMPLEX_PARAM_URL) - def passes(): + def passes(request): return text('this should pass') new_kwargs = dict(PASSING_KWARGS) @@ -216,7 +216,7 @@ def blueprint_app(): second_print = Blueprint('second', url_prefix='/second') @first_print.route('/foo') - def foo(): + def foo(request): return text('foo from first') @first_print.route('/foo/') @@ -225,7 +225,7 @@ def blueprint_app(): 'foo from first : {}'.format(param)) @second_print.route('/foo') # noqa - def foo(): + def foo(request): return text('foo from second') @second_print.route('/foo/') # noqa