Skip to content

Commit ef49268

Browse files
authored
change transports prototype using GraphQLRequest (#551)
1 parent 58cd387 commit ef49268

18 files changed

+289
-356
lines changed

gql/client.py

Lines changed: 105 additions & 119 deletions
Large diffs are not rendered by default.

gql/graphql_request.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from dataclasses import dataclass
22
from typing import Any, Dict, Optional
33

4-
from graphql import DocumentNode, GraphQLSchema
4+
from graphql import DocumentNode, GraphQLSchema, print_ast
55

66
from .utilities import serialize_variable_values
77

@@ -35,3 +35,16 @@ def serialize_variable_values(self, schema: GraphQLSchema) -> "GraphQLRequest":
3535
),
3636
operation_name=self.operation_name,
3737
)
38+
39+
@property
40+
def payload(self) -> Dict[str, Any]:
41+
query_str = print_ast(self.document)
42+
payload: Dict[str, Any] = {"query": query_str}
43+
44+
if self.operation_name:
45+
payload["operationName"] = self.operation_name
46+
47+
if self.variable_values:
48+
payload["variables"] = self.variable_values
49+
50+
return payload

gql/transport/aiohttp.py

Lines changed: 14 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from aiohttp.client_reqrep import Fingerprint
2121
from aiohttp.helpers import BasicAuth
2222
from aiohttp.typedefs import LooseCookies, LooseHeaders
23-
from graphql import DocumentNode, ExecutionResult, print_ast
23+
from graphql import ExecutionResult
2424
from multidict import CIMultiDictProxy
2525

2626
from ..graphql_request import GraphQLRequest
@@ -164,25 +164,13 @@ async def close(self) -> None:
164164

165165
self.session = None
166166

167-
def _build_payload(self, req: GraphQLRequest) -> Dict[str, Any]:
168-
query_str = print_ast(req.document)
169-
payload: Dict[str, Any] = {"query": query_str}
170-
171-
if req.operation_name:
172-
payload["operationName"] = req.operation_name
173-
174-
if req.variable_values:
175-
payload["variables"] = req.variable_values
176-
177-
return payload
178-
179167
def _prepare_batch_request(
180168
self,
181169
reqs: List[GraphQLRequest],
182170
extra_args: Optional[Dict[str, Any]] = None,
183171
) -> Dict[str, Any]:
184172

185-
payload = [self._build_payload(req) for req in reqs]
173+
payload = [req.payload for req in reqs]
186174

187175
post_args = {"json": payload}
188176

