admin管理员组

文章数量:1122846

I wrote a class that basically has two functions:

  • To connect to create a GraphQL client
  • To send a GraphQL request (query, mutation) via the client and return the answer

The send_graphql_request function needs to happen asynchronously, because in the end I need to start a subscription, then send a mutation that triggers that subscription. I removed the subscription part from the code below, because it seems to have nothing to do with the error.

Now creating the client, then sending the query works fine. Only when I send a second query, there seems to be a problem, when returning the result: Inside send_graphql_request_coroutine, the result is received, but when returning it, a RuntimeError is raised (see below).

I don't really get what RuntimeError: <asyncio.locks.Event object at 0x00000191E01F55D0 [unset]> is bound to a different event loop means, as I understand, that the previous event loop (started with asyncio.run(...) in send_graphql_request) should be closed, when returning the results the first time.

This is my code:

from gql import gql, Client
from gql.transport.websockets import WebsocketsTransport
import asyncio


class GraphQLLibrary:
    def __init__(self):
        self.client = None

    def send_graphql_request(self, query): 
        query_result = asyncio.run(self.send_graphql_request_coroutine(query))
        print("===== received query result: ", query_result)
        return query_result

    def create_graphql_client(self, url):
        transport = WebsocketsTransport(url)
        self.client = Client(transport=transport)

    async def send_graphql_request_coroutine(self, query):
        if not self.client: 
            raise AssertionError("GraphQL client is not initialized. Call 'Create GraphQL Client' first.")
        
        async with self.client as session:      
            query = gql(query)

            query_result = await session.execute(query)          
            print("===== got query result:", query_result, "\n===== returning ...")
            return query_result


url = "ws://URL/"

query = """query { system { version }}"""

gql_lib = GraphQLLibrary()

gql_lib.create_graphql_client(url)
gql_lib.send_graphql_request(query)     # this works all the time
gql_lib.send_graphql_request(query)     # this raises an error, when returning the query result

This is the terminal output. Works fine, until the results are returned to send_graphql_request the second time:

===== got query result: {'system': {'version': 'SR355.SC42.D.24090913'}} 
===== returning ...
===== received query result:  {'system': {'version': 'SR355.SC42.D.24090913'}}
===== got query result: {'system': {'version': 'SR355.SC42.D.24090913'}} 
===== returning ...
Traceback (most recent call last):
  File "c:\Users\User\directory\test_gqlLib.py", line 55, in <module>
    gql_lib.send_graphql_request(query)     # this raises an error, when returning the query result
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\User\directory\test_gqlLib.py", line 19, in send_graphql_request
    query_result = asyncio.run(self.send_graphql_request_coroutine(query))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\asyncio\base_events.py", line 650, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "c:\Users\User\directory\test_gqlLib.py", line 34, in send_graphql_request_coroutine
    async with self.client as session:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\directory\.venv\Lib\site-packages\gql\client.py", line 662, in __aexit__
    await self.close_async()
  File "C:\Users\User\directory\.venv\Lib\site-packages\gql\client.py", line 654, in close_async
    await self.transport.close()
  File "C:\Users\User\directory\.venv\Lib\site-packages\gql\transport\websockets_base.py", line 660, in close
    await self.wait_closed()
  File "C:\Users\User\directory\.venv\Lib\site-packages\gql\transport\websockets_base.py", line 667, in wait_closed
    await self._wait_closed.wait()
  File "C:\Program Files\Python311\Lib\asyncio\locks.py", line 210, in wait
    fut = self._get_loop().create_future()
          ^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\asyncio\mixins.py", line 20, in _get_loop
    raise RuntimeError(f'{self!r} is bound to a different event loop')
RuntimeError: <asyncio.locks.Event object at 0x00000191E01F55D0 [unset]> is bound to a different event loop

本文标签: