Skip to content

Commit b13d8ba

Browse files
author
Awais Hussain
committed
Rename ResponseParser to TypeAdaptor
The 'ResponseParser' name was confusing because it was too broad, and we weren't really actually parsing the response. Hopefully this makes it clearer that what we are actually doing it just adding support for custom types.
1 parent e648487 commit b13d8ba

File tree

3 files changed

+36
-32
lines changed

3 files changed

+36
-32
lines changed

gql/client.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from graphql.validation import validate
55

66
from .transport.local_schema import LocalSchemaTransport
7-
from .response_parser import ResponseParser
7+
from .type_adaptor import TypeAdaptor
88

99
log = logging.getLogger(__name__)
1010

@@ -37,7 +37,7 @@ def __init__(self, schema=None, introspection=None, type_def=None, transport=Non
3737
self.introspection = introspection
3838
self.transport = transport
3939
self.retries = retries
40-
self.response_parser = ResponseParser(schema, custom_scalars) if custom_scalars else None
40+
self.type_adaptor = TypeAdaptor(schema, custom_scalars) if custom_scalars else None
4141

4242
def validate(self, document):
4343
if not self.schema:
@@ -54,8 +54,8 @@ def execute(self, document, *args, **kwargs):
5454
if result.errors:
5555
raise Exception(str(result.errors[0]))
5656

57-
if self.response_parser:
58-
result.data = self.response_parser.parse(result.data)
57+
if self.type_adaptor:
58+
result.data = self.type_adaptor.apply(result.data)
5959

6060
return result.data
6161

gql/response_parser.py renamed to gql/type_adaptor.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,23 @@
44
from graphql.type.definition import GraphQLObjectType, GraphQLField, GraphQLScalarType
55

66

7-
class ResponseParser(object):
8-
"""The challenge is to substitute custom scalars in a GQL response with their
9-
decoded counterparts.
7+
class TypeAdaptor(object):
8+
"""Substitute custom scalars in a GQL response with their decoded counterparts.
109
11-
To solve this problem, we first need to iterate over all the fields in the
12-
response (which is done in the `_traverse()` function).
10+
GQL custom scalar types are defined on the GQL schema and are used to represent
11+
fields which have special behaviour. To define custom scalar type, you need
12+
the type name, and a class which has a class method called `parse_value()` -
13+
this is the function which will be used to deserialize the custom scalar field.
1314
14-
Each time we find a field which has type scalar and is a custom scalar, we
15-
need to replace the value of that field with the decoded value. All of this
16-
logic happens in `_substitute()`.
15+
We first need iterate over all the fields in the response (which is done in
16+
the `_traverse()` function).
17+
18+
Each time we find a field which is a custom scalar (it's type name appears
19+
as a key in self.custom_scalars), we replace the value of that field with the
20+
decoded value. All of this logic happens in `_substitute()`.
1721
1822
Public Interface:
19-
parse(): call parse with a GQL response to replace all instances of custom
23+
parse(): pass in a GQL response to replace all instances of custom
2024
scalar strings with their deserialized representation."""
2125

2226
def __init__(self, schema: GraphQLSchema, custom_scalars: Dict[str, Any] = {}) -> None:
@@ -110,5 +114,5 @@ def iterate(node: Any, keys: List[str] = []):
110114
return substitute(keys, node)
111115
return iterate(response)
112116

113-
def parse(self, response: Dict[str, Any]) -> Dict[str, Any]:
117+
def apply(self, response: Dict[str, Any]) -> Dict[str, Any]:
114118
return self._traverse(response, self._substitute)

tests/test_response_parser.py renamed to tests/test_type_adaptor.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
locally.
66
"""
77
import copy
8-
from gql.response_parser import ResponseParser
8+
from gql.type_adaptor import TypeAdaptor
99
import pytest
1010
import requests
1111
from gql import Client
@@ -36,37 +36,37 @@ def schema():
3636
return client.schema
3737

3838
def test_scalar_type_name_for_scalar_field_returns_name(schema):
39-
parser = ResponseParser(schema)
39+
type_adaptor = TypeAdaptor(schema)
4040
schema_obj = schema.get_query_type().fields['film']
4141

42-
assert parser._get_scalar_type_name(schema_obj.type.fields['releaseDate']) == 'DateTime'
42+
assert type_adaptor ._get_scalar_type_name(schema_obj.type.fields['releaseDate']) == 'DateTime'
4343

4444

4545
def test_scalar_type_name_for_non_scalar_field_returns_none(schema):
46-
parser = ResponseParser(schema)
46+
type_adaptor = TypeAdaptor(schema)
4747
schema_obj = schema.get_query_type().fields['film']
4848

49-
assert parser._get_scalar_type_name(schema_obj.type.fields['species']) is None
49+
assert type_adaptor._get_scalar_type_name(schema_obj.type.fields['species']) is None
5050

51-
def test_lookup_scalar_type(gql_schema):
52-
parser = ResponseParser(gql_schema)
51+
def test_lookup_scalar_type(schema):
52+
type_adaptor = TypeAdaptor(schema)
5353

54-
assert parser._lookup_scalar_type(["film"]) is None
55-
assert parser._lookup_scalar_type(["film", "releaseDate"]) == 'DateTime'
56-
assert parser._lookup_scalar_type(["film", "species"]) is None
54+
assert type_adaptor._lookup_scalar_type(["film"]) is None
55+
assert type_adaptor._lookup_scalar_type(["film", "releaseDate"]) == 'DateTime'
56+
assert type_adaptor._lookup_scalar_type(["film", "species"]) is None
5757

5858
def test_lookup_scalar_type_in_mutation(schema):
59-
parser = ResponseParser(schema)
59+
type_adaptor = TypeAdaptor(schema)
6060

61-
assert parser._lookup_scalar_type(["createHero"]) is None
62-
assert parser._lookup_scalar_type(["createHero", "hero"]) is None
63-
assert parser._lookup_scalar_type(["createHero", "ok"]) == 'Boolean'
61+
assert type_adaptor._lookup_scalar_type(["createHero"]) is None
62+
assert type_adaptor._lookup_scalar_type(["createHero", "hero"]) is None
63+
assert type_adaptor._lookup_scalar_type(["createHero", "ok"]) == 'Boolean'
6464

6565
def test_parse_response(schema):
6666
custom_scalars = {
6767
'DateTime': Capitalize
6868
}
69-
parser = ResponseParser(schema, custom_scalars)
69+
type_adaptor = TypeAdaptor(schema, custom_scalars)
7070

7171
response = {
7272
'film': {
@@ -82,14 +82,14 @@ def test_parse_response(schema):
8282
}
8383
}
8484

85-
assert parser.parse(response) == expected
85+
assert type_adaptor.apply(response) == expected
8686
assert response['film']['releaseDate'] == 'some_datetime' # ensure original response is not changed
8787

8888
def test_parse_response_containing_list(schema):
8989
custom_scalars = {
9090
'DateTime': Capitalize
9191
}
92-
parser = ResponseParser(schema, custom_scalars)
92+
type_adaptor = TypeAdaptor(schema, custom_scalars)
9393

9494
response = {
9595
"allFilms": {
@@ -111,7 +111,7 @@ def test_parse_response_containing_list(schema):
111111
expected['allFilms']['edges'][0]['node']['releaseDate'] = "SOME_DATETIME"
112112
expected['allFilms']['edges'][1]['node']['releaseDate'] = "SOME_OTHER_DATETIME"
113113

114-
result = parser.parse(response)
114+
result = type_adaptor.apply(response)
115115

116116
assert result == expected
117117
expected['allFilms']['edges'][0]['node']['releaseDate'] = "some_datetime"

0 commit comments

Comments
 (0)