Skip to content

Commit 4d54100

Browse files
committed
Update to latest versions of reqs, bump own version
Omit default event_loop in fixtures. Add tox configuration for testing.
1 parent 13cf990 commit 4d54100

13 files changed

+136
-89
lines changed

.flake8

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[flake8]
2+
ignore = E203,E501,W503,W504
3+
exclude = .git,.pytest_cache,.tox,.venv,__pycache__,build,dist
4+
max-line-length = 88

.gitignore

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
# Byte-compiled / optimized / DLL files
1+
# Compiled Python files
22
__pycache__/
33
*.py[cod]
4-
*$py.class
5-
6-
# C extensions
7-
*.so
84

95
# Distribution / packaging
106
.Python
7+
venv
8+
venv3[3-9]
9+
.venv
10+
.venv3[3-9]
11+
env
12+
.env
1113
build/
1214
develop-eggs/
1315
dist/
@@ -24,6 +26,10 @@ wheels/
2426
.installed.cfg
2527
*.egg
2628

29+
# PyInstaller
30+
*.manifest
31+
*.spec
32+
2733
# Installer logs
2834
pip-log.txt
2935
pip-delete-this-directory.txt
@@ -36,13 +42,15 @@ htmlcov/
3642
.cache
3743
coverage.xml
3844
*.cover
45+
.pytest_cache/
46+
.python-version
3947

40-
# Rope project settings
41-
.ropeproject
48+
# IntelliJ
49+
.idea
50+
*.iml
4251

43-
# Translations
44-
*.mo
45-
*.pot
52+
# Visual Studio
53+
/.vscode
4654

47-
# Environments
48-
env
55+
# OS X
56+
.DS_Store

LICENSE.txt renamed to LICENSE

File renamed without changes.

MANIFEST.in

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,14 @@
1+
include MANIFEST.in
2+
3+
include LICENSE
14
include README.md
25

6+
include .flake8
7+
include .pylintrc
8+
9+
include tox.ini
10+
11+
graft aiohttp_graphql
12+
graft tests
13+
14+
global-exclude *.py[co] __pycache__

aiohttp_graphql/graphqlview.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
from collections import Mapping
1+
from collections.abc import Mapping
22
from functools import partial
33

4-
from aiohttp import web
54
from promise import Promise
6-
5+
from aiohttp import web
76
from graphql.type.schema import GraphQLSchema
87
from graphql.execution.executors.asyncio import AsyncioExecutor
98
from graphql_server import (
@@ -18,7 +17,7 @@
1817
from .render_graphiql import render_graphiql
1918

2019

21-
class GraphQLView: # pylint: disable = too-many-instance-attributes
20+
class GraphQLView: # pylint: disable = too-many-instance-attributes
2221
def __init__(
2322
self,
2423
schema=None,
@@ -35,8 +34,7 @@ def __init__(
3534
max_age=86400,
3635
encoder=None,
3736
error_formatter=None,
38-
enable_async=True,
39-
):
37+
enable_async=True):
4038
# pylint: disable=too-many-arguments
4139
# pylint: disable=too-many-locals
4240

@@ -55,9 +53,7 @@ def __init__(
5553
self.encoder = encoder or json_encode
5654
self.error_formatter = error_formatter or default_format_error
5755
self.enable_async = enable_async and isinstance(
58-
self.executor,
59-
AsyncioExecutor,
60-
)
56+
self.executor, AsyncioExecutor)
6157
assert isinstance(self.schema, GraphQLSchema), \
6258
'A Schema is required to be provided to GraphQLView.'
6359

@@ -76,14 +72,13 @@ async def parse_body(self, request):
7672
r_text = await request.text()
7773
return {'query': r_text}
7874

79-
elif request.content_type == 'application/json':
75+
if request.content_type == 'application/json':
8076
text = await request.text()
8177
return load_json_body(text)
8278

83-
elif request.content_type in (
79+
if request.content_type in (
8480
'application/x-www-form-urlencoded',
85-
'multipart/form-data',
86-
):
81+
'multipart/form-data'):
8782
# TODO: seems like a multidict would be more appropriate
8883
# than casting it and de-duping variables. Alas, it's what
8984
# graphql-python wants.
@@ -143,6 +138,11 @@ async def __call__(self, request):
143138
executor=self.executor,
144139
)
145140

