From 8077feedcfb6efd0c48b7f3e2f963bb281706aec Mon Sep 17 00:00:00 2001 From: Mike Leonard Date: Wed, 22 Feb 2017 15:23:24 +1100 Subject: [PATCH 1/2] Added the ability to specify the JSON encoder --- flask_graphql/graphqlview.py | 7 ++++--- tests/encoder.py | 6 ++++++ tests/test_graphqlview.py | 13 +++++++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 tests/encoder.py diff --git a/flask_graphql/graphqlview.py b/flask_graphql/graphqlview.py index 40f074b..6bbbb73 100644 --- a/flask_graphql/graphqlview.py +++ b/flask_graphql/graphqlview.py @@ -33,6 +33,7 @@ class GraphQLView(View): graphiql_template = None middleware = None batch = False + json_encoder = None methods = ['GET', 'POST', 'PUT', 'DELETE'] @@ -142,10 +143,10 @@ def get_response(self, request, data, show_graphiql=False): def json_encode(self, request, d, show_graphiql=False): pretty = self.pretty or show_graphiql or request.args.get('pretty') if not pretty: - return json.dumps(d, separators=(',', ':')) + return json.dumps(d, separators=(',', ':'), cls=self.json_encoder) - return json.dumps(d, sort_keys=True, - indent=2, separators=(',', ': ')) + return json.dumps(d, sort_keys=True, indent=2, + separators=(',', ': '), cls=self.json_encoder) # noinspection PyBroadException def parse_body(self, request): diff --git a/tests/encoder.py b/tests/encoder.py new file mode 100644 index 0000000..6929ec6 --- /dev/null +++ b/tests/encoder.py @@ -0,0 +1,6 @@ +from json import JSONEncoder + + +class TestJSONEncoder(JSONEncoder): + def encode(self, o): + return 'TESTSTRING' diff --git a/tests/test_graphqlview.py b/tests/test_graphqlview.py index 1efcfbc..8134dfb 100644 --- a/tests/test_graphqlview.py +++ b/tests/test_graphqlview.py @@ -12,6 +12,7 @@ from urllib.parse import urlencode from .app import create_app +from .encoder import TestJSONEncoder from flask import url_for @@ -500,8 +501,8 @@ def test_batch_supports_post_json_query_with_json_variables(client): 'payload': { 'data': {'test': "Hello Dolly"} }, 'status': 200, }] - - + + @pytest.mark.parametrize('app', [create_app(batch=True)]) def test_batch_allows_post_with_operation_name(client): response = client.post( @@ -532,3 +533,11 @@ def test_batch_allows_post_with_operation_name(client): }, 'status': 200, }] + + +@pytest.mark.parametrize('app', [create_app(json_encoder=TestJSONEncoder)]) +def test_custom_encoder(client): + response = client.get(url_string(query='{test}')) + + # TestJSONEncoder just encodes everything to 'TESTSTRING' + assert response.data.decode() == 'TESTSTRING' From a3f84aab5774159a4372ff2fce284ce0e0666238 Mon Sep 17 00:00:00 2001 From: Mike Leonard Date: Thu, 23 Feb 2017 09:14:24 +1100 Subject: [PATCH 2/2] Added the ability to specify a JSON decoder --- flask_graphql/graphqlview.py | 3 ++- tests/encoder.py | 8 +++++++- tests/test_graphqlview.py | 14 +++++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/flask_graphql/graphqlview.py b/flask_graphql/graphqlview.py index 6bbbb73..1cfc317 100644 --- a/flask_graphql/graphqlview.py +++ b/flask_graphql/graphqlview.py @@ -34,6 +34,7 @@ class GraphQLView(View): middleware = None batch = False json_encoder = None + json_decoder = None methods = ['GET', 'POST', 'PUT', 'DELETE'] @@ -156,7 +157,7 @@ def parse_body(self, request): elif content_type == 'application/json': try: - request_json = json.loads(request.data.decode('utf8')) + request_json = json.loads(request.data.decode('utf8'), cls=self.json_decoder) if self.batch: assert isinstance(request_json, list) else: diff --git a/tests/encoder.py b/tests/encoder.py index 6929ec6..57b0854 100644 --- a/tests/encoder.py +++ b/tests/encoder.py @@ -1,6 +1,12 @@ -from json import JSONEncoder +from json import JSONEncoder, JSONDecoder +from json.decoder import WHITESPACE class TestJSONEncoder(JSONEncoder): def encode(self, o): return 'TESTSTRING' + + +class TestJSONDecoder(JSONDecoder): + def decode(self, s, _w=WHITESPACE.match): + return {'query': '{test}'} diff --git a/tests/test_graphqlview.py b/tests/test_graphqlview.py index 8134dfb..013c97a 100644 --- a/tests/test_graphqlview.py +++ b/tests/test_graphqlview.py @@ -12,7 +12,7 @@ from urllib.parse import urlencode from .app import create_app -from .encoder import TestJSONEncoder +from .encoder import TestJSONEncoder, TestJSONDecoder from flask import url_for @@ -541,3 +541,15 @@ def test_custom_encoder(client): # TestJSONEncoder just encodes everything to 'TESTSTRING' assert response.data.decode() == 'TESTSTRING' + + +@pytest.mark.parametrize('app', [create_app(json_decoder=TestJSONDecoder)]) +def test_custom_decoder(client): + # The submitted data here of 'TEST' is clearly not valid JSON. The TestJSONDecoder will + # decode this into valid JSON with a valid gql query. + response = client.post(url_string(), data='TEST', content_type='application/json') + + assert response.status_code == 200 + assert response_json(response) == { + 'data': {'test': "Hello World"} + }