graphql-python/gql

async for not working with subscribe()

Closed this issue · 1 comments

Describe the bug
When running the subscribe generator I get this error:

  async for res in self.client.subscribe(subscription):
TypeError: 'async for' requires an object with __aiter__ method, got generator

I'm trying to reproduce this example in the docs: https://gql.readthedocs.io/en/stable/advanced/async_advanced_usage.html
Code is fairly identical except for the client is a class member instead of a function parameter
To Reproduce
Steps to reproduce the behavior:
Run this code

class Session:
    
    @backoff.on_exception(backoff.expo, Exception, max_time=300)
    def __init__(self, url: str):
        self.client = Client(transport=WebsocketsTransport(url=f'wss://{url}/ws'))
        # self.aoi_client = Client(transport=AIOHTTPTransport(url=f'https://{url}/odb'),
        #                         fetch_schema_from_transport=True)

    async def query(self, query: gql):
        return self.client.execute(query)

    async def subscribe(self, subscription: gql):
        """
        Async generator for gql.Client.subscribe
        """
        async for res in self.client.subscribe(subscription):
            print(res)
    
    async def subscribe_all(self):
        
        await self.subscribe(observation_update)

Expected behavior
Iterate through the generator

System info (please complete the following information):

  • OS: MacOS Catalina
  • Python version: 3.9
  • gql version: latest
  • graphql-core version: latest

The subscribe method of Client is a normal (not async) Python generator and is used like this: for result in client.subscribe(query) like in the default subscriptions example.

To have an async generator, you have to make a session from your client with async with:

async with client as session:
    async for result in session.subscribe(query):
        ...

It is for the moment still difficult to keep a client reference in a class (See issue #179), but it should be solved with PR #324 which is merged in the master branch and will be available in the next version.