You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 19:36:32