Python多边界API调用失败,请求代码修正指导
问题:Postman可正常运行的API调用在Python中复现失败
我在Postman里有个能正常运行的API调用,想在Python里复现。修改Postman提供的模板代码后,API调用无法正常工作。用Wireshark对比Postman的正常请求和我的Python请求,发现第一个边界缺少application/json类型,也不确定JSON字符串传递是否正确。
Wireshark对比发现的问题
Postman的请求中,documentAttributes字段带有Content-Type: application/json标识,但我的Python请求里该字段没有这个类型声明。
当前Python请求体内容
>>> response.request.body b'--affc9f680a99e3d8509e8c9f24b422b3\r\nContent-Disposition: form-data; name="documentAttributes"\r\n\r\n{"batchInfo":{"batchName":"YMTESTALIAS","createDateTime":"2023-05-22T14:00:00.000Z"},"batchDocumentInfo":{"documentTypeName":"Photo Identification","subject":"Alias Test","metadata":[{"fieldName":"MRN","fieldValue":"9305940"},{"fieldName":"ENCTR_NBR","fieldValue":"65013813"}]},"processQueue":"BATCH","indexImmediately":"true"}\r\n--affc9f680a99e3d8509e8c9f24b422b3\r\nContent-Disposition: form-data; name="documentContent"; filename="hello.tif"\r\nContent-Type: image/tiff\r\n\r\nII*\x002\x19\x00\x00\x80?\xe0@\x0
我的Python代码
import requests import json domain = 'cert' client_mnemonic = 'xxxx_fl' auth_token = 'Basic .....==' file_path = 'C:/Users/system/Desktop/hello.tif' url = f'http://1.1.1.1/docimaging-access-1.0/{domain}.{client_mnemonic}.cernerasp.com/service/documents' batch_name = 'TESTALIAS' document_type = 'Photo Identification' subject = 'Alias Test' mrn = '9305940' fin = '65013813' # build payload payload = { 'documentAttributes': { 'batchInfo': { 'batchName': f'{batch_name}', 'createDateTime': '2023-10-31T14:00:00.000Z' }, 'batchDocumentInfo': { 'documentTypeName': f'{document_type}', 'subject': f'{subject}', 'metadata': [ { 'fieldName': 'MRN', 'fieldValue': f'{mrn}' }, { 'fieldName': 'ENCTR_NBR', 'fieldValue': f'{fin}' } ] }, 'processQueue':'BATCH', 'indexImmediately':'true' } } headers = { 'Authorization': auth_token } files = { 'documentContent': ('hello.tif', open(file_path,'rb'), 'image/tiff') } response = requests.post(url, headers=headers, data=payload, files=files)
修复方案
问题根源是requests库同时使用data和files参数时,会把data中的字段默认以普通文本格式发送,无法为单个字段指定application/json类型,和Postman的请求结构不匹配。
修改后的代码:
import requests import json domain = 'cert' client_mnemonic = 'xxxx_fl' auth_token = 'Basic .....==' file_path = 'C:/Users/system/Desktop/hello.tif' url = f'http://1.1.1.1/docimaging-access-1.0/{domain}.{client_mnemonic}.cernerasp.com/service/documents' batch_name = 'TESTALIAS' document_type = 'Photo Identification' subject = 'Alias Test' mrn = '9305940' fin = '65013813' # 将documentAttributes序列化为JSON字符串 document_attributes = json.dumps({ 'batchInfo': { 'batchName': f'{batch_name}', 'createDateTime': '2023-10-31T14:00:00.000Z' }, 'batchDocumentInfo': { 'documentTypeName': f'{document_type}', 'subject': f'{subject}', 'metadata': [ { 'fieldName': 'MRN', 'fieldValue': f'{mrn}' }, { 'fieldName': 'ENCTR_NBR', 'fieldValue': f'{fin}' } ] }, 'processQueue':'BATCH', 'indexImmediately':'true' }) headers = { 'Authorization': auth_token } # 把JSON字段和文件一起放入files参数,为JSON字段指定Content-Type files = { 'documentAttributes': (None, document_attributes, 'application/json'), 'documentContent': ('hello.tif', open(file_path,'rb'), 'image/tiff') } response = requests.post(url, headers=headers, files=files)
关键修改说明
- 将
documentAttributes的字典结构序列化为JSON字符串,不再放在data参数中 - 在
files参数中定义documentAttributes字段:第一个参数None表示该字段不是文件(无文件名),第二个参数是JSON字符串,第三个参数指定Content-Type: application/json - 移除
data参数,所有表单字段都通过files传递,确保每个字段的Content-Type符合API要求
内容的提问来源于stack exchange,提问作者Yitzhak
相关产品推荐
相关产品推荐