@@ -198,15 +186,15 @@ def _prepare_batch_request(
198186

199187
def _prepare_request(
200188
self,
201-
req: GraphQLRequest,
189+
request: GraphQLRequest,
202190
extra_args: Optional[Dict[str, Any]] = None,
203191
upload_files: bool = False,
204192
) -> Dict[str, Any]:
205193

206-
payload = self._build_payload(req)
194+
payload = request.payload
207195

208196
if upload_files:
209-
post_args = self._prepare_file_uploads(req, payload)
197+
post_args = self._prepare_file_uploads(request, payload)
210198
else:
211199
post_args = {"json": payload}
212200

@@ -228,11 +216,11 @@ def _prepare_request(
228216
return post_args
229217

230218
def _prepare_file_uploads(
231-
self, req: GraphQLRequest, payload: Dict[str, Any]
219+
self, request: GraphQLRequest, payload: Dict[str, Any]
232220
) -> Dict[str, Any]:
233221

234222
# If the upload_files flag is set, then we need variable_values
235-
variable_values = req.variable_values
223+
variable_values = request.variable_values
236224
assert variable_values is not None
237225

238226
# If we upload files, we will extract the files present in the
@@ -359,36 +347,28 @@ def _raise_invalid_result(self, result_text: str, reason: str) -> None:
359347

360348
async def execute(
361349
self,
362-
document: DocumentNode,
363-
variable_values: Optional[Dict[str, Any]] = None,
364-
operation_name: Optional[str] = None,
350+
request: GraphQLRequest,
351+
*,
365352
extra_args: Optional[Dict[str, Any]] = None,
366353
upload_files: bool = False,
367354
) -> ExecutionResult:
368-
"""Execute the provided document AST against the configured remote server
355+
"""Execute the provided request against the configured remote server
369356
using the current session.
370357
This uses the aiohttp library to perform a HTTP POST request asynchronously
371358
to the remote server.
372359
373360
Don't call this coroutine directly on the transport, instead use
374361
:code:`execute` on a client or a session.
375362
376-
:param document: the parsed GraphQL request
377-
:param variable_values: An optional Dict of variable values
378-
:param operation_name: An optional Operation name for the request
363+
:param request: GraphQL request as a
364+
:class:`GraphQLRequest <gql.GraphQLRequest>` object.
379365
:param extra_args: additional arguments to send to the aiohttp post method
380366
:param upload_files: Set to True if you want to put files in the variable values
381367
:returns: an ExecutionResult object.
382368
"""
383369

384-
req = GraphQLRequest(
385-
document=document,
386-
variable_values=variable_values,
387-
operation_name=operation_name,
388-
)
389-
390370
post_args = self._prepare_request(
391-
req,
371+
request,
392372
extra_args,
393373
upload_files,
394374
)
@@ -434,9 +414,7 @@ async def execute_batch(
434414

435415
def subscribe(
436416
self,
437-
document: DocumentNode,
438-
variable_values: Optional[Dict[str, Any]] = None,
439-
operation_name: Optional[str] = None,
417+
request: GraphQLRequest,
440418
) -> AsyncGenerator[ExecutionResult, None]:
441419
"""Subscribe is not supported on HTTP.
442420

gql/transport/appsync_websockets.py

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
from typing import Any, Dict, Optional, Tuple, Union, cast
55
from urllib.parse import urlparse
66

7-
from graphql import DocumentNode, ExecutionResult, print_ast
7+
from graphql import ExecutionResult
88

9+
from ..graphql_request import GraphQLRequest
910
from .appsync_auth import AppSyncAuthentication, AppSyncIAMAuthentication
1011
from .common.adapters.websockets import WebSocketsAdapter
1112
from .common.base import SubscriptionTransportBase
@@ -150,22 +151,14 @@ def _parse_answer(
150151

151152
async def _send_query(
152153
self,
153-
document: DocumentNode,
154-
variable_values: Optional[Dict[str, Any]] = None,
155-
operation_name: Optional[str] = None,
154+
request: GraphQLRequest,
156155
) -> int:
157156

158157
query_id = self.next_query_id
159158

160159
self.next_query_id += 1
161160

162-
data: Dict = {"query": print_ast(document)}
163-
164-
if variable_values:
165-
data["variables"] = variable_values
166-
167-
if operation_name:
168-
data["operationName"] = operation_name
161+
data: Dict[str, Any] = request.payload
169162

170163
serialized_data = json.dumps(data, separators=(",", ":"))
171164

@@ -203,9 +196,7 @@ async def _send_query(
203196

204197
async def execute(
205198
self,
206-
document: DocumentNode,
207-
variable_values: Optional[Dict[str, Any]] = None,
208-
operation_name: Optional[str] = None,
199+
request: GraphQLRequest,
209200
) -> ExecutionResult:
210201
"""This method is not available.
211202

gql/transport/async_transport.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import abc
2-
from typing import Any, AsyncGenerator, Dict, List, Optional
2+
from typing import Any, AsyncGenerator, List
33

4-
from graphql import DocumentNode, ExecutionResult
4+
from graphql import ExecutionResult
55

66
from ..graphql_request import GraphQLRequest
77

@@ -24,11 +24,9 @@ async def close(self):
2424
@abc.abstractmethod
2525
async def execute(
2626
self,
27-
document: DocumentNode,
28-
variable_values: Optional[Dict[str, Any]] = None,
29-
operation_name: Optional[str] = None,
27+
request: GraphQLRequest,
3028
) -> ExecutionResult:
31-
"""Execute the provided document AST for either a remote or local GraphQL
29+
"""Execute the provided request for either a remote or local GraphQL
3230
Schema."""
3331
raise NotImplementedError(
3432
"Any AsyncTransport subclass must implement execute method"
@@ -54,9 +52,7 @@ async def execute_batch(
5452
@abc.abstractmethod
5553
def subscribe(
5654
self,
57-
document: DocumentNode,
58-
variable_values: Optional[Dict[str, Any]] = None,
59-
operation_name: Optional[str] = None,
55+
request: GraphQLRequest,
6056
) -> AsyncGenerator[ExecutionResult, None]:
6157
"""Send a query and receive the results using an async generator
6258

gql/transport/common/base.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
from contextlib import suppress
66
from typing import Any, AsyncGenerator, Dict, Optional, Tuple, Union
77

8-
from graphql import DocumentNode, ExecutionResult
8+
from graphql import ExecutionResult
99

10+
from ...graphql_request import GraphQLRequest
1011
from ..async_transport import AsyncTransport
1112
from ..exceptions import (
1213
TransportAlreadyConnected,
@@ -158,9 +159,7 @@ async def _receive(self) -> str:
158159
@abstractmethod
159160
async def _send_query(
160161
self,
161-
document: DocumentNode,
162-
variable_values: Optional[Dict[str, Any]] = None,
163-
operation_name: Optional[str] = None,
162+
request: GraphQLRequest,
164163
) -> int:
165164
raise NotImplementedError # pragma: no cover
166165

@@ -267,9 +266,8 @@ async def _handle_answer(
267266

268267
async def subscribe(
269268
self,
270-
document: DocumentNode,
271-
variable_values: Optional[Dict[str, Any]] = None,
272-
operation_name: Optional[str] = None,
269+
request: GraphQLRequest,
270+
*,
273271
send_stop: Optional[bool] = True,
274272
) -> AsyncGenerator[ExecutionResult, None]:
275273
"""Send a query and receive the results using a python async generator.
@@ -281,7 +279,7 @@ async def subscribe(
281279

282280
# Send the query and receive the id
283281
query_id: int = await self._send_query(
284-
document, variable_values, operation_name
282+
request,
285283
)
286284

287285
# Create a queue to receive the answers for this query_id
@@ -325,11 +323,9 @@ async def subscribe(
325323

326324
async def execute(
327325
self,
328-
document: DocumentNode,
329-
variable_values: Optional[Dict[str, Any]] = None,
330-
operation_name: Optional[str] = None,
326+
request: GraphQLRequest,
331327
) -> ExecutionResult:
332-
"""Execute the provided document AST against the configured remote server
328+
"""Execute the provided request against the configured remote server
333329
using the current session.
334330
335331
Send a query but close the async generator as soon as we have the first answer.
@@ -339,7 +335,8 @@ async def execute(
339335
first_result = None
340336

341337
generator = self.subscribe(
342-
document, variable_values, operation_name, send_stop=False
338+
request,
339+
send_stop=False,
343340
)
344341

345342
async for result in generator:

0 commit comments

Comments
 (0)