调用Microsoft Graph API /communications/callRecords遇请求超时等问题求助
问题描述
我搭建了Azure环境,尝试调用https://graph.microsoft.com/v1.0/communications/callRecords接口,一开始遇到未知错误,给应用开了全部API权限后,现在又碰到「请求超时错误」。附上我的代码(敏感信息已隐去):
from msal import ConfidentialClientApplication import requests import json # Replace these values with your actual application and authentication details client_id = ' ' client_secret = ' ' tenant_id = ' ' authority = 'https://login.microsoftonline.com/' + tenant_id scopes = ['https://graph.microsoft.com/.default'] # Set up MSAL ConfidentialClientApplication app = ConfidentialClientApplication( client_id, authority=authority, client_credential=client_secret, ) # Acquire a token token_response = app.acquire_token_for_client(scopes=scopes) # Set up the GraphServiceClient with the acquired token access_token = token_response["access_token"] headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json", } # Define the batch request payload single_request = { "id": "1", "method": "GET", "url": "/communications/callRecords", # 考虑删除每个请求的不必要头部 } # 拆分单个请求为20个子请求 batch_size = 20 requests_to_process = [single_request.copy() for _ in range(batch_size)] batches = [requests_to_process[i:i + 1] for i in range(0, len(requests_to_process))] for batch_number, batch in enumerate(batches, start=1): batch_payload = {"requests": batch} # 进行批量请求 batch_response = requests.post( url="https://graph.microsoft.com/v1.0/$batch", headers=headers, json=batch_payload, ) # 检查批量响应 if batch_response.status_code != 200: print(f"Error in batch {batch_number}, status code: {batch_response.status_code}") print(batch_response.json()) else: print(f"Batch {batch_number} response:") print(json.dumps(batch_response.json(), indent=4))
问题排查与修复建议
1. 批量请求逻辑完全错误
你当前的代码把20个完全相同的请求拆成了20个单请求批次,完全浪费了$batch批量请求的优势,反而会额外增加服务器连接开销,这是超时的核心原因之一。Graph API允许一个批次最多包含20个请求,应该把所有请求打包进同一个批次发送,而不是分20次单请求调用。
2. Call Records接口本身的性能问题
/communications/callRecords返回的数据量通常很大,直接无参数请求会导致响应缓慢甚至超时,建议:
- 添加
$top参数限制单次返回的记录数,比如/communications/callRecords?$top=50 - 通过响应中的
@odata.nextLink实现分页,分批获取全量数据
3. 增加超时时间设置
requests.post默认超时时间较短,可手动设置timeout参数(比如timeout=30,单位秒),避免因接口响应慢触发的超时错误。
4. 确认权限有效性
虽然你开了全部权限,但要确认应用是否拥有**CallRecords.Read.All权限**(这是调用该接口的必要权限),且该权限已获取管理员同意——仅添加权限未授予同意会导致权限无效。
5. 优化后的代码示例
from msal import ConfidentialClientApplication import requests import json # 替换为你的实际信息 client_id = ' ' client_secret = ' ' tenant_id = ' ' authority = f'https://login.microsoftonline.com/{tenant_id}' scopes = ['https://graph.microsoft.com/.default'] # 初始化MSAL客户端 app = ConfidentialClientApplication( client_id, authority=authority, client_credential=client_secret, ) # 获取访问令牌(增加错误判断) token_response = app.acquire_token_for_client(scopes=scopes) if 'access_token' not in token_response: print(f"令牌获取失败: {token_response.get('error_description')}") exit() access_token = token_response["access_token"] headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json", } # 构建有效批量请求:一次发送20个分页请求(示例) batch_requests = [] for i in range(20): # 按分页逻辑生成请求,根据实际需求调整参数 request_url = f'/communications/callRecords?$top=50&$skip={i*50}' batch_requests.append({ "id": str(i+1), "method": "GET", "url": request_url }) # 发送单个批量请求 try: batch_response = requests.post( url="https://graph.microsoft.com/v1.0/$batch", headers=headers, json={"requests": batch_requests}, timeout=30 # 设置超时时间 ) batch_response.raise_for_status() # 主动抛出HTTP错误 print("批量请求响应:") print(json.dumps(batch_response.json(), indent=4)) except requests.exceptions.Timeout: print("请求超时,请检查网络或延长超时时间") except requests.exceptions.RequestException as e: print(f"请求出错: {e}") if batch_response.status_code != 200: print(f"错误详情: {json.dumps(batch_response.json(), indent=4)}")
6. 其他注意事项
- 避免短时间内发送大量重复请求,Graph API有请求频次限制,过度请求会被限流
- 查看Azure AD应用的日志,获取更详细的错误排查信息
- 确认你的网络环境可以正常访问Graph API,排查防火墙、代理等限制
内容的提问来源于stack exchange,提问作者Muerta
相关产品推荐
相关产品推荐

