@@ -71,7 +71,8 @@ def render_graphiql(self, **kwargs):
71
71
72
72
def dispatch_request (self ):
73
73
try :
74
- if request .method .lower () not in ('get' , 'post' ):
74
+ request_method = request .method .lower ()
75
+ if request_method not in ('get' , 'post' ):
75
76
raise HttpError (
76
77
405 ,
77
78
'GraphQL only supports GET and POST requests.' ,
@@ -95,7 +96,15 @@ def dispatch_request(self):
95
96
'Batch requests are not allowed.'
96
97
)
97
98
98
- responses = [self .get_response (request , entry , show_graphiql ) for entry in data ]
99
+ only_allow_query = request_method == 'get'
100
+
101
+ responses = [self .get_response (
102
+ self .execute ,
103
+ entry ,
104
+ show_graphiql ,
105
+ only_allow_query ,
106
+ ) for entry in data ]
107
+
99
108
response , status_codes = zip (* responses )
100
109
status_code = max (status_codes )
101
110
@@ -106,7 +115,7 @@ def dispatch_request(self):
106
115
result = self .json_encode (response , pretty )
107
116
108
117
if show_graphiql :
109
- query , variables , operation_name , id = self .get_graphql_params (request , data [0 ])
118
+ query , variables , operation_name , id = self .get_graphql_params (data [0 ])
110
119
return self .render_graphiql (
111
120
query = query ,
112
121
variables = variables ,
@@ -130,15 +139,23 @@ def dispatch_request(self):
130
139
content_type = 'application/json'
131
140
)
132
141
133
- def get_response (self , request , data , show_graphiql = False ):
134
- query , variables , operation_name , id = self .get_graphql_params (request , data )
135
- execution_result = self .execute_graphql_request (
136
- data ,
137
- query ,
138
- variables ,
139
- operation_name ,
140
- show_graphiql
141
- )
142
+ def get_response (self , execute , data , show_graphiql = False , only_allow_query = False ):
143
+ query , variables , operation_name , id = self .get_graphql_params (data )
144
+ try :
145
+ execution_result = self .execute_graphql_request (
146
+ self .schema ,
147
+ execute ,
148
+ data ,
149
+ query ,
150
+ variables ,
151
+ operation_name ,
152
+ only_allow_query ,
153
+ )
154
+ except HttpError :
155
+ if show_graphiql :
156
+ execution_result = None
157
+ else :
158
+ raise
142
159
return self .format_execution_result (execution_result , id )
143
160
144
161
def format_execution_result (self , execution_result , id ):
@@ -163,20 +180,11 @@ def format_execution_result(self, execution_result, id):
163
180
164
181
return response , status_code
165
182
166
- @staticmethod
167
- def json_encode (data , pretty = False ):
168
- if not pretty :
169
- return json .dumps (data , separators = (',' , ':' ))
170
-
171
- return json .dumps (
172
- data ,
173
- indent = 2 ,
174
- separators = (',' , ': ' )
175
- )
176
-
177
183
# noinspection PyBroadException
178
184
def parse_body (self , request ):
179
- content_type = self .get_content_type (request )
185
+ # We use mimetype here since we don't need the other
186
+ # information provided by content_type
187
+ content_type = request .mimetype
180
188
if content_type == 'application/graphql' :
181
189
return {'query' : request .data .decode ()}
182
190
@@ -197,19 +205,31 @@ def parse_body(self, request):
197
205
198
206
return {}
199
207
200
- def execute (self , * args , ** kwargs ):
201
- return execute (self .schema , * args , ** kwargs )
208
+ def execute (self , schema , * args , ** kwargs ):
209
+ root_value = self .get_root_value (request )
210
+ context_value = self .get_context (request )
211
+ middleware = self .get_middleware (request )
212
+ executor = self .get_executor (request )
213
+
214
+ return execute (
215
+ schema ,
216
+ * args ,
217
+ root_value = root_value ,
218
+ context_value = context_value ,
219
+ middleware = middleware ,
220
+ executor = executor ,
221
+ ** kwargs
222
+ )
202
223
203
- def execute_graphql_request (self , data , query , variables , operation_name , show_graphiql = False ):
224
+ @staticmethod
225
+ def execute_graphql_request (schema , execute , data , query , variables , operation_name , only_allow_query = False ):
204
226
if not query :
205
- if show_graphiql :
206
- return None
207
227
raise HttpError (400 , 'Must provide query string.' )
208
228
209
229
try :
210
230
source = Source (query , name = 'GraphQL request' )
211
231
ast = parse (source )
212
- validation_errors = validate (self . schema , ast )
232
+ validation_errors = validate (schema , ast )
213
233
if validation_errors :
214
234
return ExecutionResult (
215
235
errors = validation_errors ,
@@ -218,11 +238,9 @@ def execute_graphql_request(self, data, query, variables, operation_name, show_g
218
238
except Exception as e :
219
239
return ExecutionResult (errors = [e ], invalid = True )
220
240
221
- if request . method . lower () == 'get' :
241
+ if only_allow_query :
222
242
operation_ast = get_operation_ast (ast , operation_name )
223
243
if operation_ast and operation_ast .operation != 'query' :
224
- if show_graphiql :
225
- return None
226
244
raise HttpError (
227
245
405 ,
228
246
'Can only perform a {} operation from a POST request.' .format (operation_ast .operation ),
@@ -232,33 +250,40 @@ def execute_graphql_request(self, data, query, variables, operation_name, show_g
232
250
)
233
251
234
252
try :
235
- return self .execute (
253
+ return execute (
254
+ schema ,
236
255
ast ,
237
- root_value = self .get_root_value (request ),
238
- variable_values = variables or {},
239
256
operation_name = operation_name ,
240
- context_value = self .get_context (request ),
241
- middleware = self .get_middleware (request ),
242
- executor = self .get_executor (request )
257
+ variable_values = variables ,
243
258
)
244
259
except Exception as e :
245
260
return ExecutionResult (errors = [e ], invalid = True )
246
261
262
+ @staticmethod
263
+ def json_encode (data , pretty = False ):
264
+ if not pretty :
265
+ return json .dumps (data , separators = (',' , ':' ))
266
+
267
+ return json .dumps (
268
+ data ,
269
+ indent = 2 ,
270
+ separators = (',' , ': ' )
271
+ )
272
+
247
273
@classmethod
248
274
def can_display_graphiql (cls , data ):
249
- raw = 'raw' in request .args or 'raw' in data
250
- return not raw and cls .request_wants_html (request )
275
+ return 'raw' not in data and cls .request_wants_html ()
251
276
252
277
@classmethod
253
- def request_wants_html (cls , request ):
278
+ def request_wants_html (cls ):
254
279
best = request .accept_mimetypes \
255
280
.best_match (['application/json' , 'text/html' ])
256
281
return best == 'text/html' and \
257
282
request .accept_mimetypes [best ] > \
258
283
request .accept_mimetypes ['application/json' ]
259
284
260
285
@staticmethod
261
- def get_graphql_params (request , data ):
286
+ def get_graphql_params (data ):
262
287
query = data .get ('query' )
263
288
variables = data .get ('variables' )
264
289
id = data .get ('id' )
@@ -279,9 +304,3 @@ def format_error(error):
279
304
return format_graphql_error (error )
280
305
281
306
return {'message' : six .text_type (error )}
282
-
283
- @staticmethod
284
- def get_content_type (request ):
285
- # We use mimetype here since we don't need the other
286
- # information provided by content_type
287
- return request .mimetype
0 commit comments