Skip to content

Commit 074ca9e

Browse files
authored
Saving http response headers reference in transports (#293)
1 parent 23c6f85 commit 074ca9e

File tree

8 files changed

+150
-107
lines changed

8 files changed

+150
-107
lines changed

docs/usage/headers.rst

+2
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ If you want to add additional http headers for your connection, you can specify
66
.. code-block:: python
77
88
transport = AIOHTTPTransport(url='YOUR_URL', headers={'Authorization': 'token'})
9+
10+
After the connection, the latest response headers can be found in :code:`transport.response_headers`

gql/transport/aiohttp.py

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from aiohttp.helpers import BasicAuth
1313
from aiohttp.typedefs import LooseCookies, LooseHeaders
1414
from graphql import DocumentNode, ExecutionResult, print_ast
15+
from multidict import CIMultiDictProxy
1516

1617
from ..utils import extract_files
1718
from .appsync_auth import AppSyncAuthentication
@@ -75,6 +76,7 @@ def __init__(
7576
self.ssl_close_timeout: Optional[Union[int, float]] = ssl_close_timeout
7677
self.client_session_args = client_session_args
7778
self.session: Optional[aiohttp.ClientSession] = None
79+
self.response_headers: Optional[CIMultiDictProxy[str]]
7880

7981
async def connect(self) -> None:
8082
"""Coroutine which will create an aiohttp ClientSession() as self.session.
@@ -311,6 +313,9 @@ async def raise_response_error(resp: aiohttp.ClientResponse, reason: str):
311313
if "errors" not in result and "data" not in result:
312314
await raise_response_error(resp, 'No "data" or "errors" keys in answer')
313315

316+
# Saving latest response headers in the transport
317+
self.response_headers = resp.headers
318+
314319
return ExecutionResult(
315320
errors=result.get("errors"),
316321
data=result.get("data"),

gql/transport/requests.py

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ def __init__(
8181

8282
self.session = None
8383

84+
self.response_headers = None
85+
8486
def connect(self):
8587

8688
if self.session is None:
@@ -217,6 +219,7 @@ def execute( # type: ignore
217219
response = self.session.request(
218220
self.method, self.url, **post_args # type: ignore
219221
)
222+
self.response_headers = response.headers
220223

221224
def raise_response_error(resp: requests.Response, reason: str):
222225
# We raise a TransportServerError if the status code is 400 or higher

gql/transport/websockets_base.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import websockets
1010
from graphql import DocumentNode, ExecutionResult
1111
from websockets.client import WebSocketClientProtocol
12-
from websockets.datastructures import HeadersLike
12+
from websockets.datastructures import Headers, HeadersLike
1313
from websockets.exceptions import ConnectionClosed
1414
from websockets.typing import Data, Subprotocol
1515

@@ -169,6 +169,8 @@ def __init__(
169169
# The list of supported subprotocols should be defined in the subclass
170170
self.supported_subprotocols: List[Subprotocol] = []
171171

172+
self.response_headers: Optional[Headers] = None
173+
172174
async def _initialize(self):
173175
"""Hook to send the initialization messages after the connection
174176
and potentially wait for the backend ack.
@@ -495,6 +497,8 @@ async def connect(self) -> None:
495497

496498
self.websocket = cast(WebSocketClientProtocol, self.websocket)
497499

500+
self.response_headers = self.websocket.response_headers
501+
498502
# Run the after_connect hook of the subclass
499503
await self._after_connect()
500504

tests/conftest.py

+3
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ async def start(self, handler, extra_serve_args=None):
174174
self.testcert, ssl_context = get_localhost_ssl_context()
175175
extra_serve_args["ssl"] = ssl_context
176176

177+
# Adding dummy response headers
178+
extra_serve_args["extra_headers"] = {"dummy": "test1234"}
179+
177180
# Start a server with a random open port
178181
self.start_server = websockets.server.serve(
179182
handler, "127.0.0.1", 0, **extra_serve_args

0 commit comments

Comments
 (0)