Skip to content
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

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

Closed
MoBoo opened this issue Dec 7, 2023 · 13 comments
Assignees
Labels
bug Something isn't working

Comments

@MoBoo
Copy link

MoBoo commented Dec 7, 2023

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)

@frejonb
Copy link

frejonb commented Dec 19, 2023

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.

@ZUS666
Copy link

ZUS666 commented Jan 15, 2024

I have the same problem, but with ClientSecretCredential

@ntsphwoelfel
Copy link

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

@Christiaan-Mathu
Copy link

Same Issue here

@pumon
Copy link

pumon commented Mar 15, 2024

Same Issue here

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

@arenekosreal
Copy link

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

@andrueastman andrueastman added the bug Something isn't working label Apr 3, 2024
@mattia-danese
Copy link

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>

@ArunJRK
Copy link

ArunJRK commented Apr 29, 2024

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.

@danielniccoli
Copy link

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.

@alessnet
Copy link

alessnet commented May 8, 2024

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.

@joan1294
Copy link

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?

@ArunJRK
Copy link

ArunJRK commented Jun 27, 2024

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.

@shemogumbe shemogumbe self-assigned this Oct 14, 2024
@shemogumbe
Copy link
Collaborator

Hello @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
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests