88from aiohttp_deps .view import View
99
1010
11- def _function_handler (
12- original_route : Callable [..., Awaitable [web .StreamResponse ]],
13- ) -> Callable [[web .Request ], Awaitable [web .StreamResponse ]]:
14- original_handler = copy .copy (original_route )
15- graph = DependencyGraph (original_handler )
16-
17- async def custom_responder (request : web .Request ) -> web .StreamResponse :
18- async with graph .async_ctx (
11+ class InjectableFuncHandler :
12+ """
13+ Dependency injector for function handlers.
14+
15+ This class creates a dependency injection context on startup
16+ and then use it to server requests.
17+
18+
19+ The `__call__` method is used to serve requests.
20+
21+ Usage:
22+ new_handler = InjectableFuncHandler(old_handler)
23+ response = await new_handler(request)
24+ """
25+
26+ def __init__ (
27+ self ,
28+ original_route : Callable [..., Awaitable [web .StreamResponse ]],
29+ ) -> None :
30+ self .original_handler = copy .copy (original_route )
31+ self .graph = DependencyGraph (self .original_handler )
32+
33+ async def __call__ (self , request : web .Request ) -> web .StreamResponse :
34+ """
35+ Serve a request.
36+
37+ This function creates async context and resolves all kwargs,
38+ required to serve current request.
39+
40+ :param request: current request.
41+ :return: response.
42+ """
43+ async with self .graph .async_ctx (
1944 {
2045 web .Request : request ,
2146 web .Application : request .app ,
2247 },
23- ) as gra :
24- return await original_handler (** (await gra .resolve_kwargs ()))
25-
26- return custom_responder
48+ ) as resolver :
49+ return await self .original_handler (** (await resolver .resolve_kwargs ()))
2750
2851
29- def _view_handler (
30- original_route : Type [View ],
31- ) -> Callable [[web .Request ], Awaitable [web .StreamResponse ]]:
32- allowed_methods = {
33- method .lower ()
34- for method in hdrs .METH_ALL
35- if hasattr (original_route , method .lower ()) # noqa: WPS421
36- }
37- graph_map = {
38- method : DependencyGraph (getattr (original_route , method ))
39- for method in allowed_methods
40- }
41-
42- async def custom_responder (request : web .Request ) -> web .StreamResponse :
43- return await original_route (request , graph_map )
52+ class InjectableViewHandler :
53+ """
54+ Dependency injector for views.
4455
45- return custom_responder
56+ This class is different from function injector,
57+ because it calculates graphs for all implemented methods
58+ of the view.
4659
60+ Usage:
61+ new_handler = InjectableViewHandler(MyView)
62+ response = await new_handler(request)
63+ """
4764
48- def _route_generator (
49- original_route : Callable [..., Awaitable [web .StreamResponse ]],
50- ) -> Callable [[web .Request ], Awaitable [web .StreamResponse ]]:
51- if inspect .isclass (original_route ):
52- if issubclass (original_route , View ):
53- return _view_handler (original_route )
54- return original_route
55- return _function_handler (original_route )
65+ def __init__ (
66+ self ,
67+ original_route : Type [View ],
68+ ) -> None :
69+ self .original_handler = copy .copy (original_route )
70+ allowed_methods = {
71+ method .lower ()
72+ for method in hdrs .METH_ALL
73+ if hasattr (original_route , method .lower ()) # noqa: WPS421
74+ }
75+ self .graph_map = {
76+ method : DependencyGraph (getattr (original_route , method ))
77+ for method in allowed_methods
78+ }
79+
80+ async def __call__ (self , request : web .Request ) -> web .StreamResponse :
81+ """
82+ Serve a request.
83+
84+ This function creates async context and resolves all kwargs,
85+ required to serve current request.
86+
87+ :param request: current request.
88+ :return: response.
89+ """
90+ return await self .original_handler (request , self .graph_map )
5691
5792
5893async def init (app : web .Application ) -> None :
@@ -73,4 +108,8 @@ async def init(app: web.Application) -> None:
73108 :param app: current application.
74109 """
75110 for route in app .router .routes ():
76- route ._handler = _route_generator (route ._handler ) # noqa: WPS437
111+ if inspect .isclass (route ._handler ):
112+ if issubclass (route ._handler , View ):
113+ route ._handler = InjectableViewHandler (route ._handler )
114+ continue
115+ route ._handler = InjectableFuncHandler (route ._handler )
0 commit comments