8
8
from typing_extensions import Doc
9
9
10
10
from .conf import settings
11
- from .errors import ValidationError
12
11
from .logger import logger
12
+ from .meta import ArcStackRequestMeta
13
13
from .responses import InternalServerErrorResponse
14
- from .serializers import JsonSerializer
15
- from .signature import EndpointSignature
16
14
17
15
18
16
class ArcStackAPI :
19
- _param_middleware : Annotated [
17
+ _endpoint_middleware : Annotated [
20
18
list [Callable ],
21
19
Doc (
22
20
"""
23
21
Middleware that will be called to build the endpoint kwargs.
24
22
Should accept the following arguments:
25
23
- request: The request object.
26
- - signature: The signature of the endpoint.
27
- - callback_args: The arguments of the callback.
28
- - callback_kwargs: The keyword arguments of the callback.
29
- Should return a tuple of (kwargs, response).
30
- - kwargs: The keyword arguments to pass to the endpoint. Must be a
31
- dictionary. `None` can be returned if there is nothing to add.
32
- - response: The response to return. If the response is not None,
33
- the execution will be terminated because there is probably a
34
- validation error.
24
+ - meta: The ArcStackRequestMeta object.
25
+ Should either return a new ArcStackRequestMeta object or None.
35
26
"""
36
27
),
37
28
] = []
@@ -62,7 +53,7 @@ def __init__(self):
62
53
self .load_middleware ()
63
54
64
55
def load_middleware (self ):
65
- self ._param_middleware = []
56
+ self ._endpoint_middleware = []
66
57
self ._exception_middleware = []
67
58
handler = self ._get_response
68
59
for middleware_path in reversed (settings .API_MIDDLEWARE ):
@@ -85,73 +76,53 @@ def load_middleware(self):
85
76
f'Middleware factory { middleware_path } returned None.'
86
77
)
87
78
88
- if hasattr (mw_instance , 'process_params ' ):
89
- self ._param_middleware .insert (0 , mw_instance .process_params )
79
+ if hasattr (mw_instance , 'process_endpoint ' ):
80
+ self ._endpoint_middleware .insert (0 , mw_instance .process_endpoint )
90
81
if hasattr (mw_instance , 'process_exception' ):
91
82
self ._exception_middleware .append (mw_instance .process_exception )
92
-
93
83
self ._middleware_chain = handler
94
84
95
85
def __call__ (self , endpoint : Callable ):
96
- wrapper = self ._create_wrapper (endpoint )
97
- return wrapper
86
+ return self ._create_wrapper (endpoint )
98
87
99
88
def _create_wrapper (self , endpoint : Callable ):
100
89
@wraps (endpoint )
101
90
def wrapper (request , * args , ** kwargs ):
102
- request .endpoint = endpoint
103
- request .signature = EndpointSignature (endpoint )
91
+ request ._arcstack_meta = ArcStackRequestMeta (endpoint , args , kwargs )
104
92
105
93
try :
106
- response = self ._middleware_chain (request , * args , ** kwargs )
94
+ response = self ._middleware_chain (request )
107
95
except Exception as e :
108
96
response = self ._process_exception (e , request )
109
97
110
98
return response
111
99
112
100
return wrapper
113
101
114
- def _get_response (self , request , * args , ** kwargs ):
115
- if not hasattr (request , 'endpoint ' ):
102
+ def _get_response (self , request ):
103
+ if not hasattr (request , '_arcstack_meta ' ):
116
104
raise ImproperlyConfigured (
117
- 'The request object must have an `endpoint ` attribute. '
118
- 'To endpointize a view, use the `api ` decorator or '
105
+ 'The request object must have an `_arcstack_meta ` attribute. '
106
+ 'To endpointify a view, use the `api_endpoint ` decorator or '
119
107
'subclass `Endpoint`.'
120
108
)
121
109
122
- response , endpoint_args , endpoint_kwargs = self ._process_params (
123
- request , * args , ** kwargs
124
- )
125
-
126
- if response is None :
127
- response = request .endpoint (request , * endpoint_args , ** endpoint_kwargs )
128
-
129
- return response
110
+ endpoint = request ._arcstack_meta .endpoint
111
+ args = request ._arcstack_meta .args
112
+ kwargs = request ._arcstack_meta .kwargs
113
+ del request ._arcstack_meta
130
114
131
- def _process_params (self , request , * args , ** kwargs ):
132
- """Process the parameters of the request through the middleware."""
133
115
response = None
134
116
135
- validation_errors = []
136
- for middleware in self ._param_middleware :
137
- try :
138
- args , kwargs = middleware (args , kwargs )
139
- except ValidationError as e :
140
- validation_errors .append (e )
141
- except Exception as e :
142
- response = self ._process_exception (e , request )
117
+ for middleware in self ._endpoint_middleware :
118
+ response = middleware (request , endpoint , * args , ** kwargs )
119
+ if response is not None :
120
+ break
143
121
144
- if validation_errors :
145
- response = HttpResponse (
146
- content = JsonSerializer .serialize (
147
- {
148
- 'errors' : [str (e ) for e in validation_errors ],
149
- }
150
- ),
151
- status = 400 ,
152
- )
122
+ if response is None :
123
+ response = endpoint (request , * args , ** kwargs )
153
124
154
- return response , args , kwargs
125
+ return response
155
126
156
127
def _process_exception (
157
128
self , exception : Exception , request : HttpRequest
0 commit comments