Skip to content

REFACTOR fetch schema at start of session #167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/usage/validation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Using introspection

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

.. _introspection: https://graphql.org/learn/introspection
.. _tests/starwars/schema.py: https://github.com/graphql-python/gql/blob/master/tests/starwars/schema.py
41 changes: 17 additions & 24 deletions gql/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def __init__(
:param fetch_schema_from_transport: Boolean to indicate that if we want to fetch
the schema from the transport using an introspection query
:param execute_timeout: The maximum time in seconds for the execution of a
request before a TimeoutError is raised
request before a TimeoutError is raised. Only used for async transports.
"""
assert not (
type_def and introspection
Expand Down Expand Up @@ -103,13 +103,9 @@ def __init__(
# On async transports, we fetch the schema before executing the first query
self.fetch_schema_from_transport: bool = fetch_schema_from_transport

# Enforced timeout of the execute function
# Enforced timeout of the execute function (only for async transports)
self.execute_timeout = execute_timeout

if isinstance(transport, Transport) and fetch_schema_from_transport:
with self as session:
session.fetch_schema()

def validate(self, document: DocumentNode):
""":meta private:"""
assert (
Expand Down Expand Up @@ -249,6 +245,10 @@ async def __aenter__(self):
if not hasattr(self, "session"):
self.session = AsyncClientSession(client=self)

# Get schema from transport if needed
if self.fetch_schema_from_transport and not self.schema:
await self.session.fetch_schema()

return self.session

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

# Get schema from transport if needed
if self.fetch_schema_from_transport and not self.schema:
self.session.fetch_schema()

return self.session

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

async def fetch_and_validate(self, document: DocumentNode):
"""Fetch schema from transport if needed and validate document.

If no schema is present, the validation will be skipped.
"""

# Get schema from transport if needed
if self.client.fetch_schema_from_transport and not self.client.schema:
await self.fetch_schema()

# Validate document
if self.client.schema:
self.client.validate(document)

async def _subscribe(
self, document: DocumentNode, *args, **kwargs
) -> AsyncGenerator[ExecutionResult, None]:

# Fetch schema from transport if needed and validate document if possible
await self.fetch_and_validate(document)
# Validate document
if self.client.schema:
self.client.validate(document)

# Subscribe to the transport
inner_generator: AsyncGenerator[
Expand Down Expand Up @@ -396,8 +387,10 @@ async def subscribe(
async def _execute(
self, document: DocumentNode, *args, **kwargs
) -> ExecutionResult:
# Fetch schema from transport if needed and validate document if possible
await self.fetch_and_validate(document)

# Validate document
if self.client.schema:
self.client.validate(document)

# Execute the query with the transport with a timeout
return await asyncio.wait_for(
Expand Down
Loading