Skip to content

Commit b99207a

Browse files
blazewiczCito
authored andcommitted
Don't use executor in run_http_query when return_promise=True (#33)
1 parent 427cccb commit b99207a

File tree

5 files changed

+163
-21
lines changed

5 files changed

+163
-21
lines changed

graphql_server/__init__.py

+26-14
Original file line numberDiff line numberDiff line change
@@ -122,20 +122,32 @@ def run_http_query(
122122

123123
all_params = [get_graphql_params(entry, extra_data) for entry in data]
124124

125-
executor = execute_options.get("executor")
126-
response_executor = executor if executor else SyncExecutor()
127-
128-
response_promises = [
129-
response_executor.execute(
130-
get_response, schema, params, catch_exc, allow_only_query, **execute_options
131-
)
132-
for params in all_params
133-
]
134-
response_executor.wait_until_finished()
135-
136-
results = [
137-
result.get() if is_thenable(result) else result for result in response_promises
138-
]
125+
if execute_options.get("return_promise"):
126+
results = [
127+
get_response(schema, params, catch_exc, allow_only_query, **execute_options)
128+
for params in all_params
129+
]
130+
else:
131+
executor = execute_options.get("executor")
132+
response_executor = executor if executor else SyncExecutor()
133+
134+
response_promises = [
135+
response_executor.execute(
136+
get_response,
137+
schema,
138+
params,
139+
catch_exc,
140+
allow_only_query,
141+
**execute_options
142+
)
143+
for params in all_params
144+
]
145+
response_executor.wait_until_finished()
146+
147+
results = [
148+
result.get() if is_thenable(result) else result
149+
for result in response_promises
150+
]
139151

140152
return ServerResults(results, all_params)
141153

tests/test_asyncio.py

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# flake8: noqa
2+
3+
import pytest
4+
5+
asyncio = pytest.importorskip("asyncio")
6+
7+
from graphql.execution.executors.asyncio import AsyncioExecutor
8+
from graphql.type.definition import (
9+
GraphQLField,
10+
GraphQLNonNull,
11+
GraphQLObjectType,
12+
)
13+
from graphql.type.scalars import GraphQLString
14+
from graphql.type.schema import GraphQLSchema
15+
from graphql_server import RequestParams, run_http_query
16+
from promise import Promise
17+
18+
from .utils import as_dicts
19+
20+
21+
def resolve_error_sync(_obj, _info):
22+
raise ValueError("error sync")
23+
24+
25+
@asyncio.coroutine
26+
def resolve_error_async(_obj, _info):
27+
yield from asyncio.sleep(0.001)
28+
raise ValueError("error async")
29+
30+
31+
def resolve_field_sync(_obj, _info):
32+
return "sync"
33+
34+
35+
@asyncio.coroutine
36+
def resolve_field_async(_obj, info):
37+
yield from asyncio.sleep(0.001)
38+
return "async"
39+
40+
41+
NonNullString = GraphQLNonNull(GraphQLString)
42+
43+
QueryRootType = GraphQLObjectType(
44+
name="QueryRoot",
45+
fields={
46+
"errorSync": GraphQLField(NonNullString, resolver=resolve_error_sync),
47+
"errorAsync": GraphQLField(NonNullString, resolver=resolve_error_async),
48+
"fieldSync": GraphQLField(NonNullString, resolver=resolve_field_sync),
49+
"fieldAsync": GraphQLField(NonNullString, resolver=resolve_field_async),
50+
},
51+
)
52+
53+
schema = GraphQLSchema(QueryRootType)
54+
55+
56+
def test_get_reponses_using_asyncioexecutor():
57+
class TestExecutor(AsyncioExecutor):
58+
called = False
59+
waited = False
60+
cleaned = False
61+
62+
def wait_until_finished(self):
63+
TestExecutor.waited = True
64+
super().wait_until_finished()
65+
66+
def clean(self):
67+
TestExecutor.cleaned = True
68+
super().clean()
69+
70+
def execute(self, fn, *args, **kwargs):
71+
TestExecutor.called = True
72+
return super().execute(fn, *args, **kwargs)
73+
74+
query = "{fieldSync fieldAsync}"
75+
76+
loop = asyncio.get_event_loop()
77+
78+
@asyncio.coroutine
79+
def get_results():
80+
result_promises, params = run_http_query(
81+
schema,
82+
"get",
83+
{},
84+
dict(query=query),
85+
executor=TestExecutor(loop=loop),
86+
return_promise=True,
87+
)
88+
results = yield from Promise.all(result_promises)
89+
return results, params
90+
91+
results, params = loop.run_until_complete(get_results())
92+
93+
expected_results = [{"data": {"fieldSync": "sync", "fieldAsync": "async"}}]
94+
95+
assert as_dicts(results) == expected_results
96+
assert params == [RequestParams(query=query, variables=None, operation_name=None)]
97+
assert TestExecutor.called
98+
assert not TestExecutor.waited
99+
assert TestExecutor.cleaned

tests/test_query.py

+33-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22

33
from graphql.error import GraphQLError
4+
from promise import Promise
45

56
from graphql_server import (
67
HttpQueryError,
@@ -15,11 +16,7 @@
1516
from pytest import raises
1617

1718
from .schema import schema
18-
19-
20-
def as_dicts(results):
21-
"""Convert execution results to a list of tuples of dicts for better comparison."""
22-
return [result.to_dict(dict_class=dict) for result in results]
19+
from .utils import as_dicts
2320

2421

2522
def test_request_params():
@@ -550,6 +547,34 @@ def execute(self, fn, *args, **kwargs):
550547

551548
query = "{test}"
552549
results, params = run_http_query(
550+
schema, "get", {}, dict(query=query), executor=TestExecutor(),
551+
)
552+
553+
assert as_dicts(results) == [{"data": {"test": "Hello World"}}]
554+
assert params == [RequestParams(query=query, variables=None, operation_name=None)]
555+
assert TestExecutor.called
556+
assert TestExecutor.waited
557+
assert not TestExecutor.cleaned
558+
559+
560+
def test_get_reponses_using_executor_return_promise():
561+
class TestExecutor(object):
562+
called = False
563+
waited = False
564+
cleaned = False
565+
566+
def wait_until_finished(self):
567+
TestExecutor.waited = True
568+
569+
def clean(self):
570+
TestExecutor.cleaned = True
571+
572+
def execute(self, fn, *args, **kwargs):
573+
TestExecutor.called = True
574+
return fn(*args, **kwargs)
575+
576+
query = "{test}"
577+
result_promises, params = run_http_query(
553578
schema,
554579
"get",
555580
{},
@@ -558,8 +583,10 @@ def execute(self, fn, *args, **kwargs):
558583
return_promise=True,
559584
)
560585

586+
results = Promise.all(result_promises).get()
587+
561588
assert as_dicts(results) == [{"data": {"test": "Hello World"}}]
562589
assert params == [RequestParams(query=query, variables=None, operation_name=None)]
563590
assert TestExecutor.called
564-
assert TestExecutor.waited
591+
assert not TestExecutor.waited
565592
assert TestExecutor.cleaned

tests/utils.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
def as_dicts(results):
2+
"""Convert execution results to a list of tuples of dicts for better comparison."""
3+
return [result.to_dict(dict_class=dict) for result in results]

tox.ini

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ deps =
1010
graphql-core>=2.1,<3
1111
pytest-cov>=2.7
1212
commands =
13-
py{py,27,33,34,35,36,37}: py.test tests {posargs}
13+
py{py,27}: py.test tests {posargs} --ignore=tests/test_asyncio.py
14+
py{py3,33,34,35,36,37,38}: py.test tests {posargs}
1415

1516
[testenv:black]
1617
basepython=python3.7

0 commit comments

Comments
 (0)