Coverage for /pythoncovmergedfiles/medio/medio/src/aiohttp/aiohttp/client_middlewares.py: 41%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

22 statements  

1"""Client middleware support.""" 

2 

3from collections.abc import Awaitable, Callable 

4from functools import lru_cache 

5 

6from .client_reqrep import ClientRequest, ClientResponse 

7 

8__all__ = ("ClientMiddlewareType", "ClientHandlerType", "build_client_middlewares") 

9 

10# Type alias for client request handlers - functions that process requests and return responses 

11ClientHandlerType = Callable[[ClientRequest], Awaitable[ClientResponse]] 

12 

13# Type for client middleware - similar to server but uses ClientRequest/ClientResponse 

14ClientMiddlewareType = Callable[ 

15 [ClientRequest, ClientHandlerType], Awaitable[ClientResponse] 

16] 

17 

18 

19def build_client_middlewares( 

20 handler: ClientHandlerType, 

21 middlewares: tuple[ClientMiddlewareType, ...], 

22) -> ClientHandlerType: 

23 """ 

24 Apply middlewares to request handler. 

25 

26 The middlewares are applied in reverse order, so the first middleware 

27 in the list wraps all subsequent middlewares and the handler. 

28 

29 This implementation avoids using partial/update_wrapper to minimize overhead. 

30 """ 

31 # Optimize for single middleware case 

32 if len(middlewares) == 1: 

33 middleware = middlewares[0] 

34 

35 async def single_middleware_handler(req: ClientRequest) -> ClientResponse: 

36 return await middleware(req, handler) 

37 

38 return single_middleware_handler 

39 

40 # Build the chain for multiple middlewares 

41 current_handler = handler 

42 

43 for middleware in reversed(middlewares): 

44 # Create a new closure that captures the current state 

45 def make_wrapper( 

46 mw: ClientMiddlewareType, next_h: ClientHandlerType 

47 ) -> ClientHandlerType: 

48 async def wrapped(req: ClientRequest) -> ClientResponse: 

49 return await mw(req, next_h) 

50 

51 return wrapped 

52 

53 current_handler = make_wrapper(middleware, current_handler) 

54 

55 return current_handler 

56 

57 

58_cached_build_client_middlewares = lru_cache(maxsize=64)(build_client_middlewares)