Skip to content

Commit

Permalink
Ascola/add handler type aliases (#5847)
Browse files Browse the repository at this point in the history
* Add handler type alias
  • Loading branch information
AustinScola committed Jul 4, 2021
1 parent d55728d commit 1b45c73
Show file tree
Hide file tree
Showing 12 changed files with 56 additions and 49 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
@@ -1,6 +1,15 @@
import json
import os
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 @@ -14,6 +23,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 @@ -37,5 +48,6 @@
"BaseCookie[str]",
]

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

PathLike = Union[str, "os.PathLike[str]"]
5 changes: 3 additions & 2 deletions aiohttp/web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@


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 = Callable[[Request, _Handler], Awaitable[StreamResponse]]
_Middleware = Callable[[Request, Handler], Awaitable[StreamResponse]]
_Middlewares = FrozenList[_Middleware]
_MiddlewaresHandlers = Sequence[_Middleware]
_Subapps = List["Application"]
Expand Down
8 changes: 4 additions & 4 deletions aiohttp/web_middlewares.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import warnings
from typing import TYPE_CHECKING, Awaitable, Callable, Tuple, Type, TypeVar

from .typedefs import Handler
from .web_exceptions import HTTPMove, HTTPPermanentRedirect
from .web_request import Request
from .web_response import StreamResponse
Expand Down Expand Up @@ -41,8 +42,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 @@ -85,7 +85,7 @@ def normalize_path_middleware(
correct_configuration = not (append_slash and remove_slash)
assert correct_configuration, "Cannot both remove and append slash"

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 @@ -119,7 +119,7 @@ async def impl(request: Request, handler: _Handler) -> StreamResponse:


def _fix_request_current_app(app: "Application") -> _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 @@ -4,7 +4,6 @@
from typing import (
TYPE_CHECKING,
Any,
Awaitable,
Callable,
Dict,
Iterator,
Expand All @@ -18,7 +17,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 @@ -52,8 +51,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]


@dataclasses.dataclass(frozen=True, repr=False)
Expand Down
37 changes: 15 additions & 22 deletions aiohttp/web_urldispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from .abc import AbstractMatchInfo, AbstractRouter, AbstractView
from .helpers import DEBUG, iscoroutinefunction
from .http import HttpVersion11
from .typedefs import PathLike
from .typedefs import Handler, PathLike
from .web_exceptions import (
HTTPException,
HTTPExpectationFailed,
Expand Down Expand Up @@ -81,7 +81,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 @@ -156,7 +155,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 @@ -193,7 +192,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 @@ -226,7 +225,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 @@ -321,7 +320,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 @@ -606,7 +605,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 @@ -863,7 +862,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 @@ -1073,7 +1072,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 @@ -1115,15 +1114,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 @@ -1132,7 +1129,7 @@ def add_options(
def add_get(
self,
path: str,
handler: _WebHandler,
handler: Handler,
*,
name: Optional[str] = None,
allow_head: bool = True,
Expand All @@ -1147,29 +1144,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
7 changes: 2 additions & 5 deletions examples/web_rewrite_headers_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@
"""
Example for rewriting response headers by middleware.
"""
from typing import Awaitable, Callable

from aiohttp import web

_WebHandler = Callable[[web.Request], Awaitable[web.StreamResponse]]
from aiohttp.typedefs import Handler


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


async def middleware(request: web.Request, handler: _WebHandler) -> web.StreamResponse:
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 @@ -7,6 +7,7 @@

from aiohttp import log, web
from aiohttp.test_utils import make_mocked_coro
from aiohttp.typedefs import Handler


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

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 @@ -17,6 +17,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 @@ -1213,7 +1214,7 @@ async def handler(request):
with pytest.warns(DeprecationWarning, match="Middleware decorator is deprecated"):

@web.middleware
async def middleware(request, handler):
async def middleware(request, handler: Handler):
order.append((1, request.app["name"]))
resp = await handler(request)
assert 200 == resp.status
Expand Down Expand Up @@ -1353,7 +1354,7 @@ async def test_subapp_middleware_context(
values = []

def show_app_context(appname):
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 @@ -10,6 +10,7 @@
import aiohttp
from aiohttp import web
from aiohttp.abc import AbstractAccessLogger, AbstractAsyncAccessLogger
from aiohttp.typedefs import Handler
from aiohttp.web_log import AccessLogger
from aiohttp.web_response import Response

Expand Down Expand Up @@ -232,7 +233,7 @@ async def test_contextvars_logger(aiohttp_server: Any, aiohttp_client: Any):
async def handler(request):
return web.Response()

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

Expand Down

0 comments on commit 1b45c73

Please sign in to comment.