Skip to content

Commit

Permalink
Ascola/add handler type aliases (#5847) (#5861)
Browse files Browse the repository at this point in the history
* Ascola/add handler type aliases (#5847)

* Add handler type alias

(cherry picked from commit 1b45c73)

* Fix middleware example types

* Fix middleware example return type
  • Loading branch information
AustinScola committed Jul 7, 2021
1 parent 8ed655b commit 420cc71
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 53 deletions.
1 change: 1 addition & 0 deletions CHANGES/4686.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a request handler type alias ``aiohttp.typedefs.Handler``.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Anton Zhdan-Pushkin
Arseny Timoniq
Artem Yushkovskiy
Arthur Darcet
Austin Scola
Ben Bader
Ben Timby
Benedikt Reinartz
Expand Down
14 changes: 13 additions & 1 deletion aiohttp/typedefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@
import os
import pathlib
import sys
from typing import TYPE_CHECKING, Any, Callable, Iterable, Mapping, Tuple, Union
from typing import (
TYPE_CHECKING,
Any,
Awaitable,
Callable,
Iterable,
Mapping,
Tuple,
Union,
)

from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy, istr
from yarl import URL
Expand All @@ -26,6 +35,8 @@
_MultiDict = MultiDict[str]
_MultiDictProxy = MultiDictProxy[str]
from http.cookies import BaseCookie, Morsel

from .web import Request, StreamResponse
else:
_CIMultiDict = CIMultiDict
_CIMultiDictProxy = CIMultiDictProxy
Expand All @@ -49,6 +60,7 @@
"BaseCookie[str]",
]

Handler = Callable[["Request"], Awaitable["StreamResponse"]]

if sys.version_info >= (3, 6):
PathLike = Union[str, "os.PathLike[str]"]
Expand Down
8 changes: 4 additions & 4 deletions aiohttp/web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,13 @@


if TYPE_CHECKING: # pragma: no cover
from .typedefs import Handler

_AppSignal = Signal[Callable[["Application"], Awaitable[None]]]
_RespPrepareSignal = Signal[Callable[[Request, StreamResponse], Awaitable[None]]]
_Handler = Callable[[Request], Awaitable[StreamResponse]]
_Middleware = Union[
Callable[[Request, _Handler], Awaitable[StreamResponse]],
Callable[["Application", _Handler], Awaitable[_Handler]], # old-style
Callable[[Request, Handler], Awaitable[StreamResponse]],
Callable[["Application", Handler], Awaitable[Handler]], # old-style
]
_Middlewares = FrozenList[_Middleware]
_MiddlewaresHandlers = Optional[Sequence[Tuple[_Middleware, bool]]]
Expand All @@ -71,7 +72,6 @@
# No type checker mode, skip types
_AppSignal = Signal
_RespPrepareSignal = Signal
_Handler = Callable
_Middleware = Callable
_Middlewares = FrozenList
_MiddlewaresHandlers = Optional[Sequence]
Expand Down
8 changes: 4 additions & 4 deletions aiohttp/web_middlewares.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re
from typing import TYPE_CHECKING, Awaitable, Callable, Tuple, Type, TypeVar

from .typedefs import Handler
from .web_exceptions import HTTPPermanentRedirect, _HTTPMove
from .web_request import Request
from .web_response import StreamResponse
Expand Down Expand Up @@ -34,8 +35,7 @@ def middleware(f: _Func) -> _Func:
return f


_Handler = Callable[[Request], Awaitable[StreamResponse]]
_Middleware = Callable[[Request, _Handler], Awaitable[StreamResponse]]
_Middleware = Callable[[Request, Handler], Awaitable[StreamResponse]]


def normalize_path_middleware(
Expand Down Expand Up @@ -79,7 +79,7 @@ def normalize_path_middleware(
assert correct_configuration, "Cannot both remove and append slash"

@middleware
async def impl(request: Request, handler: _Handler) -> StreamResponse:
async def impl(request: Request, handler: Handler) -> StreamResponse:
if isinstance(request.match_info.route, SystemRoute):
paths_to_check = []
if "?" in request.raw_path:
Expand Down Expand Up @@ -114,7 +114,7 @@ async def impl(request: Request, handler: _Handler) -> StreamResponse:

def _fix_request_current_app(app: "Application") -> _Middleware:
@middleware
async def impl(request: Request, handler: _Handler) -> StreamResponse:
async def impl(request: Request, handler: Handler) -> StreamResponse:
with request.match_info.set_current_app(app):
return await handler(request)

Expand Down
6 changes: 2 additions & 4 deletions aiohttp/web_routedef.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from typing import (
TYPE_CHECKING,
Any,
Awaitable,
Callable,
Dict,
Iterator,
Expand All @@ -19,7 +18,7 @@

from . import hdrs
from .abc import AbstractView
from .typedefs import PathLike
from .typedefs import Handler, PathLike

if TYPE_CHECKING: # pragma: no cover
from .web_request import Request
Expand Down Expand Up @@ -53,8 +52,7 @@ def register(self, router: UrlDispatcher) -> List[AbstractRoute]:
pass # pragma: no cover


_SimpleHandler = Callable[[Request], Awaitable[StreamResponse]]
_HandlerType = Union[Type[AbstractView], _SimpleHandler]
_HandlerType = Union[Type[AbstractView], Handler]


@attr.s(auto_attribs=True, frozen=True, repr=False, slots=True)
Expand Down
37 changes: 15 additions & 22 deletions aiohttp/web_urldispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from .abc import AbstractMatchInfo, AbstractRouter, AbstractView
from .helpers import DEBUG
from .http import HttpVersion11
from .typedefs import Final, PathLike, TypedDict
from .typedefs import Final, Handler, PathLike, TypedDict
from .web_exceptions import (
HTTPException,
HTTPExpectationFailed,
Expand Down Expand Up @@ -84,7 +84,6 @@
PATH_SEP: Final[str] = re.escape("/")


_WebHandler = Callable[[Request], Awaitable[StreamResponse]]
_ExpectHandler = Callable[[Request], Awaitable[None]]
_Resolve = Tuple[Optional[AbstractMatchInfo], Set[str]]

Expand Down Expand Up @@ -159,7 +158,7 @@ class AbstractRoute(abc.ABC):
def __init__(
self,
method: str,
handler: Union[_WebHandler, Type[AbstractView]],
handler: Union[Handler, Type[AbstractView]],
*,
expect_handler: Optional[_ExpectHandler] = None,
resource: Optional[AbstractResource] = None,
Expand Down Expand Up @@ -211,7 +210,7 @@ def method(self) -> str:
return self._method

@property
def handler(self) -> _WebHandler:
def handler(self) -> Handler:
return self._handler

@property
Expand Down Expand Up @@ -244,7 +243,7 @@ def __init__(self, match_dict: Dict[str, str], route: AbstractRoute):
self._frozen = False

@property
def handler(self) -> _WebHandler:
def handler(self) -> Handler:
return self._route.handler

@property
Expand Down Expand Up @@ -339,7 +338,7 @@ def __init__(self, *, name: Optional[str] = None) -> None:
def add_route(
self,
method: str,
handler: Union[Type[AbstractView], _WebHandler],
handler: Union[Type[AbstractView], Handler],
*,
expect_handler: Optional[_ExpectHandler] = None,
) -> "ResourceRoute":
Expand Down Expand Up @@ -624,7 +623,7 @@ def get_info(self) -> _InfoDict:
"routes": self._routes,
}

def set_options_route(self, handler: _WebHandler) -> None:
def set_options_route(self, handler: Handler) -> None:
if "OPTIONS" in self._routes:
raise RuntimeError("OPTIONS route was set already")
self._routes["OPTIONS"] = ResourceRoute(
Expand Down Expand Up @@ -881,7 +880,7 @@ class ResourceRoute(AbstractRoute):
def __init__(
self,
method: str,
handler: Union[_WebHandler, Type[AbstractView]],
handler: Union[Handler, Type[AbstractView]],
resource: AbstractResource,
*,
expect_handler: Optional[_ExpectHandler] = None,
Expand Down Expand Up @@ -1091,7 +1090,7 @@ def add_route(
self,
method: str,
path: str,
handler: Union[_WebHandler, Type[AbstractView]],
handler: Union[Handler, Type[AbstractView]],
*,
name: Optional[str] = None,
expect_handler: Optional[_ExpectHandler] = None,
Expand Down Expand Up @@ -1133,15 +1132,13 @@ def add_static(
self.register_resource(resource)
return resource

def add_head(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute:
def add_head(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method HEAD
"""
return self.add_route(hdrs.METH_HEAD, path, handler, **kwargs)

def add_options(
self, path: str, handler: _WebHandler, **kwargs: Any
) -> AbstractRoute:
def add_options(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method OPTIONS
"""
Expand All @@ -1150,7 +1147,7 @@ def add_options(
def add_get(
self,
path: str,
handler: _WebHandler,
handler: Handler,
*,
name: Optional[str] = None,
allow_head: bool = True,
Expand All @@ -1165,29 +1162,25 @@ def add_get(
resource.add_route(hdrs.METH_HEAD, handler, **kwargs)
return resource.add_route(hdrs.METH_GET, handler, **kwargs)

def add_post(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute:
def add_post(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method POST
"""
return self.add_route(hdrs.METH_POST, path, handler, **kwargs)

def add_put(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute:
def add_put(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method PUT
"""
return self.add_route(hdrs.METH_PUT, path, handler, **kwargs)

def add_patch(
self, path: str, handler: _WebHandler, **kwargs: Any
) -> AbstractRoute:
def add_patch(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method PATCH
"""
return self.add_route(hdrs.METH_PATCH, path, handler, **kwargs)

def add_delete(
self, path: str, handler: _WebHandler, **kwargs: Any
) -> AbstractRoute:
def add_delete(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method DELETE
"""
Expand Down
4 changes: 2 additions & 2 deletions examples/web_rewrite_headers_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
"""
Example for rewriting response headers by middleware.
"""

from aiohttp import web
from aiohttp.typedefs import Handler


async def handler(request):
return web.Response(text="Everything is fine")


@web.middleware
async def middleware(request, handler):
async def middleware(request: web.Request, handler: Handler) -> web.StreamResponse:
try:
response = await handler(request)
except web.HTTPException as exc:
Expand Down
3 changes: 2 additions & 1 deletion tests/test_web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from aiohttp.abc import AbstractAccessLogger, AbstractRouter
from aiohttp.helpers import DEBUG, PY_36
from aiohttp.test_utils import make_mocked_coro
from aiohttp.typedefs import Handler


async def test_app_ctor() -> None:
Expand Down Expand Up @@ -261,7 +262,7 @@ def test_app_run_middlewares() -> None:
assert root._run_middlewares is False

@web.middleware
async def middleware(request, handler):
async def middleware(request, handler: Handler):
return await handler(request)

root = web.Application(middlewares=[middleware])
Expand Down
5 changes: 3 additions & 2 deletions tests/test_web_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from aiohttp import FormData, HttpVersion10, HttpVersion11, TraceConfig, multipart, web
from aiohttp.hdrs import CONTENT_LENGTH, CONTENT_TYPE, TRANSFER_ENCODING
from aiohttp.test_utils import make_mocked_coro
from aiohttp.typedefs import Handler

try:
import ssl
Expand Down Expand Up @@ -1273,7 +1274,7 @@ async def test_subapp_middlewares(aiohttp_client) -> None:
async def handler(request):
return web.Response(text="OK")

async def middleware_factory(app, handler):
async def middleware_factory(app, handler: Handler):
async def middleware(request):
order.append((1, app))
resp = await handler(request)
Expand Down Expand Up @@ -1412,7 +1413,7 @@ async def test_subapp_middleware_context(aiohttp_client, route, expected, middle

def show_app_context(appname):
@web.middleware
async def middleware(request, handler):
async def middleware(request, handler: Handler):
values.append("{}: {}".format(appname, request.app["my_value"]))
return await handler(request)

Expand Down
3 changes: 2 additions & 1 deletion tests/test_web_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from aiohttp import web
from aiohttp.abc import AbstractAccessLogger
from aiohttp.helpers import PY_37
from aiohttp.typedefs import Handler
from aiohttp.web_log import AccessLogger

try:
Expand Down Expand Up @@ -177,7 +178,7 @@ async def handler(request):
return web.Response()

@web.middleware
async def middleware(request, handler):
async def middleware(request, handler: Handler):
VAR.set("uuid")
return await handler(request)

Expand Down

0 comments on commit 420cc71

Please sign in to comment.