使用Asyncio调用Azure REST API时输出被覆盖,如何合并多接口结果?
解决思路
你的代码核心逻辑没问题,asyncio.gather(*tasks) 会返回所有异步任务的结果组成的列表,每个元素对应循环中单个订阅的API返回数据,不存在“覆盖前一次结果”的情况。你觉得结果被覆盖,大概率是后续处理getTMs时没有正确遍历这个列表。
给你几个具体的处理方案:
1. 正确遍历所有结果
getTMs是一个列表,长度和subscriptions['value']一致,每个元素对应一个订阅的Traffic Manager数据。如果需要逐个处理每个订阅的结果,直接循环遍历即可:
async def TrafficManagers(): async with aiohttp.ClientSession(headers=headerAuth,connector=aiohttp.TCPConnector(ssl=False)) as session: tasks = [] for subscription in subscriptions['value']: urlTMs = f'https://management.azure.com/subscriptions/{subscription["subscriptionId"]}/providers/Microsoft.Network/trafficmanagerprofiles?api-version=2018-04-01&$top=2000' tasks.append(asyncio.ensure_future(TM_main(session,urlTMs))) getTMs = await asyncio.gather(*tasks) # 遍历所有结果 for idx, tm_data in enumerate(getTMs): sub_id = subscriptions['value'][idx]['subscriptionId'] print(f"订阅 {sub_id} 的Traffic Manager数据: {tm_data}")
2. 合并所有订阅的Traffic Manager数据
如果需要把所有订阅的Traffic Manager实例合并成一个统一列表,可以提取每个结果中的value字段(Azure REST API返回的资源列表通常在value键下):
async def TrafficManagers(): async with aiohttp.ClientSession(headers=headerAuth,connector=aiohttp.TCPConnector(ssl=False)) as session: tasks = [] for subscription in subscriptions['value']: urlTMs = f'https://management.azure.com/subscriptions/{subscription["subscriptionId"]}/providers/Microsoft.Network/trafficmanagerprofiles?api-version=2018-04-01&$top=2000' tasks.append(asyncio.ensure_future(TM_main(session,urlTMs))) getTMs = await asyncio.gather(*tasks) # 合并所有数据 all_traffic_managers = [] for result in getTMs: if 'value' in result: all_traffic_managers.extend(result['value']) # 现在all_traffic_managers包含所有订阅的TM实例 print(f"总计获取到 {len(all_traffic_managers)} 个Traffic Manager实例")
3. 关联订阅ID与对应数据
如果需要明确每个TM数据所属的订阅,可以修改任务逻辑,让返回结果包含订阅ID:
async def TM_main(session, urlTMs, sub_id): async with session.get(urlTMs) as resp: tm_data = await resp.json() return {'subscriptionId': sub_id, 'trafficManagers': tm_data} async def TrafficManagers(): async with aiohttp.ClientSession(headers=headerAuth,connector=aiohttp.TCPConnector(ssl=False)) as session: tasks = [] for subscription in subscriptions['value']: sub_id = subscription['subscriptionId'] urlTMs = f'https://management.azure.com/subscriptions/{sub_id}/providers/Microsoft.Network/trafficmanagerprofiles?api-version=2018-04-01&$top=2000' tasks.append(asyncio.ensure_future(TM_main(session, urlTMs, sub_id))) getTMs = await asyncio.gather(*tasks) # 每个元素都包含订阅ID和对应数据 for item in getTMs: print(f"订阅 {item['subscriptionId']} 的TM数量: {len(item['trafficManagers'].get('value', []))}")
内容的提问来源于stack exchange,提问作者kubn2
相关产品推荐
相关产品推荐

