Coverage for nexios\middlewares\base.py: 94%
18 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-21 20:31 +0100
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-21 20:31 +0100
1from nexios.http import Request, Response
2import typing
3from typing_extensions import Annotated, Doc, Any
6class BaseMiddleware:
7 """
8 Base middleware class for handling request-response processing in Nexios.
10 This class provides a structure for middleware in the Nexios framework.
11 It allows child classes to intercept and modify HTTP requests before they
12 reach the main application logic and modify responses before they are returned
13 to the client.
15 Middleware classes inheriting from `BaseMiddleware` should implement:
17 - `process_request()`: To inspect, modify, or reject an incoming request.
18 - `process_response()`: To inspect or modify an outgoing response.
20 The user can decide when to call `next()` to proceed to the next middleware or handler.
21 """
23 def __init__(
24 self,
25 **kwargs: Annotated[
26 typing.Dict[typing.Any, typing.Any],
27 Doc("Additional keyword arguments for middleware configuration."),
28 ],
29 ) -> None:
30 """
31 Initializes the middleware with optional keyword arguments.
33 Middleware can accept configuration parameters via `kwargs`. These parameters
34 can be used to modify behavior when subclassing this base class.
36 Args:
37 **kwargs (dict): Arbitrary keyword arguments for middleware settings.
38 """
39 pass
41 async def __call__(
42 self,
43 request: Annotated[
44 Request,
45 Doc("The incoming HTTP request object representing the client request."),
46 ],
47 response: Annotated[
48 Response,
49 Doc("The HTTP response object that will be returned to the client."),
50 ],
51 call_next: Annotated[
52 typing.Callable[..., typing.Awaitable[Any]],
53 Doc("The next middleware function in the processing chain."),
54 ],
55 ) -> Any:
56 """
57 Handles the request-response cycle for the middleware.
59 This method does the following:
60 1. Calls `process_request()` to inspect or modify the request before passing it forward.
61 2. Allows the user to decide when to call `next_middleware()`.
62 3. Calls `process_response()` to modify the response after `next_middleware()` is called.
64 Args:
65 request (Request): The incoming HTTP request object.
66 next_middleware (Callable[..., Awaitable[Response]]): A function representing the next middleware.
68 Returns:
69 Response: The final HTTP response object.
70 """
71 self._call_next = False
73 async def wrapped_call_next() -> Any:
74 self._call_next = True
75 return await call_next() # type:ignore
77 await self.process_request(request, response, wrapped_call_next)
78 if self._call_next:
79 await self.process_response(request, response)
81 async def process_request(
82 self,
83 request: Annotated[
84 Request, Doc("The HTTP request object that needs to be processed.")
85 ],
86 response: Annotated[
87 Response,
88 Doc("The HTTP response object that will be returned to the client."),
89 ],
90 call_next: Annotated[
91 typing.Callable[..., typing.Awaitable[Response]],
92 Doc("The next middleware or handler to call."),
93 ],
94 ) -> Annotated[
95 Any,
96 Doc("The HTTP response object returned by the next middleware or handler."),
97 ]:
98 """
99 Hook for processing an HTTP request before passing it forward.
101 Override this method in subclasses to inspect, modify, or reject requests before
102 they reach the next middleware or the application logic. The user can decide when
103 to call `next()` to proceed.
105 Args:
106 request (Request): The incoming HTTP request object.
107 next (Callable[..., Awaitable[Response]]): The next middleware or handler to call.
109 Returns:
110 Response: The HTTP response object returned by the next middleware or handler.
111 """
112 return await call_next()
114 async def process_response(
115 self,
116 request: Annotated[
117 Request,
118 Doc(
119 "The original HTTP request object, available for context during response processing."
120 ),
121 ],
122 response: Annotated[
123 Response,
124 Doc(
125 "The HTTP response object that can be modified before sending to the client."
126 ),
127 ],
128 ) -> Annotated[
129 Any,
130 Doc("The modified HTTP response object to be returned to the client."),
131 ]:
132 """
133 Hook for processing an HTTP response before returning it to the client.
135 Override this method in subclasses to modify response headers, content, or status codes
136 before they are sent back to the client.
138 Args:
139 request (Request): The original HTTP request object.
140 response (Response): The outgoing HTTP response object.
142 Returns:
143 Response: The modified HTTP response object.
144 """
145 # Default behavior: Return the response as is
146 return response