如何连接目标API?Python代码运行失败,求解决方案及工具建议
问题分析与解决方案
现有代码的问题点
- 令牌请求端点不符合要求:你使用的
https://login.microsoftonline.com/common/oauth2/token是旧版OAuth2端点,应替换为v2.0版本https://login.microsoftonline.com/{租户ID}/oauth2/v2.0/token,且不能用common(需指定客户提供的租户ID,多租户场景除外)。 - API请求头缺失订阅密钥:调用目标API时,你仅携带了Bearer令牌,但未加入
Ocp-Apim-Subscription-Key。Azure APIM的API通常要求同时携带该订阅密钥,建议补充到请求头中。 - 权限配置需验证:确保
client_id对应的Azure AD应用已被授予目标API的相关权限,且管理员已完成权限同意(client_credentials流必须管理员同意)。
修正后的代码示例
import requests # API端点 api_url = "https://apim-genericapi-test.azure-api.net/GenericAPI/v1/" # 认证信息 subscription_key = "xxxxxxxx" client_secret = "xxxxxxxxxx" client_id = "xxxxxxxxx" tenant_id = "你的租户ID" # 需替换为客户提供的租户ID # 获取访问令牌 token_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token" token_payload = { "client_id": client_id, "client_secret": client_secret, "grant_type": "client_credentials", "scope": f"{api_url}/.default" # 目标API的权限范围,格式为API应用ID URI + /.default } try: token_response = requests.post(token_url, data=token_payload) token_response.raise_for_status() token_data = token_response.json() access_token = token_data.get("access_token") if not access_token: print("获取访问令牌失败") print("响应内容:", token_data) exit() except Exception as e: print(f"获取令牌时出错: {e}") exit() # 调用API api_headers = { "Ocp-Apim-Subscription-Key": subscription_key, "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" } try: response = requests.get(api_url, headers=api_headers) response.raise_for_status() print(response.json()) except requests.exceptions.HTTPError as err: print(f"HTTP错误: {err}") print("响应内容:", response.text) except Exception as e: print(f"调用API时出错: {e}")
是否需要Azure工具?
不需要强制使用Azure专属工具,用requests库完全可以实现需求。但如果想更规范、便捷地处理Azure认证,推荐使用Azure官方的azure-identity库,它会自动处理令牌缓存、端点版本等细节,示例如下:
from azure.identity import ClientSecretCredential import requests tenant_id = "你的租户ID" client_id = "xxxxxxxxx" client_secret = "xxxxxxxxxx" subscription_key = "xxxxxxxx" api_url = "https://apim-genericapi-test.azure-api.net/GenericAPI/v1/" # 使用Azure Identity获取凭据 credential = ClientSecretCredential(tenant_id, client_id, client_secret) # 获取访问令牌 access_token = credential.get_token(f"{api_url}/.default").token # 调用API headers = { "Ocp-Apim-Subscription-Key": subscription_key, "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" } try: response = requests.get(api_url, headers=headers) response.raise_for_status() print(response.json()) except requests.exceptions.HTTPError as err: print(f"HTTP错误: {err}") print("响应内容:", response.text) except Exception as e: print(f"调用API时出错: {e}")
使用azure-identity的优势是无需手动处理令牌请求的细节,它会自动管理令牌的刷新和缓存,更适合长期维护的代码。
内容的提问来源于stack exchange,提问作者Ferby
相关产品推荐
相关产品推荐