141+
if is_graphiql and self.enable_async:
142+
# catch errors like run_http_query does when async
143+
execution_results = [
144+
result.catch(lambda value: None)
145+
for result in execution_results]
146146
awaited_execution_results = await Promise.all(execution_results)
147147
result, status_code = encode_execution_results(
148148
awaited_execution_results,

aiohttp_graphql/render_graphiql.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def escape_js_value(value):
131131
quotation = False
132132
if value.startswith('"') and value.endswith('"'):
133133
quotation = True
134-
value = value[1:len(value)-1]
134+
value = value[1:-1]
135135

136136
value = value.replace('\\\\n', '\\\\\\n').replace('\\n', '\\\\n')
137137
if quotation:
@@ -167,8 +167,7 @@ async def render_graphiql(
167167
graphiql_version=None,
168168
graphiql_template=None,
169169
params=None,
170-
result=None,
171-
):
170+
result=None):
172171
graphiql_version = graphiql_version or GRAPHIQL_VERSION
173172
template = graphiql_template or TEMPLATE
174173
template_vars = {

setup.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,38 @@
22

33
setup(
44
name='aiohttp-graphql',
5-
version='1.0.0',
5+
version='1.1.0',
66
description='Adds GraphQL support to your aiohttp application',
77
long_description=open('README.md').read(),
8-
url='https://github.com/dfee/aiohttp-graphql',
9-
download_url='https://github.com/dfee/aiohttp-graphql/releases',
8+
long_description_content_type='text/markdown',
9+
url='https://github.com/graphql-python/aiohttp-graphql',
10+
download_url='https://github.com/graphql-python/aiohttp-graphql/releases',
1011
author='Devin Fee',
1112
author_email='devin@devinfee.com',
1213
license='MIT',
1314
classifiers=[
1415
'Development Status :: 5 - Production/Stable',
1516
'Intended Audience :: Developers',
1617
'Topic :: Software Development :: Libraries',
17-
'Programming Language :: Python :: 3.5',
1818
'Programming Language :: Python :: 3.6',
19+
'Programming Language :: Python :: 3.7',
20+
'Programming Language :: Python :: 3.8',
1921
'License :: OSI Approved :: MIT License',
2022
],
2123
keywords='api graphql protocol aiohttp',
2224
packages=find_packages(exclude=['tests']),
2325
install_requires=[
24-
'graphql-core>=2.0.dev,<3',
25-
'graphql-server-core>=1.0.dev,<2',
26-
'aiohttp>=2.0.0',
27-
'pytest-runner',
26+
'graphql-core>=2.3,<3',
27+
'graphql-server-core>=1.2,<2',
28+
'aiohttp>=3,<4',
2829
],
2930
extras_require={
3031
'test': [
31-
'pylint>=1.7.2',
32-
'pytest>=2.7.3',
33-
'pytest-asyncio>=0.7.0',
34-
'jinja2>=2.9.0',
35-
'yarl>=0.9.6',
32+
'pytest>=5.3,<5.4',
33+
'pytest-asyncio>=0.10,<0.11',
34+
'pytest-cov>=2.8,<3',
35+
'jinja2>=2.10,<3',
36+
'yarl>1.4,<1.5',
3637
],
3738
},
3839
include_package_data=True,

tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# aiohttp-graphql tests

tests/conftest.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from urllib.parse import urlencode
22

3+
import pytest
4+
35
from aiohttp import web
4-
import aiohttp.test_utils
6+
from aiohttp.test_utils import TestClient, TestServer
57
from graphql.execution.executors.asyncio import AsyncioExecutor
6-
import pytest
78

89
from aiohttp_graphql import GraphQLView
910

@@ -12,9 +13,9 @@
1213

1314
# GraphQL Fixtures
1415
@pytest.fixture(params=[True, False], ids=['async', 'sync'])
15-
def executor(request, event_loop):
16+
def executor(request):
1617
if request.param:
17-
return AsyncioExecutor(event_loop)
18+
return AsyncioExecutor()
1819
return None
1920

2021

@@ -26,21 +27,20 @@ def view_kwargs():
2627

2728
# aiohttp Fixtures
2829
@pytest.fixture
29-
def app(event_loop, executor, view_kwargs):
30-
app = web.Application(loop=event_loop)
30+
def app(executor, view_kwargs):
31+
app = web.Application()
3132
GraphQLView.attach(app, executor=executor, **view_kwargs)
3233
return app
3334

3435

3536
@pytest.fixture
36-
async def client(event_loop, app):
37-
client = aiohttp.test_utils.TestClient(app, loop=event_loop)
37+
async def client(app):
38+
client = TestClient(TestServer(app))
3839
await client.start_server()
3940
yield client
4041
await client.close()
4142

4243

43-
4444
# URL Fixtures
4545
@pytest.fixture
4646
def base_url():

tests/schema.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,18 @@ def resolve_raises(*args):
2525
),
2626
'request': GraphQLField(
2727
GraphQLNonNull(GraphQLString),
28-
resolver=lambda obj, info, *args: \
29-
info.context['request'].query.get('q'),
30-
),
28+
resolver=lambda obj, info, *args:
29+
info.context['request'].query.get('q'),
30+
),
3131
'context': GraphQLField(
3232
GraphQLNonNull(GraphQLString),
3333
resolver=lambda obj, info, *args: info.context,
3434
),
3535
'test': GraphQLField(
3636
type=GraphQLString,
3737
args={'who': GraphQLArgument(GraphQLString)},
38-
# resolver=lambda obj, args, context, info: \
39-
resolver=lambda obj, info, **args: \
40-
'Hello %s' % (args.get('who') or 'World'),
38+
resolver=lambda obj, info, **args:
39+
'Hello %s' % (args.get('who') or 'World'),
4140
),
4241
},
4342
)
@@ -63,11 +62,13 @@ async def resolver(context, *args):
6362
await asyncio.sleep(0.001)
6463
return 'hey'
6564

65+
6666
async def resolver_2(context, *args):
6767
# pylint: disable=unused-argument
6868
await asyncio.sleep(0.003)
6969
return 'hey2'
7070

71+
7172
def resolver_3(context, *args):
7273
# pylint: disable=unused-argument
7374
return 'hey3'

tests/test_graphiqlview.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from graphql.execution.executors.asyncio import AsyncioExecutor
2+
23
from jinja2 import Environment
4+
35
import pytest
46

57
from .schema import (
@@ -29,6 +31,7 @@ def view_kwargs():
2931
'graphiql': True,
3032
}
3133

34+
3235
@pytest.mark.asyncio
3336
async def test_graphiql_is_enabled(client, base_url):
3437
response = await client.get(base_url, headers={'Accept': 'text/html'})

0 commit comments

Comments
 (0)