This commit is contained in:
Adam Hopkins
2021-02-01 09:56:58 +02:00
8 changed files with 154 additions and 34 deletions

View File

@@ -24,6 +24,7 @@ from sanic.blueprints import Blueprint
from sanic.config import BASE_LOGO, Config
from sanic.exceptions import (
InvalidUsage,
MethodNotSupported,
NotFound,
SanicException,
ServerError,
@@ -82,9 +83,7 @@ class Sanic(BaseSanic):
self.name = name
self.asgi = False
self.router = router or Router(
exception=NotFound, method_handler_exception=NotFound
)
self.router = router or Router()
self.request_class = request_class
self.error_handler = error_handler or ErrorHandler()
self.config = Config(load_env=load_env)
@@ -103,6 +102,7 @@ class Sanic(BaseSanic):
self.websocket_tasks: Set[Future] = set()
self.named_request_middleware: Dict[str, MiddlewareType] = {}
self.named_response_middleware: Dict[str, MiddlewareType] = {}
self._test_manager = None
self._test_client = None
self._asgi_client = None
# Register alternative method names
@@ -234,7 +234,6 @@ class Sanic(BaseSanic):
middleware: FutureMiddleware,
route_names: Optional[List[str]] = None,
):
print(f"{middleware=}")
if route_names:
return self.register_named_middleware(
middleware.middleware, route_names, middleware.attach_to
@@ -589,18 +588,22 @@ class Sanic(BaseSanic):
# -------------------------------------------------------------------- #
@property
def test_client(self):
def test_client(self): # noqa
if self._test_client:
return self._test_client
elif self._test_manager:
return self._test_manager.test_client
from sanic_testing.testing import SanicTestClient # type: ignore
self._test_client = SanicTestClient(self)
return self._test_client
@property
def asgi_client(self):
def asgi_client(self): # noqa
if self._asgi_client:
return self._asgi_client
elif self._test_manager:
return self._test_manager.asgi_client
from sanic_testing.testing import SanicASGITestClient # type: ignore
self._asgi_client = SanicASGITestClient(self)
@@ -879,7 +882,13 @@ class Sanic(BaseSanic):
):
"""Helper function used by `run` and `create_server`."""
self.router.finalize()
# TODO:
# - Catch proper exception
try:
self.router.finalize()
except Exception as e:
if not Sanic.test_mode:
raise e
if isinstance(ssl, dict):
# try common aliaseses

View File

@@ -100,7 +100,7 @@ class RouteMixin:
route = FutureRoute(
handler,
uri,
methods,
frozenset([x.upper() for x in methods]),
host,
strict_slashes,
stream,

View File

@@ -2,9 +2,12 @@ from functools import lru_cache
from typing import Iterable, Optional, Union
from sanic_routing import BaseRouter
from sanic_routing.exceptions import NoMethod
from sanic_routing.exceptions import NotFound as RoutingNotFound
from sanic_routing.route import Route
from sanic.constants import HTTP_METHODS
from sanic.exceptions import MethodNotSupported, NotFound
from sanic.request import Request
@@ -17,7 +20,7 @@ class Router(BaseRouter):
DEFAULT_METHOD = "GET"
ALLOWED_METHODS = HTTP_METHODS
@lru_cache
# @lru_cache
def get(self, request: Request):
"""
Retrieve a `Route` object containg the details about how to handle
@@ -30,10 +33,21 @@ class Router(BaseRouter):
:rtype: Tuple[ RouteHandler, Tuple[Any, ...], Dict[str, Any], str, str,
Optional[str], bool, ]
"""
route, handler, params = self.resolve(
path=request.path,
method=request.method,
)
try:
route, handler, params = self.resolve(
path=request.path,
method=request.method,
)
except RoutingNotFound as e:
raise NotFound("Requested URL {} not found".format(e.path))
except NoMethod as e:
raise MethodNotSupported(
"Method {} not allowed for URL {}".format(
request.method, request.url
),
method=request.method,
allowed_methods=e.allowed_methods,
)
# TODO: Implement response
# - args,
@@ -98,9 +112,30 @@ class Router(BaseRouter):
uri = "/".join([f"/v{version}", uri.lstrip("/")])
route = super().add(
path=uri, handler=handler, methods=methods, name=name
path=uri,
handler=handler,
methods=methods,
name=name,
strict=strict_slashes,
)
route.ctx.ignore_body = ignore_body
route.ctx.stream = stream
return route
def is_stream_handler(self, request) -> bool:
"""
Handler for request is stream or not.
:param request: Request object
:return: bool
"""
try:
handler = self.get(request)[0]
except (NotFound, MethodNotSupported):
return False
if hasattr(handler, "view_class") and hasattr(
handler.view_class, request.method.lower()
):
handler = getattr(handler.view_class, request.method.lower())
return hasattr(handler, "is_stream")