def test_batch_endpoint(sync_graph): endpoint = BatchGraphQLEndpoint(Engine(SyncExecutor()), sync_graph) assert endpoint.dispatch([]) == [] result = endpoint.dispatch({'query': '{answer}'}) assert result == {'data': {'answer': '42'}} batch_result = endpoint.dispatch([ { 'query': '{answer}' }, { 'query': '{__typename}' }, ]) assert batch_result == [ { 'data': { 'answer': '42' } }, { 'data': { '__typename': 'Query' } }, ]
def test_with_pass_context(graph_name, sample_count): def root_fields1(fields): return [1 for _ in fields] @pass_context def root_fields2(ctx, fields): return [2 for _ in fields] graph = Graph([ Root([ Field('a', None, root_fields1), Field('b', None, root_fields2), ]), ]) graph = apply(graph, [GraphMetrics(graph_name)]) assert sample_count('Root', 'a') is None assert sample_count('Root', 'b') is None result = Engine(SyncExecutor()).execute( graph, q.Node([ q.Field('a'), q.Field('b'), ])) check_result(result, { 'a': 1, 'b': 2, }) assert sample_count('Root', 'a') == 1.0 assert sample_count('Root', 'b') == 1.0
def testSubQuery(self): thread_pool = ThreadPoolExecutor(2) e = Engine(ThreadsExecutor(thread_pool)) def query_a(fields, ids): data = {1: {'f': 2}} return [[data[i][f] for f in fields] for i in ids] r = graph.Edge(None, [ graph.Edge('a', [ graph.Field('f', query_a), ]), ]) # ---------------------------------------------- @define('[[:f]]', _name='inc_f') def inc_f(obj): return obj['f'] + 1 r1 = graph.Edge(None, [ graph.Edge('a1', subquery_fields(r, 'a', { 'f1': inc_f(S.this), })), graph.Link('la1', None, 'a1', lambda: [1], True), ]) self.assertEqual( e.execute(r1, read('[{:la1 [:f1]}]'))['la1'], [{ 'f1': 3 }])
def test_complex_field(): engine = Engine(SyncExecutor()) def get_a(fields, ids): return [[{'s': 'bar'} for _ in fields] for _ in ids] ll_graph = Graph([ Node('Foo', [ Field('a', Record[{ 's': String }], get_a), ]), ]) foo_sg = SubGraph(ll_graph, 'Foo') hl_graph = Graph([ Node('Foo', [ Field('a', Record[{ 's': String }], foo_sg), ]), Root([ Link('foo', TypeRef['Foo'], lambda: 1, requires=None), ]), ]) result = engine.execute(hl_graph, build([Q.foo[Q.a[Q.s]]])) check_result(result, {'foo': {'a': {'s': 'bar'}}})
def setUp(self): sa_engine = create_engine( 'sqlite://', connect_args={'check_same_thread': False}, poolclass=StaticPool, ) metadata.create_all(sa_engine) session.configure(bind=sa_engine) def bar_insert(r): return sa_engine.execute(bar_table.insert(), r).lastrowid self.bar_ids = list(map(bar_insert, [ {'name': 'bar1', 'type': 1}, {'name': 'bar2', 'type': 2}, {'name': 'bar3', 'type': 3}, ])) def foo_insert(r): return sa_engine.execute(foo_table.insert(), r).lastrowid list(map(foo_insert, [ {'name': 'foo1', 'count': 5, 'bar_id': self.bar_ids[0]}, {'name': 'foo2', 'count': 10, 'bar_id': self.bar_ids[1]}, {'name': 'foo3', 'count': 15, 'bar_id': self.bar_ids[2]}, ])) self.engine = Engine(ThreadsExecutor(thread_pool))
async def test_async_batch_endpoint(async_graph): endpoint = AsyncBatchGraphQLEndpoint(Engine(AsyncIOExecutor()), async_graph) assert await endpoint.dispatch([]) == [] result = await endpoint.dispatch({'query': '{answer}'}) assert result == {'data': {'answer': '42'}} batch_result = await endpoint.dispatch([ { 'query': '{answer}' }, { 'query': '{__typename}' }, ]) assert batch_result == [ { 'data': { 'answer': '42' } }, { 'data': { '__typename': 'Query' } }, ]
async def _check(self, src, value): sa_engine = create_async_engine(self.db_dsn) engine = Engine(AsyncIOExecutor()) try: result = await engine.execute(self.graph, read(src), {SA_ENGINE_KEY: sa_engine}) check_result(result, value) finally: await greenlet_spawn(sa_engine.sync_engine.dispose)
def main(): logging.basicConfig() app = web.Application() app.add_routes([ web.post('/graphql', handle_graphql), ]) app['graphql-endpoint'] = AsyncGraphQLEndpoint( Engine(AsyncIOExecutor()), QUERY_GRAPH, MUTATION_GRAPH, ) web.run_app(app)
async def _check(self, src, value): sa_engine = await aiopg.sa.create_engine(self.db_dsn, minsize=0) engine = Engine(AsyncIOExecutor()) try: result = await engine.execute(self.graph, read(src), {SA_ENGINE_KEY: sa_engine}) check_result(result, value) finally: sa_engine.close() await sa_engine.wait_closed()
def introspect(graph): engine = Engine(SyncExecutor()) graph = apply(graph, [GraphQLIntrospection()]) query = read(QUERY) errors = validate(graph, query) assert not errors norm_result = engine.execute(graph, query) return denormalize(graph, norm_result, query)
def test_process_ordered_node(): ordering = [] def f1(fields): names = tuple(f.name for f in fields) ordering.append(names) return names def f2(fields): return f1(fields) def f3(): ordering.append('x1') return 'x1' @listify def f4(fields, ids): for i in ids: yield ['{}-e'.format(i) for _ in fields] graph = Graph([ Node('X', [ Field('e', None, f4), ]), Root([ Field('a', None, f1), Field('b', None, f1), Field('c', None, f2), Field('d', None, f2), Link('x', TypeRef['X'], f3, requires=None), ]), ]) query = q.Node([ q.Field('d'), q.Field('b'), q.Field('a'), q.Link('x', q.Node([ q.Field('e'), ])), q.Field('c'), ], ordered=True) engine = Engine(SyncExecutor()) result = engine.execute(graph, query) check_result(result, { 'a': 'a', 'b': 'b', 'c': 'c', 'd': 'd', 'x': { 'e': 'x1-e', }, }) assert ordering == [('d',), ('b', 'a'), 'x1', ('c',)]
async def test_simple_async(graph_name, sample_count): async def x_fields(fields, ids): return [[42 for _ in fields] for _ in ids] async def root_fields(fields): return [1 for _ in fields] async def x_link(): return 2 ll_graph = Graph([ Node('X', [ Field('id', None, x_fields), ]), ]) x_sg = SubGraph(ll_graph, 'X') hl_graph = Graph([ Node('X', [ Field('id', None, x_sg), ]), Root([ Field('a', None, root_fields), Link('x', TypeRef['X'], x_link, requires=None), ]), ]) hl_graph = apply(hl_graph, [AsyncGraphMetrics(graph_name)]) query = q.Node([ q.Field('a'), q.Link('x', q.Node([ q.Field('id'), ])), ]) engine = Engine(AsyncIOExecutor()) assert sample_count('Root', 'a') is None assert sample_count('Root', 'x') is None assert sample_count('X', 'id') is None result = await engine.execute(hl_graph, query) check_result(result, { 'a': 1, 'x': { 'id': 42, }, }) assert sample_count('Root', 'a') == 1.0 assert sample_count('Root', 'x') == 1.0 assert sample_count('X', 'id') == 1.0
def check(self, src, value): sa_engine = create_engine( 'sqlite://', connect_args={'check_same_thread': False}, poolclass=StaticPool, ) setup_db(sa_engine) engine = Engine(ThreadsExecutor(thread_pool)) result = engine.execute(self.graph, read(src), {SA_ENGINE_KEY: sa_engine}) check_result(result, value)
def introspect(query_graph, mutation_graph=None): engine = Engine(SyncExecutor()) query_graph = apply(query_graph, [ GraphQLIntrospection(query_graph, mutation_graph), ]) query = read(QUERY) errors = validate(query_graph, query) assert not errors norm_result = engine.execute(query_graph, query) return denormalize(query_graph, norm_result)
async def test_async_introspection(event_loop): from hiku.executors.asyncio import AsyncIOExecutor from hiku.introspection.graphql import MakeAsync graph = MakeAsync().visit(GRAPH) async_hiku_engine = Engine(AsyncIOExecutor(event_loop)) from hiku.graph import apply from hiku.introspection.graphql import AsyncGraphQLIntrospection graph = apply(graph, [AsyncGraphQLIntrospection()]) query = read('{ __typename }') result = await async_hiku_engine.execute(graph, query) simple_result = denormalize(graph, result, query) assert simple_result == {'__typename': 'Root'}
async def test_actor_to_character(db_dsn, event_loop): hiku_engine = Engine(AsyncIOExecutor(event_loop)) async with aiopg.sa.create_engine(db_dsn, loop=event_loop) as sa_engine: result = await execute(hiku_engine, sa_engine, GRAPH, '[{:actors [:name {:character [:name]}]}]') assert result == { 'actors': [ { 'name': 'William Shatner', 'character': { 'name': 'James T. Kirk' }, }, { 'name': 'Leonard Nimoy', 'character': { 'name': 'Spock' }, }, { 'name': 'DeForest Kelley', 'character': { 'name': 'Leonard McCoy' }, }, { 'name': 'Chris Pine', 'character': { 'name': 'James T. Kirk' }, }, { 'name': 'Zachary Quinto', 'character': { 'name': 'Spock' }, }, { 'name': 'Karl Urban', 'character': { 'name': 'Leonard McCoy' }, }, ], }
def test(): for query in [query_graphql(), query_simple(), query_python()]: hiku_engine = Engine(SyncExecutor()) result = hiku_engine.execute(GRAPH, query) result = denormalize(GRAPH, result, query) assert result == \ { "characters": [ { "name": "James T. Kirk", "species": "Human" }, { "name": "Spock", "species": "Vulcan/Human" }, { "name": "Leonard McCoy", "species": "Human" } ] }
def test_endpoint(sync_graph): endpoint = GraphQLEndpoint(Engine(SyncExecutor()), sync_graph) result = endpoint.dispatch({'query': '{answer}'}) assert result == {'data': {'answer': '42'}}
try: query = read(data['query'], data.get('variables')) errors = validate(app.config['GRAPH'], query) if errors: result = {'errors': [{'message': e} for e in errors]} else: result = hiku_engine.execute(app.config['GRAPH'], query, ctx=app.config['HIKU_CTX']) result = {'data': denormalize(app.config['GRAPH'], result, query)} except Exception as err: result = {'errors': [{'message': repr(err)}]} return jsonify(result) if __name__ == "__main__": sa_engine = create_engine('sqlite://', connect_args={'check_same_thread': False}, poolclass=StaticPool) setup_db(sa_engine) app.config['HIKU_ENGINE'] = Engine(SyncExecutor()) app.config['HIKU_CTX'] = {SA_ENGINE_KEY: sa_engine} graph = get_graph(get_queries(hiku.sources.sqlalchemy, SA_ENGINE_KEY, SyncQueries)) graph = apply(graph, [GraphQLIntrospection()]) app.config['GRAPH'] = graph app.run()
GRAPH = Graph([ Root([ Field('foo', String, foo_field_func), ]), ]) async def handler(request): hiku_engine = request.app['HIKU_ENGINE'] data = await request.json() try: query = read(data['query'], data.get('variables')) errors = validate(request.app['GRAPH'], query) if errors: result = {'errors': [{'message': e} for e in errors]} else: result = await hiku_engine.execute(request.app['GRAPH'], query) result = {'data': denormalize(request.app['GRAPH'], result, query)} except Exception as err: result = {'errors': [{'message': repr(err)}]} return web.json_response(result) if __name__ == "__main__": app = web.Application() app.router.add_post('/', handler) app['HIKU_ENGINE'] = Engine(AsyncIOExecutor(asyncio.get_event_loop())) app['GRAPH'] = apply(GRAPH, [AsyncGraphQLIntrospection()]) web.run_app(app)
def setUp(self): self.engine = Engine(ThreadsExecutor(ThreadPoolExecutor(2)))
def _engine(): return Engine(ThreadsExecutor(ThreadPoolExecutor(2)))
def setUp(self): self.engine = Engine(ThreadsExecutor(thread_pool))
async def test_async_endpoint(async_graph): endpoint = AsyncGraphQLEndpoint(Engine(AsyncIOExecutor()), async_graph) result = await endpoint.dispatch({'query': '{answer}'}) assert result == {'data': {'answer': '42'}}
def execute(graph, query_, ctx=None): engine = Engine(SyncExecutor()) return engine.execute(graph, query_, ctx=ctx)
GRAPH = Graph([ Node('Character', [ Field('name', None, character_data), Field('species', None, character_data), ]), Root([ Link('characters', Sequence[TypeRef['Character']], to_characters_link, requires=None), ]), ]) # test hiku_engine = Engine(SyncExecutor()) def execute(graph, query_string): query = read(query_string) result = hiku_engine.execute(graph, query) return denormalize(graph, result) def test(): result = execute(GRAPH, '[{:characters [:name :species]}]') assert result == { "characters": [ { "species": "Human", "name": "James T. Kirk",
data_types=DATA_TYPES) MUTATION_GRAPH = Graph(QUERY_GRAPH.nodes + [ Root([ Field('action', Boolean, action_func, options=[Option('data', TypeRef['Data'])]), ]), ], data_types=DATA_TYPES) app = Flask(__name__) graphql_endpoint = GraphQLEndpoint( Engine(SyncExecutor()), QUERY_GRAPH, MUTATION_GRAPH, ) @app.route('/graphql', methods={'POST'}) def handle_graphql(): data = request.get_json() result = graphql_endpoint.dispatch(data) return jsonify(result) def main(): logging.basicConfig() app.run(port=5000)