Python requests PUT文件请求失败但cURL正常,求问题排查
Python requests PUT请求返回500,但cURL正常的问题排查
用cURL测试API端点可正常工作,但Python代码发起PUT请求时返回500状态码,推测问题出在数据/文件的结构上。
正常运行的cURL命令
curl --location --request PUT 'https://myurl/endpoint' --header 'client-id: my-client-id' --header 'client-secret: my-client-secret' --header 'correlation-id: my-correlation-id' --header 'backend: service' --form 'entity_content={"Title":"1megabytetestimage","PathOnClient":"1mbimage.jpg"};type=application/json' --form 'VersionData=@"/path/to/1mbimage.jpg"' --cert certificate.pem
无法正常运行的Python代码
import requests url = 'https://myurl/endpoint' headers = { 'client-id': 'my-client-id', 'client-secret': 'my-client-secret', 'correlation-id': 'my-correlation-id', 'backend': 'service', } data = { 'entity_content': '{"Title":"1megabytetestimage","PathOnClient":"1mbimage.jpg"};type=application/json' } files = { 'VersionData': ('1mbimage.jpg', open('/mnt/d/1mbimage.jpg', 'rb'), 'image/jpeg'), } response = requests.put(url, headers=headers, files=files, data=data, cert='certificate.pem')
补充:返回的响应内容
--ec2f2bf4ebd9869d1d6a6a2d7f3b1ab7 Content-Disposition: form-data; name="entity_content" {"Title":"1megabytetestimage","PathOnClient":"1mbimage.jpg"};type=application/json --ec2f2bf4ebd9869d1d6a6a2d7f3b1ab7 Content-Disposition: form-data; name="VersionData"; filename="1mbimage.jpg" Content-Type: image/jpeg <Image Bytes> --ec2f2bf4ebd9869d1d6a6a2d7f3b1ab7--
问题原因及修复方案
问题核心
cURL命令中--form参数里的;type=application/json是指定该表单字段的Content-Type,而非字段值的一部分。但你的Python代码把这部分字符串直接作为entity_content的值传递,导致后端收到的内容不是合法JSON,解析失败返回500。
修复后的代码
将entity_content放到files字典中,明确指定其Content-Type为application/json,同时不要在字段值中包含;type=application/json:
import requests url = 'https://myurl/endpoint' headers = { 'client-id': 'my-client-id', 'client-secret': 'my-client-secret', 'correlation-id': 'my-correlation-id', 'backend': 'service', } # 纯JSON字符串,不带类型声明 entity_json = '{"Title":"1megabytetestimage","PathOnClient":"1mbimage.jpg"}' files = { # 用None作为文件名,只传递内容和类型 'entity_content': (None, entity_json, 'application/json'), 'VersionData': ('1mbimage.jpg', open('/mnt/d/1mbimage.jpg', 'rb'), 'image/jpeg'), } response = requests.put(url, headers=headers, files=files, cert='certificate.pem')
额外优化建议
- 不要手动在headers中添加
Content-Type,requests会自动处理multipart/form-data的边界和类型声明。 - 使用
with语句管理文件资源,避免潜在的资源泄漏:import requests url = 'https://myurl/endpoint' headers = { 'client-id': 'my-client-id', 'client-secret': 'my-client-secret', 'correlation-id': 'my-correlation-id', 'backend': 'service', } entity_json = '{"Title":"1megabytetestimage","PathOnClient":"1mbimage.jpg"}' with open('/mnt/d/1mbimage.jpg', 'rb') as img_file: files = { 'entity_content': (None, entity_json, 'application/json'), 'VersionData': ('1mbimage.jpg', img_file, 'image/jpeg'), } response = requests.put(url, headers=headers, files=files, cert='certificate.pem')
内容的提问来源于stack exchange,提问作者Diogo Vala
相关产品推荐
相关产品推荐

