2525
2626from graphql .error import GraphQLError
2727from graphql .execution import ExecutionResult , execute
28- from graphql .language import OperationType , parse
28+ from graphql .language import OperationType , parse , DocumentNode
2929from graphql .pyutils import AwaitableOrValue
3030from graphql .type import GraphQLSchema , validate_schema
3131from graphql .utilities import get_operation_ast
6161
6262@dataclass
6363class GraphQLParams :
64- query : str
64+ query : str | DocumentNode
6565 variables : Optional [Dict [str , Any ]] = None
6666 operation_name : Optional [str ] = None
6767
@@ -158,16 +158,13 @@ def run_http_query(
158158 all_params : List [GraphQLParams ] = [
159159 get_graphql_params (entry , extra_data ) for entry in data
160160 ]
161- # print("GET ROOT VALUE 0", type(request_method), all_params)
162- # print(dict(schema=schema, all_params=all_params, catch_exc=catch_exc, allow_only=allow_only_query, run_sync=run_sync))
163161
164162 results : List [Optional [AwaitableOrValue [ExecutionResult ]]] = [
165163 get_response (
166164 schema , params , catch_exc , allow_only_query , run_sync , ** execute_options
167165 )
168166 for params in all_params
169167 ]
170- # print("GET ROOT VALUE 1")
171168
172169 return GraphQLResponse (results = results , params = all_params )
173170
@@ -314,6 +311,55 @@ def assume_not_awaitable(_value: Any) -> bool:
314311 return False
315312
316313
314+ def parse_document (
315+ schema : GraphQLSchema ,
316+ params : GraphQLParams ,
317+ allow_only_query : bool = False ,
318+ validation_rules : Optional [Collection [Type [ASTValidationRule ]]] = None ,
319+ max_errors : Optional [int ] = None ,
320+ ) -> Optional [Dict ]:
321+ if not params .query :
322+ raise HttpQueryError (400 , "Must provide query string." )
323+
324+ if not isinstance (params .query , str ) and not isinstance (params .query , DocumentNode ):
325+ raise HttpQueryError (400 , "Unexpected query type." )
326+
327+ if isinstance (params .query , DocumentNode ):
328+ return params .query
329+ schema_validation_errors = validate_schema (schema )
330+ if schema_validation_errors :
331+ return ExecutionResult (data = None , errors = schema_validation_errors )
332+
333+ try :
334+ document = parse (params .query )
335+ except GraphQLError as e :
336+ return ExecutionResult (data = None , errors = [e ])
337+ except Exception as e :
338+ e = GraphQLError (str (e ), original_error = e )
339+ return ExecutionResult (data = None , errors = [e ])
340+
341+ if allow_only_query :
342+ operation_ast = get_operation_ast (document , params .operation_name )
343+ if operation_ast :
344+ operation = operation_ast .operation .value
345+ if operation != OperationType .QUERY .value :
346+ raise HttpQueryError (
347+ 405 ,
348+ f"Can only perform a { operation } operation" " from a POST request." ,
349+ headers = {"Allow" : "POST" },
350+ )
351+
352+ validation_errors = validate (
353+ schema ,
354+ document ,
355+ rules = validation_rules ,
356+ max_errors = max_errors ,
357+ )
358+ if validation_errors :
359+ return ExecutionResult (data = None , errors = validation_errors )
360+ return document
361+
362+
317363def get_response (
318364 schema : GraphQLSchema ,
319365 params : GraphQLParams ,
@@ -334,44 +380,18 @@ def get_response(
334380 belong to an exception class specified by catch_exc.
335381 """
336382 # noinspection PyBroadException
383+ document = parse_document (
384+ schema ,
385+ params ,
386+ allow_only_query ,
387+ validation_rules ,
388+ max_errors ,
389+ )
390+ if isinstance (document , ExecutionResult ):
391+ return document
392+ if not isinstance (document , DocumentNode ):
393+ raise Exception ("GraphQL query could not be parsed properly." )
337394 try :
338- if not params .query :
339- raise HttpQueryError (400 , "Must provide query string." )
340-
341- # Sanity check query
342- if not isinstance (params .query , str ):
343- raise HttpQueryError (400 , "Unexpected query type." )
344-
345- schema_validation_errors = validate_schema (schema )
346- if schema_validation_errors :
347- return ExecutionResult (data = None , errors = schema_validation_errors )
348-
349- try :
350- document = parse (params .query )
351- except GraphQLError as e :
352- return ExecutionResult (data = None , errors = [e ])
353- except Exception as e :
354- e = GraphQLError (str (e ), original_error = e )
355- return ExecutionResult (data = None , errors = [e ])
356-
357- if allow_only_query :
358- operation_ast = get_operation_ast (document , params .operation_name )
359- if operation_ast :
360- operation = operation_ast .operation .value
361- if operation != OperationType .QUERY .value :
362- raise HttpQueryError (
363- 405 ,
364- f"Can only perform a { operation } operation"
365- " from a POST request." ,
366- headers = {"Allow" : "POST" },
367- )
368-
369- validation_errors = validate (
370- schema , document , rules = validation_rules , max_errors = max_errors
371- )
372- if validation_errors :
373- return ExecutionResult (data = None , errors = validation_errors )
374-
375395 execution_result = execute (
376396 schema ,
377397 document ,
0 commit comments