Cleanup type checking
This commit is contained in:
parent
209579f280
commit
d402d0362e
15
sanic/app.py
15
sanic/app.py
|
@ -243,6 +243,7 @@ class Sanic(BaseSanic):
|
||||||
self.named_response_middleware[_rn] = deque()
|
self.named_response_middleware[_rn] = deque()
|
||||||
if middleware not in self.named_response_middleware[_rn]:
|
if middleware not in self.named_response_middleware[_rn]:
|
||||||
self.named_response_middleware[_rn].appendleft(middleware)
|
self.named_response_middleware[_rn].appendleft(middleware)
|
||||||
|
return middleware
|
||||||
|
|
||||||
def _apply_exception_handler(self, handler: FutureException):
|
def _apply_exception_handler(self, handler: FutureException):
|
||||||
"""Decorate a function to be registered as a handler for exceptions
|
"""Decorate a function to be registered as a handler for exceptions
|
||||||
|
@ -257,12 +258,12 @@ class Sanic(BaseSanic):
|
||||||
self.error_handler.add(e, handler.handler)
|
self.error_handler.add(e, handler.handler)
|
||||||
else:
|
else:
|
||||||
self.error_handler.add(exception, handler.handler)
|
self.error_handler.add(exception, handler.handler)
|
||||||
return handler
|
return handler.handler
|
||||||
|
|
||||||
def _apply_listener(self, listener: FutureListener):
|
def _apply_listener(self, listener: FutureListener):
|
||||||
return self.register_listener(listener.listener, listener.event)
|
return self.register_listener(listener.listener, listener.event)
|
||||||
|
|
||||||
def _apply_route(self, route: FutureRoute) -> Route:
|
def _apply_route(self, route: FutureRoute) -> List[Route]:
|
||||||
params = route._asdict()
|
params = route._asdict()
|
||||||
websocket = params.pop("websocket", False)
|
websocket = params.pop("websocket", False)
|
||||||
subprotocols = params.pop("subprotocols", None)
|
subprotocols = params.pop("subprotocols", None)
|
||||||
|
@ -277,7 +278,15 @@ class Sanic(BaseSanic):
|
||||||
websocket_handler.__name__ = route.handler.__name__ # type: ignore
|
websocket_handler.__name__ = route.handler.__name__ # type: ignore
|
||||||
websocket_handler.is_websocket = True # type: ignore
|
websocket_handler.is_websocket = True # type: ignore
|
||||||
params["handler"] = websocket_handler
|
params["handler"] = websocket_handler
|
||||||
return self.router.add(**params)
|
|
||||||
|
routes = self.router.add(**params)
|
||||||
|
if isinstance(routes, Route):
|
||||||
|
routes = [routes]
|
||||||
|
for r in routes:
|
||||||
|
r.ctx.websocket = websocket
|
||||||
|
r.ctx.static = params.get("static", False)
|
||||||
|
|
||||||
|
return routes
|
||||||
|
|
||||||
def _apply_static(self, static: FutureStatic) -> Route:
|
def _apply_static(self, static: FutureStatic) -> Route:
|
||||||
return self._register_static(static)
|
return self._register_static(static)
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import Optional
|
from typing import Dict, List, Optional
|
||||||
|
|
||||||
|
from sanic_routing.route import Route # type: ignore
|
||||||
|
|
||||||
from sanic.base import BaseSanic
|
from sanic.base import BaseSanic
|
||||||
from sanic.blueprint_group import BlueprintGroup
|
from sanic.blueprint_group import BlueprintGroup
|
||||||
|
from sanic.handlers import ListenerType, MiddlewareType, RouteHandler
|
||||||
from sanic.models.futures import FutureRoute, FutureStatic
|
from sanic.models.futures import FutureRoute, FutureStatic
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,12 +40,12 @@ class Blueprint(BaseSanic):
|
||||||
self.url_prefix = url_prefix
|
self.url_prefix = url_prefix
|
||||||
self.host = host
|
self.host = host
|
||||||
|
|
||||||
self.routes = []
|
self.routes: List[Route] = []
|
||||||
self.websocket_routes = []
|
self.websocket_routes: List[Route] = []
|
||||||
self.exceptions = []
|
self.exceptions: List[RouteHandler] = []
|
||||||
self.listeners = defaultdict(list)
|
self.listeners: Dict[str, List[ListenerType]] = {}
|
||||||
self.middlewares = []
|
self.middlewares: List[MiddlewareType] = []
|
||||||
self.statics = []
|
self.statics: List[RouteHandler] = []
|
||||||
self.version = version
|
self.version = version
|
||||||
self.strict_slashes = strict_slashes
|
self.strict_slashes = strict_slashes
|
||||||
|
|
||||||
|
@ -107,6 +110,9 @@ class Blueprint(BaseSanic):
|
||||||
url_prefix = options.get("url_prefix", self.url_prefix)
|
url_prefix = options.get("url_prefix", self.url_prefix)
|
||||||
|
|
||||||
routes = []
|
routes = []
|
||||||
|
middleware = []
|
||||||
|
exception_handlers = []
|
||||||
|
listeners = defaultdict(list)
|
||||||
|
|
||||||
# Routes
|
# Routes
|
||||||
for future in self._future_routes:
|
for future in self._future_routes:
|
||||||
|
@ -159,12 +165,22 @@ class Blueprint(BaseSanic):
|
||||||
# Middleware
|
# Middleware
|
||||||
if route_names:
|
if route_names:
|
||||||
for future in self._future_middleware:
|
for future in self._future_middleware:
|
||||||
app._apply_middleware(future, route_names)
|
middleware.append(app._apply_middleware(future, route_names))
|
||||||
|
|
||||||
# Exceptions
|
# Exceptions
|
||||||
for future in self._future_exceptions:
|
for future in self._future_exceptions:
|
||||||
app._apply_exception_handler(future)
|
exception_handlers.append(app._apply_exception_handler(future))
|
||||||
|
|
||||||
# Event listeners
|
# Event listeners
|
||||||
for listener in self._future_listeners:
|
for listener in self._future_listeners:
|
||||||
app._apply_listener(listener)
|
listeners[listener.event].append(app._apply_listener(listener))
|
||||||
|
|
||||||
|
self.routes = [route for route in routes if isinstance(route, Route)]
|
||||||
|
|
||||||
|
# Deprecate these in 21.6
|
||||||
|
self.websocket_routes = [
|
||||||
|
route for route in self.routes if route.ctx.websocket
|
||||||
|
]
|
||||||
|
self.middlewares = middleware
|
||||||
|
self.exceptions = exception_handlers
|
||||||
|
self.listeners = dict(listeners)
|
||||||
|
|
|
@ -113,8 +113,8 @@ class Config(dict):
|
||||||
config.update_config("${some}/py/file")
|
config.update_config("${some}/py/file")
|
||||||
|
|
||||||
Yes you can put environment variable here, but they must be provided
|
Yes you can put environment variable here, but they must be provided
|
||||||
in format: ``${some_env_var}``, and mark that ``$some_env_var`` is treated
|
in format: ``${some_env_var}``, and mark that ``$some_env_var`` is
|
||||||
as plain string.
|
treated as plain string.
|
||||||
|
|
||||||
You can upload app config by providing dict holding settings.
|
You can upload app config by providing dict holding settings.
|
||||||
|
|
||||||
|
@ -134,7 +134,8 @@ class Config(dict):
|
||||||
|
|
||||||
config.update_config(C)
|
config.update_config(C)
|
||||||
|
|
||||||
`See user guide <https://sanicframework.org/guide/deployment/configuration.html>`__
|
`See user guide
|
||||||
|
<https://sanicframework.org/guide/deployment/configuration.html>`__
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isinstance(config, (bytes, str, Path)):
|
if isinstance(config, (bytes, str, Path)):
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
"""
|
"""
|
||||||
Sanic `provides a pattern <https://sanicframework.org/guide/best-practices/exceptions.html#using-sanic-exceptions>`_
|
Sanic `provides a pattern
|
||||||
|
<https://sanicframework.org/guide/best-practices/exceptions.html#using-sanic-exceptions>`_
|
||||||
for providing a response when an exception occurs. However, if you do no handle
|
for providing a response when an exception occurs. However, if you do no handle
|
||||||
an exception, it will provide a fallback. There are three fallback types:
|
an exception, it will provide a fallback. There are three fallback types:
|
||||||
|
|
||||||
|
@ -72,9 +73,9 @@ class BaseRenderer:
|
||||||
status_text = STATUS_CODES.get(self.status, b"Error Occurred").decode()
|
status_text = STATUS_CODES.get(self.status, b"Error Occurred").decode()
|
||||||
return f"{self.status} — {status_text}"
|
return f"{self.status} — {status_text}"
|
||||||
|
|
||||||
def render(self) -> str:
|
def render(self) -> HTTPResponse:
|
||||||
"""
|
"""
|
||||||
Outputs the exception as a ``str`` for response.
|
Outputs the exception as a :class:`HTTPResponse`.
|
||||||
|
|
||||||
:return: The formatted exception
|
:return: The formatted exception
|
||||||
:rtype: str
|
:rtype: str
|
||||||
|
@ -86,14 +87,14 @@ class BaseRenderer:
|
||||||
)
|
)
|
||||||
return output()
|
return output()
|
||||||
|
|
||||||
def minimal(self) -> str: # noqa
|
def minimal(self) -> HTTPResponse: # noqa
|
||||||
"""
|
"""
|
||||||
Provide a formatted message that is meant to not show any sensitive
|
Provide a formatted message that is meant to not show any sensitive
|
||||||
data or details.
|
data or details.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def full(self) -> str: # noqa
|
def full(self) -> HTTPResponse: # noqa
|
||||||
"""
|
"""
|
||||||
Provide a formatted message that has all details and is mean to be used
|
Provide a formatted message that has all details and is mean to be used
|
||||||
primarily for debugging and non-production environments.
|
primarily for debugging and non-production environments.
|
||||||
|
@ -145,7 +146,7 @@ class HTMLRenderer(BaseRenderer):
|
||||||
"{body}"
|
"{body}"
|
||||||
)
|
)
|
||||||
|
|
||||||
def full(self):
|
def full(self) -> HTTPResponse:
|
||||||
return html(
|
return html(
|
||||||
self.OUTPUT_HTML.format(
|
self.OUTPUT_HTML.format(
|
||||||
title=self.title,
|
title=self.title,
|
||||||
|
@ -156,7 +157,7 @@ class HTMLRenderer(BaseRenderer):
|
||||||
status=self.status,
|
status=self.status,
|
||||||
)
|
)
|
||||||
|
|
||||||
def minimal(self):
|
def minimal(self) -> HTTPResponse:
|
||||||
return html(
|
return html(
|
||||||
self.OUTPUT_HTML.format(
|
self.OUTPUT_HTML.format(
|
||||||
title=self.title,
|
title=self.title,
|
||||||
|
@ -217,7 +218,7 @@ class TextRenderer(BaseRenderer):
|
||||||
OUTPUT_TEXT = "{title}\n{bar}\n{text}\n\n{body}"
|
OUTPUT_TEXT = "{title}\n{bar}\n{text}\n\n{body}"
|
||||||
SPACER = " "
|
SPACER = " "
|
||||||
|
|
||||||
def full(self):
|
def full(self) -> HTTPResponse:
|
||||||
return text(
|
return text(
|
||||||
self.OUTPUT_TEXT.format(
|
self.OUTPUT_TEXT.format(
|
||||||
title=self.title,
|
title=self.title,
|
||||||
|
@ -228,7 +229,7 @@ class TextRenderer(BaseRenderer):
|
||||||
status=self.status,
|
status=self.status,
|
||||||
)
|
)
|
||||||
|
|
||||||
def minimal(self):
|
def minimal(self) -> HTTPResponse:
|
||||||
return text(
|
return text(
|
||||||
self.OUTPUT_TEXT.format(
|
self.OUTPUT_TEXT.format(
|
||||||
title=self.title,
|
title=self.title,
|
||||||
|
@ -277,11 +278,11 @@ class JSONRenderer(BaseRenderer):
|
||||||
Render an exception as JSON.
|
Render an exception as JSON.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def full(self):
|
def full(self) -> HTTPResponse:
|
||||||
output = self._generate_output(full=True)
|
output = self._generate_output(full=True)
|
||||||
return json(output, status=self.status, dumps=dumps)
|
return json(output, status=self.status, dumps=dumps)
|
||||||
|
|
||||||
def minimal(self):
|
def minimal(self) -> HTTPResponse:
|
||||||
output = self._generate_output(full=False)
|
output = self._generate_output(full=False)
|
||||||
return json(output, status=self.status, dumps=dumps)
|
return json(output, status=self.status, dumps=dumps)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from typing import Any, Callable, Coroutine, List, Optional, Set, Union
|
from typing import Any, Callable, Coroutine, List, Optional, Union
|
||||||
|
|
||||||
from sanic.models.futures import FutureListener
|
from sanic.models.futures import FutureListener
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ class RouteMixin:
|
||||||
self._future_routes: Set[FutureRoute] = set()
|
self._future_routes: Set[FutureRoute] = set()
|
||||||
self._future_statics: Set[FutureStatic] = set()
|
self._future_statics: Set[FutureStatic] = set()
|
||||||
self.name = ""
|
self.name = ""
|
||||||
self.strict_slashes = False
|
self.strict_slashes: Optional[bool] = False
|
||||||
|
|
||||||
def _apply_route(self, route: FutureRoute) -> Route:
|
def _apply_route(self, route: FutureRoute) -> Route:
|
||||||
raise NotImplementedError # noqa
|
raise NotImplementedError # noqa
|
||||||
|
@ -41,7 +41,7 @@ class RouteMixin:
|
||||||
def route(
|
def route(
|
||||||
self,
|
self,
|
||||||
uri: str,
|
uri: str,
|
||||||
methods: Iterable[str] = frozenset({"GET"}),
|
methods: Optional[Iterable[str]] = None,
|
||||||
host: Optional[str] = None,
|
host: Optional[str] = None,
|
||||||
strict_slashes: Optional[bool] = None,
|
strict_slashes: Optional[bool] = None,
|
||||||
stream: bool = False,
|
stream: bool = False,
|
||||||
|
|
|
@ -21,7 +21,6 @@ if TYPE_CHECKING:
|
||||||
import email.utils
|
import email.utils
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from asyncio.transports import Transport
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from http.cookies import SimpleCookie
|
from http.cookies import SimpleCookie
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
@ -39,6 +38,7 @@ from sanic.headers import (
|
||||||
parse_xforwarded,
|
parse_xforwarded,
|
||||||
)
|
)
|
||||||
from sanic.log import error_logger, logger
|
from sanic.log import error_logger, logger
|
||||||
|
from sanic.models.protocol_types import TransportProtocol
|
||||||
from sanic.response import BaseHTTPResponse, HTTPResponse
|
from sanic.response import BaseHTTPResponse, HTTPResponse
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ class Request:
|
||||||
headers: Header,
|
headers: Header,
|
||||||
version: str,
|
version: str,
|
||||||
method: str,
|
method: str,
|
||||||
transport: Transport,
|
transport: TransportProtocol,
|
||||||
app: Sanic,
|
app: Sanic,
|
||||||
):
|
):
|
||||||
self.raw_url = url_bytes
|
self.raw_url = url_bytes
|
||||||
|
@ -148,7 +148,7 @@ class Request:
|
||||||
self.uri_template: Optional[str] = None
|
self.uri_template: Optional[str] = None
|
||||||
self.request_middleware_started = False
|
self.request_middleware_started = False
|
||||||
self._cookies: Optional[Dict[str, str]] = None
|
self._cookies: Optional[Dict[str, str]] = None
|
||||||
self._match_info = {}
|
self._match_info: Dict[str, Any] = {}
|
||||||
self.stream: Optional[Http] = None
|
self.stream: Optional[Http] = None
|
||||||
self.endpoint: Optional[str] = None
|
self.endpoint: Optional[str] = None
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ class Router(BaseRouter):
|
||||||
@lru_cache(maxsize=ROUTER_CACHE_SIZE)
|
@lru_cache(maxsize=ROUTER_CACHE_SIZE)
|
||||||
def _get(
|
def _get(
|
||||||
self, path, method, host
|
self, path, method, host
|
||||||
) -> Tuple[RouteHandler, Dict[str, Any], str, str, bool,]:
|
) -> Tuple[RouteHandler, Dict[str, Any], str, str, bool]:
|
||||||
try:
|
try:
|
||||||
route, handler, params = self.resolve(
|
route, handler, params = self.resolve(
|
||||||
path=path,
|
path=path,
|
||||||
|
|
|
@ -40,6 +40,7 @@ from sanic.config import Config
|
||||||
from sanic.exceptions import RequestTimeout, ServiceUnavailable
|
from sanic.exceptions import RequestTimeout, ServiceUnavailable
|
||||||
from sanic.http import Http, Stage
|
from sanic.http import Http, Stage
|
||||||
from sanic.log import logger
|
from sanic.log import logger
|
||||||
|
from sanic.models.protocol_types import TransportProtocol
|
||||||
from sanic.request import Request
|
from sanic.request import Request
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ class ConnInfo:
|
||||||
"ssl",
|
"ssl",
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, transport: Transport, unix=None):
|
def __init__(self, transport: TransportProtocol, unix=None):
|
||||||
self.ssl: bool = bool(transport.get_extra_info("sslcontext"))
|
self.ssl: bool = bool(transport.get_extra_info("sslcontext"))
|
||||||
self.server = self.client = ""
|
self.server = self.client = ""
|
||||||
self.server_port = self.client_port = 0
|
self.server_port = self.client_port = 0
|
||||||
|
|
Loading…
Reference in New Issue
Block a user