Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ascola/add handler type aliases #5847

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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]"]
6 changes: 4 additions & 2 deletions aiohttp/web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@
if TYPE_CHECKING: # pragma: no cover
_AppSignal = Signal[Callable[["Application"], Awaitable[None]]]
_RespPrepareSignal = Signal[Callable[[Request, StreamResponse], Awaitable[None]]]
_Handler = Callable[[Request], Awaitable[StreamResponse]]
_Middleware = Callable[[Request, _Handler], Awaitable[StreamResponse]]

from .typedefs import Handler
Dreamsorcerer marked this conversation as resolved.
Show resolved Hide resolved

_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