Example #1
0
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'
            }
        },
    ]
Example #2
0
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
Example #3
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
            }])
Example #4
0
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'}}})
Example #5
0
    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))
Example #6
0
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)
Example #8
0
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)
Example #9
0
 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)
Example #11
0
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',)]
Example #12
0
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
Example #13
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)
Example #15
0
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'}
Example #16
0
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'
                    },
                },
            ],
        }
Example #17
0
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"
                }
            ]
        }
Example #18
0
def test_endpoint(sync_graph):
    endpoint = GraphQLEndpoint(Engine(SyncExecutor()), sync_graph)
    result = endpoint.dispatch({'query': '{answer}'})
    assert result == {'data': {'answer': '42'}}
Example #19
0
    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()
Example #20
0
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)
Example #21
0
 def setUp(self):
     self.engine = Engine(ThreadsExecutor(ThreadPoolExecutor(2)))
Example #22
0
def _engine():
    return Engine(ThreadsExecutor(ThreadPoolExecutor(2)))
Example #23
0
 def setUp(self):
     self.engine = Engine(ThreadsExecutor(thread_pool))
Example #24
0
async def test_async_endpoint(async_graph):
    endpoint = AsyncGraphQLEndpoint(Engine(AsyncIOExecutor()), async_graph)
    result = await endpoint.dispatch({'query': '{answer}'})
    assert result == {'data': {'answer': '42'}}
Example #25
0
def execute(graph, query_, ctx=None):
    engine = Engine(SyncExecutor())
    return engine.execute(graph, query_, ctx=ctx)
Example #26
0
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",
Example #27
0
                    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)