Skip to content

Update dependencies #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Dec 25, 2022
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 1 addition & 11 deletions graphql_server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,7 @@
import json
from collections import namedtuple
from collections.abc import MutableMapping
from typing import (
Any,
Callable,
Collection,
Dict,
List,
Optional,
Type,
Union,
cast,
)
from typing import Any, Callable, Collection, Dict, List, Optional, Type, Union, cast

from graphql.error import GraphQLError
from graphql.execution import ExecutionResult, execute
Expand Down
4 changes: 2 additions & 2 deletions graphql_server/quart/graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ async def parse_body():
# information provided by content_type
content_type = request.mimetype
if content_type == "application/graphql":
refined_data = await request.get_data(raw=False)
refined_data = await request.get_data(as_text=True)
return {"query": refined_data}

elif content_type == "application/json":
refined_data = await request.get_data(raw=False)
refined_data = await request.get_data(as_text=True)
return load_json_body(refined_data)

elif content_type == "application/x-www-form-urlencoded":
Expand Down
17 changes: 8 additions & 9 deletions graphql_server/render_graphiql.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Based on (express-graphql)[https://github.com/graphql/express-graphql/blob/master/src/renderGraphiQL.js] and
"""Based on (express-graphql)[https://github.com/graphql/express-graphql/blob/main/src/renderGraphiQL.ts] and
(subscriptions-transport-ws)[https://github.com/apollographql/subscriptions-transport-ws]"""
import json
import re
Expand All @@ -7,7 +7,7 @@
from jinja2 import Environment
from typing_extensions import TypedDict

GRAPHIQL_VERSION = "1.0.3"
GRAPHIQL_VERSION = "1.4.7"

Comment on lines 9 to 11
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to not update to 2.2.0 straight away?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We definitely should upgrade to 2.2.0. I was basing this on https://github.com/graphql/express-graphql/blob/main/src/renderGraphiQL.ts plus the graphiql readme recommending upgrading to 1.4.7 so I was under the impression that 1.4.7 is the latest version. Will try upgrading to 2.2.0 and verifying that everything's working, but maybe we should merge this first and I'll submit a subsequent PR for that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

GRAPHIQL_TEMPLATE = """<!--
The request to this GraphQL server provided the header "Accept: text/html"
Expand All @@ -34,12 +34,12 @@
}
</style>
<link href="//cdn.jsdelivr.net/npm/graphiql@{{graphiql_version}}/graphiql.css" rel="stylesheet" />
<script src="//cdn.jsdelivr.net/npm/promise-polyfill@8.1.3/dist/polyfill.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/unfetch@4.1.0/dist/unfetch.umd.js"></script>
<script src="//cdn.jsdelivr.net/npm/react@16.13.1/umd/react.production.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/react-dom@16.13.1/umd/react-dom.production.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/promise-polyfill@8.2.0/dist/polyfill.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/unfetch@4.2.0/dist/unfetch.umd.js"></script>
<script src="//cdn.jsdelivr.net/npm/react@16.14.0/umd/react.production.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/react-dom@16.14.0/umd/react-dom.production.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/graphiql@{{graphiql_version}}/graphiql.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/[email protected].16/browser/client.js"></script>
<script src="//cdn.jsdelivr.net/npm/[email protected].18/browser/client.js"></script>
<script src="//cdn.jsdelivr.net/npm/[email protected]/browser/client.js"></script>
</head>
<body>
Expand Down Expand Up @@ -308,9 +308,8 @@ async def render_graphiql_async(
jinja_env: Optional[Environment] = config.get("jinja_env")

if jinja_env:
# This method returns a Template. See https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.Template
template = jinja_env.from_string(graphiql_template)
if jinja_env.is_async: # type: ignore
if jinja_env.is_async:
source = await template.render_async(**template_vars)
else:
source = template.render(**template_vars)
Expand Down
4 changes: 3 additions & 1 deletion graphql_server/sanic/graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def get_validation_rules(self):
return specified_rules
return self.validation_rules

async def dispatch_request(self, request, *args, **kwargs):
async def __handle_request(self, request, *args, **kwargs):
try:
request_method = request.method.lower()
data = self.parse_body(request)
Expand Down Expand Up @@ -173,6 +173,8 @@ async def dispatch_request(self, request, *args, **kwargs):
content_type="application/json",
)

get = post = put = head = options = patch = delete = __handle_request

# noinspection PyBroadException
def parse_body(self, request):
content_type = self.get_mime_type(request)
Expand Down
8 changes: 4 additions & 4 deletions graphql_server/webob/graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

class GraphQLView:
schema = None
request = None
root_value = None
context = None
pretty = False
Expand Down Expand Up @@ -187,8 +186,9 @@ def should_display_graphiql(self, request):
if not self.graphiql or "raw" in request.params:
return False

return self.request_wants_html()
return self.request_wants_html(request)

def request_wants_html(self):
best = self.request.accept.best_match(["application/json", "text/html"])
@staticmethod
def request_wants_html(request):
best = request.accept.best_match(["application/json", "text/html"])
return best == "text/html"
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ ignore = E203, E501, W503

[isort]
known_first_party=graphql_server
profile=black
multi_line_output=3
include_trailing_comma=True
force_grid_wrap=0
Expand Down
27 changes: 15 additions & 12 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
from re import search
from setuptools import setup, find_packages

install_requires = ["graphql-core>=3.2,<3.3", "typing-extensions>=4,<5"]
install_requires = [
"graphql-core>=3.2,<3.3",
"Jinja2>=3.1,<4",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is jinja now a required dependency? AFAIK it's only used for GraphiQL, which users can disable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup you're right. Just moved it back to test dependencies.

"typing-extensions>=4,<5",
]

tests_requires = [
"pytest>=6.2,<6.3",
"pytest-asyncio>=0.16,<1",
"pytest-cov>=3,<4",
"aiohttp>=3.8,<4",
"Jinja2>=2.11,<3",
"pytest>=7.2,<8",
"pytest-asyncio>=0.20,<1",
"pytest-cov>=4,<5",
"sanic-testing>=22.3,<23",
]

dev_requires = [
"flake8>=4,<5",
"flake8>=5,<6",
"isort>=5,<6",
"black>=19.10b0",
"mypy>=0.931,<1",
"black>=22.12,<22.13",
"mypy>=0.991,<1",
"check-manifest>=0.47,<1",
] + tests_requires

install_flask_requires = [
"flask>=1,<2",
"flask>=1,<3",
]

install_sanic_requires = [
"sanic>=20.3,<21",
"sanic>=21.12,<23",
]

install_webob_requires = [
Expand All @@ -35,7 +38,7 @@
"aiohttp>=3.8,<4",
]

install_quart_requires = ["quart>=0.6.15,<0.15"]
install_quart_requires = ["quart>=0.15,<1"]

install_all_requires = (
install_requires
Expand Down
3 changes: 2 additions & 1 deletion tests/aiohttp/test_graphiqlview.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
import pytest_asyncio
from aiohttp.test_utils import TestClient, TestServer
from jinja2 import Environment

Expand All @@ -12,7 +13,7 @@ def app():
return app


@pytest.fixture
@pytest_asyncio.fixture
async def client(app):
client = TestClient(TestServer(app))
await client.start_server()
Expand Down
3 changes: 2 additions & 1 deletion tests/aiohttp/test_graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from urllib.parse import urlencode

import pytest
import pytest_asyncio
from aiohttp import FormData
from aiohttp.test_utils import TestClient, TestServer

Expand All @@ -15,7 +16,7 @@ def app():
return app


@pytest.fixture
@pytest_asyncio.fixture
async def client(app):
client = TestClient(TestServer(app))
await client.start_server()
Expand Down
3 changes: 3 additions & 0 deletions tests/quart/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from quart.typing import TestClientProtocol

TestClientProtocol.__test__ = False # type: ignore
24 changes: 13 additions & 11 deletions tests/quart/test_graphiqlview.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from typing import Optional

import pytest
from quart import Quart, Response, url_for
from quart.testing import QuartClient
from quart.typing import TestClientProtocol
from werkzeug.datastructures import Headers

from .app import create_app
Expand All @@ -18,16 +20,16 @@ def app() -> Quart:


@pytest.fixture
def client(app: Quart) -> QuartClient:
def client(app: Quart) -> TestClientProtocol:
return app.test_client()


@pytest.mark.asyncio
async def execute_client(
app: Quart,
client: QuartClient,
client: TestClientProtocol,
method: str = "GET",
headers: Headers = None,
headers: Optional[Headers] = None,
**extra_params
) -> Response:
test_request_context = app.test_request_context(path="/", method=method)
Expand All @@ -37,15 +39,15 @@ async def execute_client(


@pytest.mark.asyncio
async def test_graphiql_is_enabled(app: Quart, client: QuartClient):
async def test_graphiql_is_enabled(app: Quart, client: TestClientProtocol):
response = await execute_client(
app, client, headers=Headers({"Accept": "text/html"}), externals=False
)
assert response.status_code == 200


@pytest.mark.asyncio
async def test_graphiql_renders_pretty(app: Quart, client: QuartClient):
async def test_graphiql_renders_pretty(app: Quart, client: TestClientProtocol):
response = await execute_client(
app, client, headers=Headers({"Accept": "text/html"}), query="{test}"
)
Expand All @@ -57,26 +59,26 @@ async def test_graphiql_renders_pretty(app: Quart, client: QuartClient):
" }\n"
"}".replace('"', '\\"').replace("\n", "\\n")
)
result = await response.get_data(raw=False)
result = await response.get_data(as_text=True)
assert pretty_response in result


@pytest.mark.asyncio
async def test_graphiql_default_title(app: Quart, client: QuartClient):
async def test_graphiql_default_title(app: Quart, client: TestClientProtocol):
response = await execute_client(
app, client, headers=Headers({"Accept": "text/html"})
)
result = await response.get_data(raw=False)
result = await response.get_data(as_text=True)
assert "<title>GraphiQL</title>" in result


@pytest.mark.asyncio
@pytest.mark.parametrize(
"app", [create_app(graphiql=True, graphiql_html_title="Awesome")]
)
async def test_graphiql_custom_title(app: Quart, client: QuartClient):
async def test_graphiql_custom_title(app: Quart, client: TestClientProtocol):
response = await execute_client(
app, client, headers=Headers({"Accept": "text/html"})
)
result = await response.get_data(raw=False)
result = await response.get_data(as_text=True)
assert "<title>Awesome</title>" in result
Loading