def test_gets_named_operation(): doc = parse( "query TestQ { field } mutation TestM { field } subscription TestS { field }" ) assert get_operation_ast(doc, "TestQ") == doc.definitions[0] assert get_operation_ast(doc, "TestM") == doc.definitions[1] assert get_operation_ast(doc, "TestS") == doc.definitions[2]
def execute_graphql_request(self, request): ''' THIS IS IMPLEMENTED IN A SUB-OPTIMAL MANNER. DO NOT... A.) Judge Me. B.) Use unless you accept that the performance here probably is miserable. ''' subqueries = self.parse_body(request) results = [] for subquery in subqueries: query, variables, operation_name, _id = self.get_graphql_params(subquery) if not query: raise HttpError(HttpResponseBadRequest('Must provide query string.')) source = Source(query, name='GraphQL request') try: document_ast = parse(source) validation_errors = validate(self.schema, document_ast) if validation_errors: # TODO: Do not return here. We should handle this per subquery. return ExecutionResult( errors=validation_errors, invalid=True, ) except Exception as e: return ExecutionResult(errors=[e], invalid=True) if request.method.lower() == 'get': operation_ast = get_operation_ast(document_ast, operation_name) if operation_ast and operation_ast.operation != 'query': raise HttpError(HttpResponseNotAllowed( ['POST'], 'Can only perform a {} operation from a POST request.'.format(operation_ast.operation) )) try: result = self.execute( document_ast, root_value=self.get_root_value(request), variable_values=variables, operation_name=operation_name, context_value=self.get_context(request) ) # TODO: This is really optimistic. # We may have status, we may have errors, etc... # payload should be set according to graphql spec, not # simply "IT WORKED Spec". results.append({ "id": _id, "payload": { "data": result.data, } }) except Exception as e: return ExecutionResult(errors=[e], invalid=True) return results
def execute_graphql_request(self, request, data, query, variables, operation_name, show_graphiql=False): if os.getenv('DEBUG_ESCAPE_GRAPHQL', False) == 'True': return self.escaped_execute_graphql_request( request, data, query, variables, operation_name, show_graphiql) if not query: if show_graphiql: return None raise HttpError( HttpResponseBadRequest('Must provide query string.')) source = Source(query, name='GraphQL request') try: document_ast = parse(source) validation_errors = validate(self.schema, document_ast) if validation_errors: return ExecutionResult( errors=validation_errors, invalid=True, ) except Exception as e: return ExecutionResult(errors=[e], invalid=True) if request.method.lower() == 'get': operation_ast = get_operation_ast(document_ast, operation_name) if operation_ast and operation_ast.operation != 'query': if show_graphiql: return None raise HttpError( HttpResponseNotAllowed( ['POST'], 'Can only perform a {} operation from a POST request.'. format(operation_ast.operation))) try: return self.execute( document_ast, root_value=self.get_root_value(request), variable_values=variables, operation_name=operation_name, context_value=self.get_context(request), middleware=self.get_middleware(request), executor=self.executor, ) except Exception as e: return ExecutionResult(errors=[e], invalid=True)
def get_operation_ast(self, request): data = self.parse_body(request) query = request.GET.get("query") or data.get("query") if not query: return None source = Source(query, name="GraphQL request") document_ast = parse(source) operation_ast = get_operation_ast(document_ast, None) return operation_ast
def execute(self, *args, **kwargs): operation_ast = get_operation_ast(args[0]) if operation_ast and operation_ast.operation == "subscription": result = subscribe(self.schema, *args, **kwargs) if isinstance(result, Observable): a = [] result.subscribe(lambda x: a.append(x)) if len(a) > 0: result = a[-1] return result return execute(self.schema, *args, **kwargs)
async def execute_graphql_request(self, request, data, query, variables, operation_name, show_graphiql=False): if not query: if show_graphiql: return None raise HttpError( SanicException('Must provide query string.', status_code=400)) try: source = Source(query, name='GraphQL request') ast = parse(source) validation_errors = validate(self.schema, ast) if validation_errors: return ExecutionResult( errors=validation_errors, invalid=True, ) except Exception as e: return ExecutionResult(errors=[e], invalid=True) if request.method.lower() == 'get': operation_ast = get_operation_ast(ast, operation_name) if operation_ast and operation_ast.operation != 'query': if show_graphiql: return None raise HttpError( SanicException( 'Can only perform a {} operation from a POST request.'. format(operation_ast.operation), status_code=405, )) try: return await self.execute(ast, root_value=self.get_root_value(request), variable_values=variables or {}, operation_name=operation_name, context_value=self.get_context(request), middleware=self.get_middleware(request), executor=self.get_executor(request)) except Exception as e: return ExecutionResult(errors=[e], invalid=True)
def execute_graphql_request(self, data, query, variables, operation_name, show_graphiql=False): if not query: if show_graphiql: return None raise HttpError(BadRequest('Must provide query string.')) try: source = Source(query, name='GraphQL request') ast = parse(source) validation_errors = validate(self.schema, ast) if validation_errors: return ExecutionResult( errors=validation_errors, invalid=True, ) except Exception as e: return ExecutionResult(errors=[e], invalid=True) if request.method.lower() == 'get': operation_ast = get_operation_ast(ast, operation_name) if operation_ast and operation_ast.operation != 'query': if show_graphiql: return None raise HttpError( MethodNotAllowed( ['POST'], 'Can only perform a {} operation from a POST request.'. format(operation_ast.operation))) try: return self.execute(ast, root_value=self.get_root_value(request), variable_values=variables or {}, operation_name=operation_name, context_value=self.get_context(request), executor=self.executor) except Exception as e: return ExecutionResult(errors=[e], invalid=True)
def execute_graphql_request(self, request, data, query, variables, operation_name, show_graphiql=False): if not query: if show_graphiql: return None raise HttpError(HttpResponseBadRequest('Must provide query string.')) source = Source(query, name='GraphQL request') try: document_ast = parse(source) validation_errors = validate(self.schema, document_ast) if validation_errors: return ExecutionResult( errors=validation_errors, invalid=True, ) except Exception as e: return ExecutionResult(errors=[e], invalid=True) if request.method.lower() == 'get': operation_ast = get_operation_ast(document_ast, operation_name) if operation_ast and operation_ast.operation != 'query': if show_graphiql: return None raise HttpError(HttpResponseNotAllowed( ['POST'], 'Can only perform a {} operation from a POST request.'.format(operation_ast.operation) )) try: return self.execute( document_ast, root_value=self.get_root_value(request), variable_values=variables, operation_name=operation_name, context_value=self.get_context(request), middleware=self.get_middleware(request), executor=self.executor, ) except Exception as e: return ExecutionResult(errors=[e], invalid=True)
async def execute_graphql_request(schema, params, allow_only_query=False, **kwargs): if not params.query: raise HttpQueryError(400, 'Must provide query string.') try: source = Source(params.query, name='GraphQL request') ast = parse(source) validation_errors = validate(schema, ast) if validation_errors: return ExecutionResult( errors=validation_errors, invalid=True, ) except Exception as e: return ExecutionResult(errors=[e], invalid=True) if allow_only_query: operation_ast = get_operation_ast(ast, params.operation_name) if operation_ast and operation_ast.operation != 'query': raise HttpQueryError( 405, 'Can only perform a {} operation from a POST request.'.format( operation_ast.operation), headers={ 'Allow': ['POST'], }) try: return await execute(schema, ast, operation_name=params.operation_name, variable_values=params.variables, **kwargs) except Exception as e: return ExecutionResult(errors=[e], invalid=True)
def test_gets_named_operation(): doc = parse('query TestQ { field } mutation TestM { field } subscription TestS { field }') assert get_operation_ast(doc, 'TestQ') == doc.definitions[0] assert get_operation_ast(doc, 'TestM') == doc.definitions[1] assert get_operation_ast(doc, 'TestS') == doc.definitions[2]
def test_does_not_get_fragment(): doc = parse("fragment Foo on Type { field }") assert not get_operation_ast(doc) assert not get_operation_ast(doc, "Foo")
def test_does_not_get_missing_operation(): doc = parse('{ field } mutation Test { field }') assert not get_operation_ast(doc)
def _get_op_name(self, query): ast = get_operation_ast(graphql_parse(query)) return ast.name.value
def test_does_not_get_fragment_with_same_name_query(): doc = parse('fragment Foo on Type { field } query Foo { field }') assert get_operation_ast(doc) == doc.definitions[1] assert get_operation_ast(doc, 'Foo') == doc.definitions[1]
def test_gets_an_operation_from_a_document_with_named_mutation_operation(): doc = parse('mutation Test { field }') assert get_operation_ast(doc) == doc.definitions[0]
def test_does_not_get_fragment(): doc = parse('fragment Foo on Type { field }') assert not get_operation_ast(doc) assert not get_operation_ast(doc, 'Foo')
def test_gets_an_operation_from_a_simple_document(): doc = parse('{ field }') assert get_operation_ast(doc) == doc.definitions[0]
def test_gets_an_operation_from_a_document_with_named_subscription_operation(): doc = parse("subscription Test { field }") assert get_operation_ast(doc) == doc.definitions[0]
def test_does_not_get_misnamed_operation(): doc = parse('query TestQ { field } mutation TestM { field } subscription TestSub { field }') assert not get_operation_ast(doc, 'Unknown')
def test_does_not_get_ambiguous_named_operation(): doc = parse('query TestQ { field } mutation TestM { field } subscription TestSub { field }') assert not get_operation_ast(doc)