Python调用Microsoft Graph API查询AuditLog时的数据不一致问题
问题分析与解决方案
问题现象
- 单用户单次查询Microsoft Graph API获取登录记录时结果正常
- 循环批量查询6位用户时,同一用户的最后登录时间返回结果混乱(如昨天、今天、2天前交替出现)
- 移除循环内的
sleep(3)延迟后,查询30天全量登录记录会出现空白行;添加延迟则能获取完整数据
根因定位
问题源于Microsoft Graph API的节流机制:短时间内发送过多请求时,API会触发限流,部分响应会返回Retry-After字段,指示客户端需要等待的时长。如果未处理该字段直接继续请求,会导致请求被部分拦截或返回不完整/错误数据,表现为结果混乱、空白行等异常。
解决方案
在脚本中添加节流处理逻辑,每次请求后检查响应头中的Retry-After字段,若存在则按指定时长等待后再发起下一次请求,替代固定的3秒延迟:
示例代码(Python)
import requests import time def get_last_sign_in(user_principal_name): request_url = f"https://graph.microsoft.com/v1.0/auditLogs/signIns?$filter=contains(UserPrincipalName,'{user_principal_name}')&$orderby=createdDateTime desc&$top=1" # 假设已完成身份验证,此处省略token获取逻辑 headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"} while True: response = requests.get(request_url, headers=headers) if response.status_code == 429: # 读取Retry-After字段,转为整数秒数,默认等待3秒 retry_after = int(response.headers.get("Retry-After", 3)) time.sleep(retry_after) continue elif response.status_code == 200: return response.json() else: print(f"请求失败,状态码:{response.status_code}") return None # 批量查询示例 users = ["user1@domain.com", "user2@domain.com", ...] for user in users: result = get_last_sign_in(user) if result and result.get("value"): print(f"用户 {user} 最后登录时间:{result['value'][0]['createdDateTime']}")
关键要点
- 优先使用
Retry-After字段指定的等待时长,而非固定延迟,能精准适配API的限流规则 - 针对429状态码(请求过多)做循环重试,确保请求最终成功执行
- 避免硬编码等待时间,提升脚本的鲁棒性
内容的提问来源于stack exchange,提问作者Lasse Ronnenberg
相关产品推荐
相关产品推荐

