Skip to content

AttributeError: 'NoneType' object has no attribute '__aenter__' when using asyncio.gather #505

Closed

Description

@MoBoo

Hello,

i am using the OnBehalfOf-Flow to fetch informations about applications from graphapi.
When using asyncio.gather to "parallelize" multiple requests (e.g. to fetch application infos and application owners) i get this error AttributeError: 'NoneType' object has no attribute '__aenter__.

This is a minimal example the reproduce the error:

async def main():
  scopes = ["https://graph.microsoft.com/Application.ReadWrite.All"]
  credentials = OnBehalfOfCredential(
              tenant_id=<redacted>,
              client_id=<redacted>,
              client_secret=<redacted>,
              user_assertion=<redacted>,
          )
  client = GraphServiceClient(credentials=credentials, scopes=scopes)
  
  app, app_owners = await asyncio.gather(*[
        client.applications.by_application_id<redacted>).get(),
        client.applications.by_application_id(<redacted>).owners.get()
    ])

asyncio.run(main())

When running those two requests sequentially they work without any problems. So i think there is some sort of race condition going on?

For a large amount of requests, this can have quite a performance impact, because it limits the benefits of actually it runnung concurrently.

Maybe there is an easy fix for it, that i might have overlooked. (E.g. manually trigger token exchange before the asyncio.gather call)

Activity

  1. frejonb commented on Dec 19, 2023

    @frejonb

    The issue might be related to this other discussion: Azure/azure-sdk-for-python#32309. We get the same error but we're not using asyncio.gather.

  2. zus666 commented on Jan 15, 2024

    @zus666

    I have the same problem, but with ClientSecretCredential

  3. ntsphwoelfel commented on Feb 13, 2024

    @ntsphwoelfel

    Same here with ClientSecretCredential using it in an AsyncAPIView with django rest framework.

  4. Christiaan-Mathu commented on Feb 27, 2024

    @Christiaan-Mathu

    Same Issue here

  5. pumon commented on Mar 15, 2024

    @pumon

    Same Issue here

    [2024-03-15T13:02:17.411Z] ClientSecretCredential.get_token failed: 'NoneType' object has no attribute '__aenter__'

  6. arenekosreal commented on Mar 27, 2024

    @arenekosreal

    This does not only happen when asyncio.gather is used. I make my msgraph api requests by using aiohttp's background tasks, but this also happens.
    I found a workaround: use sync version instead async version. For example, using from azure.identity import ClientSecretCredential instead from azure.identity.aio import ClientSecretCredential

  7. mattia-danese commented on Apr 6, 2024

    @mattia-danese

    I got the same error in an async with asyncio.TaskGroup() as tg: block.
    I solved this error by defining GraphServiceClient in the function that I give to tg.create_task().

    tasks = []
    async with asyncio.TaskGroup() as tg:
      for data in temp:
          task = tg.create_task(foo(data))
          tasks.append(task)
    return [task.result() for task in tasks]
    
    async def foo(data):
      credentials = ClientSecretCredential(
            tenant_id=... ,
            client_id=... ,
            client_secret=... 
        )
        scopes = ['https://graph.microsoft.com/.default']
        graph_client = GraphServiceClient(credentials, scopes)
    
       return await <GRAPH API ENDPOINT>
    
    
  8. ArunJRK commented on Apr 29, 2024

    @ArunJRK

    This solved for me:

    changed this from azure.identity.aio import ClientSecretCredential
    to from azure.identity import ClientSecretCredential

    The synchronous version of ClientSecretCredential is not being a problem.

  9. danielniccoli commented on May 6, 2024

    @danielniccoli

    I'm using this SDK in Azure Durable Functions. I also get this error and it seems more likely to see it the more requests are being made in a certain time period.

  10. alessnet commented on May 8, 2024

    @alessnet

    I confirm I have the same issue in Azure (Durable) Functions. I'm using ClientSecretCredential from azure.identity.aio.
    It always happens after an inactivity period.

  11. joan1294 commented on Jun 25, 2024

    @joan1294

    I have the same issue even in local from azure.identity import ClientSecretCredential worked for me. What are the consequences of using the synchronous version of ClientSecretCredential?

  12. ArunJRK commented on Jun 27, 2024

    @ArunJRK

    What are the consequences of using the synchronous version of ClientSecretCredential?

    It may block some parts of the execution. But in my experience with asyncio, multiprocessing, and threading, the GIL doesn't make sure the aio improvement doesn't trickle down into faster execution. So it might not be an issue for you here.

  13. shemogumbe commented on Oct 29, 2024

    @shemogumbe
    Contributor

    Hello Daniel Niccoli (@danielniccoli) thanks for using the SDK and for raising.

    On investigating this, it looks to be an issue with Azure_identity's management of sync and async requests rather that on the Graph SDK.

    Closing this and moving the workarounds to discussion forums to help anyone who experiences this in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions