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

Python requests PUT请求用json参数失败,data参数成功的原因解析

问题:使用requests的json参数调用PagerDuty合并API返回400错误,data参数却成功

我已查阅requests库中json与data参数的相关文档及差异说明,自认理解二者区别。但在调用PagerDuty事件管理软件的合并事件API时,使用PUT请求,传入data参数可成功返回200状态码,传入json参数却返回400错误。当前安装的requests版本为2.28.0,且官方示例使用的是json参数,疑惑该现象是否与payload中包含列表有关,寻求原因说明。

成功请求代码

payload = f'{{"source_incidents": [{{"id": "{child_incident_id}", "type": "incident_reference"}}]}}'

headers = {
    'Content-Type': "application/json",
    'Accept': "application/vnd.pagerduty+json;version=2",
    'From': email,
    'Authorization': f"Token token={read_write_api_token}"
    }

response = requests.put(f'https://api.pagerduty.com/incidents/{parent_incident_id}/merge', data=payload, headers=headers)

print("response: ", response)

结果:

response:  <Response [200]>

失败请求代码

payload = f'{{"source_incidents": [{{"id": "{child_incident_id}", "type": "incident_reference"}}]}}'

headers = {
    'Content-Type': "application/json",
    'Accept': "application/vnd.pagerduty+json;version=2",
    'From': email,
    'Authorization': f"Token token={read_write_api_token}"
    }

response = requests.put(f'https://api.pagerduty.com/incidents/{parent_incident_id}/merge', json=payload, headers=headers)

print("response: ", response)

结果:

response:  <Response [400]>

原因说明

核心问题是你传给json参数的是已格式化完成的JSON字符串,而非Python字典/列表这类原生对象。

requests的json参数设计初衷是接收Python原生数据结构,它会自动将其序列化为JSON字符串,同时自动设置Content-Type为application/json(即使手动设置了该头也不冲突)。但如果传入的是字符串,requests会对这个字符串再次执行JSON序列化,最终发送的内容会变成双重转义的格式(比如"\"source_incidents\": [...]"),PagerDuty的API无法解析这种格式,因此返回400错误。

而使用data参数时,你手动传入了正确的JSON字符串,同时手动设置了Content-Type头,API能正确解析请求内容,所以返回200状态码。

正确的json参数用法

把payload定义为Python字典,再传给json参数即可,无需手动拼接JSON字符串,也不需要手动设置Content-Type:

payload = {
    "source_incidents": [{"id": child_incident_id, "type": "incident_reference"}]
}

headers = {
    'Accept': "application/vnd.pagerduty+json;version=2",
    'From': email,
    'Authorization': f"Token token={read_write_api_token}"
}

response = requests.put(
    f'https://api.pagerduty.com/incidents/{parent_incident_id}/merge',
    json=payload,
    headers=headers
)

内容的提问来源于stack exchange,提问作者whoopscheckmate

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 12:40:20