graphql-python / gql

A GraphQL client in Python
https://gql.readthedocs.io
MIT License
1.56k stars 180 forks source link

Issue with example async permanent session #510

Closed brett-fitz closed 3 weeks ago

brett-fitz commented 3 weeks ago

Describe the bug

This could be a common problem/user error but I've gone through the documentation of creating a async permanent session and the documented pattern does not seem to work.

Code

from gql import Client, gql
from gql.transport.aiohttp import AIOHTTPTransport

async def main():
    client = Client(
        transport=AIOHTTPTransport(
            url="redacted",
            headers={
                "Authorization": 
                    f"Bearer redacted",
            },
            ssl=True
        ),
        fetch_schema_from_transport=True,
        execute_timeout=60
    )
    await client.connect_async(reconnecting=True)

    query = gql(
    """
        <gql query here>
    """
    )

    print(await client.execute(query))
    await client.close_async()

await main()

Error

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[1], line 37
     34     print(await client.execute(query))
     35     await client.close_async()
---> 37 await main()

Cell In[1], line 34
     17 await client.connect_async(reconnecting=True)
     19 query = gql(
     20 """
     21     query RootIndicatorQuery {
   (...)
     31 """
     32 )
---> 34 print(await client.execute(query))
     35 await client.close_async()

File ~/Library/Caches/pypoetry/virtualenvs/redacted/lib/python3.11/site-packages/gql/client.py:464, in Client.execute(self, document, variable_values, operation_name, serialize_variables, parse_result, get_execution_result, **kwargs)
    461     loop = asyncio.new_event_loop()
    462     asyncio.set_event_loop(loop)
--> 464 assert not loop.is_running(), (
    465     "Cannot run client.execute(query) if an asyncio loop is running."
    466     " Use 'await client.execute_async(query)' instead."
    467 )
    469 data = loop.run_until_complete(
    470     self.execute_async(
    471         document,
   (...)
    478     )
    479 )
    481 return data

AssertionError: Cannot run client.execute(query) if an asyncio loop is running. Use 'await client.execute_async(query)' instead.

_Note: If I switch to using execute_async method I get the following error:_

gql.transport.exceptions.TransportAlreadyConnected: Transport is already connected

I first tried this in an Jupyter environment but then tried it in an interpreter session and still got the same error.

To Reproduce Steps to reproduce the behavior:

Expected behavior A clear and concise description of what you expected to happen.

System info (please complete the following information):

brett-fitz commented 3 weeks ago

I've also tried this example with the same error:

https://gql.readthedocs.io/en/stable/advanced/async_permanent_session.html#console-example

TransportAlreadyConnected: Transport is already connected
leszekhanusz commented 3 weeks ago

You have to run execute on the session created from client.connect_async, not from client directly.

extract from the docs:

# Create a session from the client which will reconnect automatically.
# This session can be kept in a class for example to provide a way
# to execute GraphQL queries from many different places
session = await client.connect_async(reconnecting=True)

# You can run execute or subscribe method on this session
result = await session.execute(query)