Skip to content

Commit 6254ab9

Browse files
authored
REFACTOR fetch schema at start of session (#167)
* AsyncClient: fetch schema at start of session instead of before execution of query * SyncClient: fetch schema at start of session instead of in the __init__ of the Client * DOC update docs to specify when the introspection query is done
1 parent 56bed9c commit 6254ab9

File tree

4 files changed

+301
-519
lines changed

4 files changed

+301
-519
lines changed

docs/usage/validation.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Using introspection
3737

3838
In order to get the schema directly from the GraphQL Server API using the transport, you need
3939
to set the `fetch_schema_from_transport` argument of Client to True, and the client will
40-
fetch the schema before the execution of the first query.
40+
fetch the schema directly after the first connection to the backend.
4141

4242
.. _introspection: https://graphql.org/learn/introspection
4343
.. _tests/starwars/schema.py: https://github.com/graphql-python/gql/blob/master/tests/starwars/schema.py

gql/client.py

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def __init__(
5656
:param fetch_schema_from_transport: Boolean to indicate that if we want to fetch
5757
the schema from the transport using an introspection query
5858
:param execute_timeout: The maximum time in seconds for the execution of a
59-
request before a TimeoutError is raised
59+
request before a TimeoutError is raised. Only used for async transports.
6060
"""
6161
assert not (
6262
type_def and introspection
@@ -103,13 +103,9 @@ def __init__(
103103
# On async transports, we fetch the schema before executing the first query
104104
self.fetch_schema_from_transport: bool = fetch_schema_from_transport
105105

106-
# Enforced timeout of the execute function
106+
# Enforced timeout of the execute function (only for async transports)
107107
self.execute_timeout = execute_timeout
108108

109-
if isinstance(transport, Transport) and fetch_schema_from_transport:
110-
with self as session:
111-
session.fetch_schema()
112-
113109
def validate(self, document: DocumentNode):
114110
""":meta private:"""
115111
assert (
@@ -249,6 +245,10 @@ async def __aenter__(self):
249245
if not hasattr(self, "session"):
250246
self.session = AsyncClientSession(client=self)
251247

248+
# Get schema from transport if needed
249+
if self.fetch_schema_from_transport and not self.schema:
250+
await self.session.fetch_schema()
251+
252252
return self.session
253253

254254
async def __aexit__(self, exc_type, exc, tb):
@@ -267,6 +267,10 @@ def __enter__(self):
267267
if not hasattr(self, "session"):
268268
self.session = SyncClientSession(client=self)
269269

270+
# Get schema from transport if needed
271+
if self.fetch_schema_from_transport and not self.schema:
272+
self.session.fetch_schema()
273+
270274
return self.session
271275

272276
def __exit__(self, *args):
@@ -335,26 +339,13 @@ def __init__(self, client: Client):
335339
""":param client: the :class:`client <gql.client.Client>` used"""
336340
self.client = client
337341

338-
async def fetch_and_validate(self, document: DocumentNode):
339-
"""Fetch schema from transport if needed and validate document.
340-
341-
If no schema is present, the validation will be skipped.
342-
"""
343-
344-
# Get schema from transport if needed
345-
if self.client.fetch_schema_from_transport and not self.client.schema:
346-
await self.fetch_schema()
347-
348-
# Validate document
349-
if self.client.schema:
350-
self.client.validate(document)
351-
352342
async def _subscribe(
353343
self, document: DocumentNode, *args, **kwargs
354344
) -> AsyncGenerator[ExecutionResult, None]:
355345

356-
# Fetch schema from transport if needed and validate document if possible
357-
await self.fetch_and_validate(document)
346+
# Validate document
347+
if self.client.schema:
348+
self.client.validate(document)
358349

359350
# Subscribe to the transport
360351
inner_generator: AsyncGenerator[
@@ -396,8 +387,10 @@ async def subscribe(
396387
async def _execute(
397388
self, document: DocumentNode, *args, **kwargs
398389
) -> ExecutionResult:
399-
# Fetch schema from transport if needed and validate document if possible
400-
await self.fetch_and_validate(document)
390+
391+
# Validate document
392+
if self.client.schema:
393+
self.client.validate(document)
401394

402395
# Execute the query with the transport with a timeout
403396
return await asyncio.wait_for(

0 commit comments

Comments
 (0)