Используйте Asyncio внутри циклаPython

Программы на Python
Anonymous
Используйте Asyncio внутри цикла

Сообщение Anonymous »

Я создал программу, содержащую две основные асинхронные функции, которые я запускаю с помощью asyncio:
  • get_all_group_members(): принимает список идентификаторов групп Entra ID и возвращает список членов этой группы с помощью API Microsoft Graph (используя функцию в другом скрипте).
  • get_user_name(): принимает список пользователей, имеющих доступ к ресурсу Azure. и получает отображаемое имя пользователя с помощью API Microsoft Graph.
Если я запустил свою программу один раз, с одним списком групп идентификаторов Entra и одним списком Пользователи ресурсов Azure, все работает отлично, я получаю ожидаемые результаты от API Graph. Однако если я затем помещу свой код в цикл, который выполняет одни и те же действия для нескольких списков групп и нескольких списков пользователей ресурсов Azure, он завершится ошибкой только на второй итерации цикла с ошибкой Event. цикл закрыт. Я получаю эту ошибку на второй итерации цикла независимо от того, какую методологию я использую с asyncio.
Я хочу знать, как я могу выполнять отдельные асинхронные вызовы Graph API с помощью asyncio и получать второй цикл вызовов API для работы. Мне нужно иметь возможность просматривать список ресурсов/групп и получать данные для всех из них, а не просто запускать одну группу/список за раз.
Что я пробовал ( у меня ничего из этого не работает):
  • Использование asyncio.gather(), а затем asyncio.run()

    Код: Выделить всё

    async def get_all_group_members():
    memberListAll = []
    for group in groupList:
    results = await gq.get_group_user(group['GroupID'], graphServiceClient)
    memberDict = {"GroupName":group["GroupName"], "GroupID":group["GroupID"], "MemberList":results}
    memberListAll.append(memberDict)
    return memberListAll
    
    # This function will get the display name for an Entra ID user based on the object ID for that account
    async def get_user_name():
    ownerUsernameList = []
    for owner in ownersList:
    if owner['principalType'] == 'User':
    results = await gq.get_user_by_id(userID=owner['principalID'],graphServiceClient=graphServiceClient)
    ownerUsernameList.append(results)
    return ownerUsernameList
    
    async def run_async_functions():
    groupResults, usernameResults = await asyncio.gather(get_all_group_members(), get_user_name())
    return groupResults, usernameResults
    
    groupResults, usernameResults = asyncio.run(run_async_functions())
    
  • Создание собственного цикла, его открытие, использование цикла и его закрытие. На второй итерации обработки моих списков/вызова API Graph мой цикл сообщит, что он открыт, но я все равно получаю вышеуказанную ошибку при запуске асинхронных функций.

Код: Выделить всё

asyncio.set_event_loop(asyncio.new_event_loop())
newLoop = asyncio.get_event_loop()
isOpen = asyncio.get_event_loop().is_closed()
print("Is the loop open? ", not isOpen)
>>>> Is the loop open? True

async def get_all_group_members():
memberListAll = []
for group in groupList:
results = await gq.get_group_user(group['GroupID'], graphServiceClient) # Calls function from other script I wrote
memberDict = {"GroupName":group["GroupName"], "GroupID":group["GroupID"], "MemberList":results}
memberListAll.append(memberDict)
return memberListAll

async def get_user_name():
ownerUsernameList = []
for owner in ownersList:
if owner['principalType'] == 'User':
results = await gq.get_user_by_id(userID=owner['principalID'],graphServiceClient=graphServiceClient)
ownerUsernameList.append(results)
return ownerUsernameList

# This function calls both of the above async functions so that we can have one function for asyncio to run
async def run_async_functions():
groupResults = await get_all_group_members()
usernameResults = await get_user_name()
return groupResults, usernameResults

groupResults, usernameResults = newLoop.run_until_complete(run_async_functions())

newLoop.close()
isClosed = asyncio.get_event_loop().is_closed()
print("Is the loop closed? ", str(isClosed))
>>>> Is the loop closed? True
  • Создание отдельного цикла для первой асинхронной функции, закрытие этого цикла, а затем создание второго цикла для второй асинхронной функции. Тем не менее, я по-прежнему получаю ту же ошибку, но только на второй итерации моего скрипта при обработке второго списка групп/пользователей.

Код: Выделить всё

async def get_all_group_members():
memberListAll = []
for group in groupList:
results = await gq.get_group_user(group['GroupID'], graphServiceClient)
memberDict = {"GroupName":group["GroupName"], "GroupID":group["GroupID"], "MemberList":results}
memberListAll.append(memberDict)
return memberListAll

async def get_user_name():
ownerUsernameList = []
for owner in ownersList:
if owner['principalType'] == 'User':
results = await gq.get_user_by_id(userID=owner['principalID'],graphServiceClient=graphServiceClient)
ownerUsernameList.append(results)
return ownerUsernameList

groupLoop = asyncio.new_event_loop()
asyncio.set_event_loop(groupLoop)
isOpen = asyncio.get_event_loop().is_closed()
print("Is the loop open? ", not isOpen)
>>>> Is the loop open? True

groupResults = groupLoop.run_until_complete(get_all_group_members())

groupLoop.close()
isClosed = asyncio.get_event_loop().is_closed()
print("Is the loop closed? ", str(isClosed))
>>>> Is the loop closed? True

usernameLoop = asyncio.new_event_loop()
asyncio.set_event_loop(usernameLoop)
isOpen = asyncio.get_event_loop().is_closed()
print("Is the loop open? ", not isOpen)
>>>> Is the loop open? True

usernameResults = usernameLoop.run_until_complete(get_user_name())

usernameLoop.close()
isClosed = asyncio.get_event_loop().is_closed()
print("Is the loop closed? ", str(isClosed))
>>>> Is the loop closed? True
Так как же мне успешно заставить эти асинхронные функции работать и не выдавать ошибку на второй итерации моей программы, когда я пытаюсь обработать второй список групп и пользователей? Почему, хотя я специально открываю цикл и он говорит, что он открыт, я получаю ошибку «Цикл событий закрыт»?

Подробнее здесь: https://stackoverflow.com/questions/786 ... hin-a-loop

Вернуться в «Python»