def test_gevent_executor(): @run_in_greenlet def resolver(context, *_): gevent.sleep(0.001) return 'hey' @run_in_greenlet def resolver_2(context, *_): gevent.sleep(0.003) return 'hey2' def resolver_3(contest, *_): return 'hey3' Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), 'b': GraphQLField(GraphQLString, resolver=resolver_2), 'c': GraphQLField(GraphQLString, resolver=resolver_3) }) doc = '{ a b c }' executor = Executor([GeventExecutionMiddleware()]) result = executor.execute(GraphQLSchema(Type), doc) assert not result.errors assert result.data == {'a': 'hey', 'b': 'hey2', 'c': 'hey3'}
def test_executor_defer_failure(): class Data(object): def promise(self): return fail(Exception('Something bad happened! Sucks :(')) def notPromise(self): return 'i should work' DataType = GraphQLObjectType( 'DataType', { 'promise': GraphQLField(GraphQLNonNull(GraphQLString)), 'notPromise': GraphQLField(GraphQLString), }) doc = ''' query Example { promise notPromise } ''' schema = GraphQLSchema(query=DataType) executor = Executor() result = executor.execute(schema, doc, Data(), operation_name='Example') assert result.called result = result.result assert result.data is None formatted_errors = list(map(format_error, result.errors)) assert formatted_errors == [{ 'locations': [dict(line=3, column=9)], 'message': "Something bad happened! Sucks :(" }]
def test_gevent_executor_with_error(): doc = 'query Example { a, b }' @run_in_greenlet def resolver(context, *_): gevent.sleep(0.001) return 'hey' @run_in_greenlet def resolver_2(context, *_): gevent.sleep(0.003) raise Exception('resolver_2 failed!') Type = GraphQLObjectType( 'Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), 'b': GraphQLField(GraphQLString, resolver=resolver_2) }) executor = Executor([GeventExecutionMiddleware()]) result = executor.execute(GraphQLSchema(Type), doc) formatted_errors = list(map(format_error, result.errors)) assert formatted_errors == [{ 'locations': [{ 'line': 1, 'column': 20 }], 'message': 'resolver_2 failed!' }] assert result.data == {'a': 'hey', 'b': None}
def test_synchronous_executor_doesnt_support_defers(): class Data(object): def promise(self): return succeed('i shouldn\'nt work') def notPromise(self): return 'i should work' DataType = GraphQLObjectType('DataType', { 'promise': GraphQLField(GraphQLNonNull(GraphQLString)), 'notPromise': GraphQLField(GraphQLString), }) doc = ''' query Example { promise notPromise } ''' schema = GraphQLSchema(query=DataType) executor = Executor([SynchronousExecutionMiddleware()]) result = executor.execute(schema, doc, Data(), operation_name='Example') assert not isinstance(result, Deferred) assert result.data is None formatted_errors = list(map(format_error, result.errors)) assert formatted_errors == [{'locations': [dict(line=3, column=9)], 'message': 'You cannot return a Deferred from a resolver ' 'when using SynchronousExecutionMiddleware'}]
def test_executor_defer_failure(): class Data(object): def promise(self): return fail(Exception('Something bad happened! Sucks :(')) def notPromise(self): return 'i should work' DataType = GraphQLObjectType('DataType', { 'promise': GraphQLField(GraphQLNonNull(GraphQLString)), 'notPromise': GraphQLField(GraphQLString), }) doc = ''' query Example { promise notPromise } ''' schema = GraphQLSchema(query=DataType) executor = Executor() result = executor.execute(schema, doc, Data(), operation_name='Example') assert result.called result = result.result assert result.data is None formatted_errors = list(map(format_error, result.errors)) assert formatted_errors == [{'locations': [dict(line=3, column=9)], 'message': "Something bad happened! Sucks :("}]
def test_gevent_executor(): @run_in_greenlet def resolver(context, *_): gevent.sleep(0.001) return 'hey' @run_in_greenlet def resolver_2(context, *_): gevent.sleep(0.003) return 'hey2' def resolver_3(contest, *_): return 'hey3' Type = GraphQLObjectType( 'Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), 'b': GraphQLField(GraphQLString, resolver=resolver_2), 'c': GraphQLField(GraphQLString, resolver=resolver_3) }) doc = '{ a b c }' executor = Executor([GeventExecutionMiddleware()]) result = executor.execute(GraphQLSchema(Type), doc) assert not result.errors assert result.data == {'a': 'hey', 'b': 'hey2', 'c': 'hey3'}
def test_executor_can_enforce_strict_ordering(): Type = GraphQLObjectType('Type', lambda: { 'a': GraphQLField(GraphQLString, resolver=lambda *_: succeed('Apple')), 'b': GraphQLField(GraphQLString, resolver=lambda *_: succeed('Banana')), 'c': GraphQLField(GraphQLString, resolver=lambda *_: succeed('Cherry')), 'deep': GraphQLField(Type, resolver=lambda *_: succeed({})), }) schema = GraphQLSchema(query=Type) executor = Executor(map_type=OrderedDict) query = '{ a b c aa: c cc: c bb: b aaz: a bbz: b deep { b a c deeper: deep { c a b } } ' \ 'ccz: c zzz: c aaa: a }' def handle_results(result): assert not result.errors data = result.data assert isinstance(data, OrderedDict) assert list(data.keys()) == ['a', 'b', 'c', 'aa', 'cc', 'bb', 'aaz', 'bbz', 'deep', 'ccz', 'zzz', 'aaa'] deep = data['deep'] assert isinstance(deep, OrderedDict) assert list(deep.keys()) == ['b', 'a', 'c', 'deeper'] deeper = deep['deeper'] assert isinstance(deeper, OrderedDict) assert list(deeper.keys()) == ['c', 'a', 'b'] raise_callback_results(executor.execute(schema, query), handle_results) raise_callback_results(executor.execute(schema, query, execute_serially=True), handle_results)
def test_executor_can_enforce_strict_ordering(): Type = GraphQLObjectType('Type', lambda: { 'a': GraphQLField(GraphQLString, resolver=lambda *_: 'Apple'), 'b': GraphQLField(GraphQLString, resolver=lambda *_: 'Banana'), 'c': GraphQLField(GraphQLString, resolver=lambda *_: 'Cherry'), 'deep': GraphQLField(Type, resolver=lambda *_: {}), }) schema = GraphQLSchema(query=Type) executor = Executor(execution_middlewares=[SynchronousExecutionMiddleware], map_type=OrderedDict) query = '{ a b c aa: c cc: c bb: b aaz: a bbz: b deep { b a c deeper: deep { c a b } } ' \ 'ccz: c zzz: c aaa: a }' def check_result(result): assert not result.errors data = result.data assert isinstance(data, OrderedDict) assert list(data.keys()) == ['a', 'b', 'c', 'aa', 'cc', 'bb', 'aaz', 'bbz', 'deep', 'ccz', 'zzz', 'aaa'] deep = data['deep'] assert isinstance(deep, OrderedDict) assert list(deep.keys()) == ['b', 'a', 'c', 'deeper'] deeper = deep['deeper'] assert isinstance(deeper, OrderedDict) assert list(deeper.keys()) == ['c', 'a', 'b'] check_result(executor.execute(schema, query)) check_result(executor.execute(schema, query, execute_serially=True))
def test_synchronous_executor_doesnt_support_defers(): class Data(object): def promise(self): return succeed('i shouldn\'nt work') def notPromise(self): return 'i should work' DataType = GraphQLObjectType( 'DataType', { 'promise': GraphQLField(GraphQLNonNull(GraphQLString)), 'notPromise': GraphQLField(GraphQLString), }) doc = ''' query Example { promise notPromise } ''' schema = GraphQLSchema(query=DataType) executor = Executor([SynchronousExecutionMiddleware()]) result = executor.execute(schema, doc, Data(), operation_name='Example') assert not isinstance(result, Deferred) assert result.data is None formatted_errors = list(map(format_error, result.errors)) assert formatted_errors == [{ 'locations': [dict(line=3, column=9)], 'message': 'You cannot return a Deferred from a resolver ' 'when using SynchronousExecutionMiddleware' }]
def test_executor_detects_strict_ordering(): executor = Executor() assert not executor.enforce_strict_ordering assert executor.map_type is dict executor = Executor(map_type=OrderedDict) assert executor.enforce_strict_ordering assert executor.map_type is OrderedDict
def update_schema(schema): print('[~] Generating Schema Documents... ') executor = Executor(execution_middlewares=[SynchronousExecutionMiddleware()], map_type=OrderedDict) result = executor.execute(schema, introspection_query) if result.errors: print('[X] Error inspecting schema: ', result.errors) else: with open(os.path.join(os.path.dirname(__file__), '..', 'schema.json'), 'w') as fp: json.dump({'data': result.data}, fp, indent=2) print('[~] Wrote schema.json') with open(os.path.join(os.path.dirname(__file__), '..', 'schema.graphql'), 'w') as fp: fp.write(print_schema(schema)) print('[~] Wrote schema.graphql') print('[!] Done.')
def test_synchronous_executor_will_synchronously_resolve(): class Data(object): def promise(self): return 'I should work' DataType = GraphQLObjectType('DataType', { 'promise': GraphQLField(GraphQLString), }) doc = ''' query Example { promise } ''' schema = GraphQLSchema(query=DataType) executor = Executor([SynchronousExecutionMiddleware()]) result = executor.execute(schema, doc, Data(), operation_name='Example') assert not isinstance(result, Deferred) assert result.data == {"promise": 'I should work'} assert not result.errors
def test_get_and_set_default_executor(): e1 = get_default_executor() e2 = get_default_executor() assert e1 is e2 new_executor = Executor() set_default_executor(new_executor) assert get_default_executor() is new_executor set_default_executor(None) assert get_default_executor() is not e1 assert get_default_executor() is not new_executor
def test_gevent_executor(): doc = 'query Example { a, b }' @run_in_greenlet def resolver(context, *_): gevent.sleep(0.001) return 'hey' @run_in_greenlet def resolver_2(context, *_): gevent.sleep(0.003) return 'hey2' Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), 'b': GraphQLField(GraphQLString, resolver=resolver_2) }) executor = Executor(GraphQLSchema(Type), [GeventExecutionMiddleware()]) result = executor.execute(doc) assert not result.errors assert result.data == {'a': 'hey', 'b': 'hey2'}
def test_gevent_executor_with_error(): doc = 'query Example { a, b }' @run_in_greenlet def resolver(context, *_): gevent.sleep(0.001) return 'hey' @run_in_greenlet def resolver_2(context, *_): gevent.sleep(0.003) raise Exception('resolver_2 failed!') Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), 'b': GraphQLField(GraphQLString, resolver=resolver_2) }) executor = Executor([GeventExecutionMiddleware()]) result = executor.execute(GraphQLSchema(Type), doc) formatted_errors = list(map(format_error, result.errors)) assert formatted_errors == [{'locations': [{'line': 1, 'column': 20}], 'message': 'resolver_2 failed!'}] assert result.data == {'a': 'hey', 'b': None}
def test_gevent_executor(): doc = 'query Example { a, b }' @run_in_greenlet def resolver(context, *_): gevent.sleep(0.001) return 'hey' @run_in_greenlet def resolver_2(context, *_): gevent.sleep(0.003) return 'hey2' Type = GraphQLObjectType( 'Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), 'b': GraphQLField(GraphQLString, resolver=resolver_2) }) executor = Executor(GraphQLSchema(Type), [GeventExecutionMiddleware()]) result = executor.execute(doc) assert not result.errors assert result.data == {'a': 'hey', 'b': 'hey2'}
async def test_asyncio_py35_executor(): doc = 'query Example { a, b }' async def resolver(context, *_): await asyncio.sleep(0.001) return 'hey' async def resolver_2(context, *_): await asyncio.sleep(0.003) return 'hey2' Type = GraphQLObjectType( 'Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), 'b': GraphQLField(GraphQLString, resolver=resolver_2) }) executor = Executor(GraphQLSchema(Type), [AsyncioExecutionMiddleware()]) result = await executor.execute(doc) assert not result.errors assert result.data == {'a': 'hey', 'b': 'hey2'}
from collections import namedtuple from graphql.core.error import format_error from graphql.core.execution import Executor, execute from graphql.core.language.parser import parse from graphql.core.pyutils.defer import fail, succeed from graphql.core.type import (GraphQLField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLSchema) Data = namedtuple('Data', 'test') ast = parse('{ nest { test } }') executor = Executor() def check(test_data, expected): def run_check(self): test_type = self.type data = Data(test=test_data) DataType = GraphQLObjectType( name='DataType', fields=lambda: { 'test': GraphQLField(test_type), 'nest': GraphQLField(DataType, resolver=lambda *_: data) }) schema = GraphQLSchema(query=DataType) response = executor.execute(schema, ast, data) assert response.called response = response.result
from collections import OrderedDict from graphql.core.error import format_error from graphql.core.execution import Executor, execute from graphql.core.language.parser import parse from graphql.core.pyutils.defer import fail, succeed from graphql.core.type import (GraphQLField, GraphQLNonNull, GraphQLObjectType, GraphQLSchema, GraphQLString) sync_error = Exception('sync') non_null_sync_error = Exception('nonNullSync') promise_error = Exception('promise') non_null_promise_error = Exception('nonNullPromise') executor = Executor(map_type=OrderedDict) class ThrowingData(object): def sync(self): raise sync_error def nonNullSync(self): raise non_null_sync_error def promise(self): return fail(promise_error) def nonNullPromise(self): return fail(non_null_promise_error) def nest(self):
def test_executes_arbitary_code(): class Data(object): a = 'Apple' b = 'Banana' c = 'Cookie' d = 'Donut' e = 'Egg' @property def f(self): return succeed('Fish') def pic(self, size=50): return succeed('Pic of size: {}'.format(size)) def deep(self): return DeepData() def promise(self): return succeed(Data()) class DeepData(object): a = 'Already Been Done' b = 'Boring' c = ['Contrived', None, succeed('Confusing')] def deeper(self): return [Data(), None, succeed(Data())] doc = ''' query Example($size: Int) { a, b, x: c ...c f ...on DataType { pic(size: $size) promise { a } } deep { a b c deeper { a b } } } fragment c on DataType { d e } ''' expected = { 'a': 'Apple', 'b': 'Banana', 'x': 'Cookie', 'd': 'Donut', 'e': 'Egg', 'f': 'Fish', 'pic': 'Pic of size: 100', 'promise': { 'a': 'Apple' }, 'deep': { 'a': 'Already Been Done', 'b': 'Boring', 'c': ['Contrived', None, 'Confusing'], 'deeper': [{ 'a': 'Apple', 'b': 'Banana' }, None, { 'a': 'Apple', 'b': 'Banana' }] } } DataType = GraphQLObjectType( 'DataType', lambda: { 'a': GraphQLField(GraphQLString), 'b': GraphQLField(GraphQLString), 'c': GraphQLField(GraphQLString), 'd': GraphQLField(GraphQLString), 'e': GraphQLField(GraphQLString), 'f': GraphQLField(GraphQLString), 'pic': GraphQLField( args={'size': GraphQLArgument(GraphQLInt)}, type=GraphQLString, resolver=lambda obj, args, *_: obj.pic(args['size']), ), 'deep': GraphQLField(DeepDataType), 'promise': GraphQLField(DataType), }) DeepDataType = GraphQLObjectType( 'DeepDataType', { 'a': GraphQLField(GraphQLString), 'b': GraphQLField(GraphQLString), 'c': GraphQLField(GraphQLList(GraphQLString)), 'deeper': GraphQLField(GraphQLList(DataType)), }) schema = GraphQLSchema(query=DataType) executor = Executor() def handle_result(result): assert not result.errors assert result.data == expected raise_callback_results( executor.execute(schema, doc, Data(), {'size': 100}, 'Example'), handle_result) raise_callback_results( executor.execute(schema, doc, Data(), {'size': 100}, 'Example', execute_serially=True), handle_result)
def test_executes_arbitary_code(): class Data(object): a = 'Apple' b = 'Banana' c = 'Cookie' d = 'Donut' e = 'Egg' @property def f(self): return succeed('Fish') def pic(self, size=50): return succeed('Pic of size: {}'.format(size)) def deep(self): return DeepData() def promise(self): return succeed(Data()) class DeepData(object): a = 'Already Been Done' b = 'Boring' c = ['Contrived', None, succeed('Confusing')] def deeper(self): return [Data(), None, succeed(Data())] doc = ''' query Example($size: Int) { a, b, x: c ...c f ...on DataType { pic(size: $size) promise { a } } deep { a b c deeper { a b } } } fragment c on DataType { d e } ''' expected = { 'a': 'Apple', 'b': 'Banana', 'x': 'Cookie', 'd': 'Donut', 'e': 'Egg', 'f': 'Fish', 'pic': 'Pic of size: 100', 'promise': {'a': 'Apple'}, 'deep': { 'a': 'Already Been Done', 'b': 'Boring', 'c': ['Contrived', None, 'Confusing'], 'deeper': [ {'a': 'Apple', 'b': 'Banana'}, None, {'a': 'Apple', 'b': 'Banana'}]} } DataType = GraphQLObjectType('DataType', lambda: { 'a': GraphQLField(GraphQLString), 'b': GraphQLField(GraphQLString), 'c': GraphQLField(GraphQLString), 'd': GraphQLField(GraphQLString), 'e': GraphQLField(GraphQLString), 'f': GraphQLField(GraphQLString), 'pic': GraphQLField( args={'size': GraphQLArgument(GraphQLInt)}, type=GraphQLString, resolver=lambda obj, args, *_: obj.pic(args['size']), ), 'deep': GraphQLField(DeepDataType), 'promise': GraphQLField(DataType), }) DeepDataType = GraphQLObjectType('DeepDataType', { 'a': GraphQLField(GraphQLString), 'b': GraphQLField(GraphQLString), 'c': GraphQLField(GraphQLList(GraphQLString)), 'deeper': GraphQLField(GraphQLList(DataType)), }) schema = GraphQLSchema(query=DataType) executor = Executor() def handle_result(result): assert not result.errors assert result.data == expected raise_callback_results(executor.execute(schema, doc, Data(), {'size': 100}, 'Example'), handle_result) raise_callback_results(executor.execute(schema, doc, Data(), {'size': 100}, 'Example', execute_serially=True), handle_result)
query=GraphQLObjectType( name='Type', fields={ 'sync': GraphQLField(GraphQLString), 'syncError': GraphQLField(GraphQLString), 'syncReturnError': GraphQLField(GraphQLString), 'syncReturnErrorList': GraphQLField(GraphQLList(GraphQLString)), 'async': GraphQLField(GraphQLString), 'asyncReject': GraphQLField(GraphQLString), 'asyncEmptyReject': GraphQLField(GraphQLString), 'asyncReturnError': GraphQLField(GraphQLString), } ) ) executor = Executor(map_type=OrderedDict) def handle_results(result): assert result.data == { 'async': 'async', 'asyncEmptyReject': None, 'asyncReject': None, 'asyncReturnError': None, 'sync': 'sync', 'syncError': None, 'syncReturnError': None, 'syncReturnErrorList': ['sync0', None, 'sync2', None] } assert list(map(format_error, result.errors)) == [ {'locations': [{'line': 4, 'column': 9}], 'message': 'Error getting syncError'}, {'locations': [{'line': 5, 'column': 9}], 'message': 'Error getting syncReturnError'},
from flask_graphql import GraphQL from schema import schema, orm app = Flask(__name__, static_url_path='/static/') app.debug = True from graphql.core.execution import Executor, SynchronousExecutionMiddleware class PonyMiddleware(object): @staticmethod def run_resolve_fn(resolver, original_resolver): with orm.db_session: return SynchronousExecutionMiddleware.run_resolve_fn( resolver, original_resolver) @staticmethod def execution_result(executor): with orm.db_session: return SynchronousExecutionMiddleware.execution_result(executor) executor = Executor([PonyMiddleware()]) graphql = GraphQL(app, schema=schema, executor=executor) CORS(app) with orm.db_session: app.run()
def test_synchronous_error_nulls_out_error_subtrees(): doc = ''' { sync syncError syncReturnError syncReturnErrorList async asyncReject asyncEmptyReject asyncReturnError } ''' class Data: def sync(self): return 'sync' def syncError(self): raise Exception('Error getting syncError') def syncReturnError(self): return Exception("Error getting syncReturnError") def syncReturnErrorList(self): return [ 'sync0', Exception('Error getting syncReturnErrorList1'), 'sync2', Exception('Error getting syncReturnErrorList3') ] def async (self): return succeed('async') def asyncReject(self): return fail(Exception('Error getting asyncReject')) def asyncEmptyReject(self): return fail() def asyncReturnError(self): return succeed(Exception('Error getting asyncReturnError')) schema = GraphQLSchema(query=GraphQLObjectType( name='Type', fields={ 'sync': GraphQLField(GraphQLString), 'syncError': GraphQLField(GraphQLString), 'syncReturnError': GraphQLField(GraphQLString), 'syncReturnErrorList': GraphQLField(GraphQLList(GraphQLString)), 'async': GraphQLField(GraphQLString), 'asyncReject': GraphQLField(GraphQLString), 'asyncEmptyReject': GraphQLField(GraphQLString), 'asyncReturnError': GraphQLField(GraphQLString), })) executor = Executor(map_type=OrderedDict) def handle_results(result): assert result.data == { 'async': 'async', 'asyncEmptyReject': None, 'asyncReject': None, 'asyncReturnError': None, 'sync': 'sync', 'syncError': None, 'syncReturnError': None, 'syncReturnErrorList': ['sync0', None, 'sync2', None] } assert list(map(format_error, result.errors)) == [{ 'locations': [{ 'line': 4, 'column': 9 }], 'message': 'Error getting syncError' }, { 'locations': [{ 'line': 5, 'column': 9 }], 'message': 'Error getting syncReturnError' }, { 'locations': [{ 'line': 6, 'column': 9 }], 'message': 'Error getting syncReturnErrorList1' }, { 'locations': [{ 'line': 6, 'column': 9 }], 'message': 'Error getting syncReturnErrorList3' }, { 'locations': [{ 'line': 8, 'column': 9 }], 'message': 'Error getting asyncReject' }, { 'locations': [{ 'line': 9, 'column': 9 }], 'message': 'An unknown error occurred.' }, { 'locations': [{ 'line': 10, 'column': 9 }], 'message': 'Error getting asyncReturnError' }] raise_callback_results(executor.execute(schema, doc, Data()), handle_results)