multipart/form-data Mirakl API 请求中的错误请求
Bad request in multipart/form-data Mirakl API request
我正尝试在 Python 3.8 中进行 API 调用。
我在curl中实现了请求,如下:
curl --location --request POST 'https://url.mirakl.net/api/orders/1720178-A/documents' --header 'Authorization: 9xxxxxxxx-4xxx-4xxx-8xxx-xxxxxxxxxxx6' --header 'Accept: application/json' --header 'Content-Type: multipart/form-data' --frm 'files=@"1720178-A.pdf"' --form 'order_documents="<body><order_documents><order_document><file_name>1720178-A.pdf</file_name><type_code>CUSTOMER_INVOICE</type_code> </order_document></order_documents></body>";type=application/xml'
有效,但 Python 代码无效:
url = "https://url.mirakl.net/api/orders/1720178-A/documents"
payload = {"order_documents": '<body><order_documents><order_document><file_name>1720178-A.pdf</file_name>'
'<type_code>CUSTOMER_INVOICE</type_code></order_document></order_documents></body>'}
files = [
("files", ('1720178-A.pdf', open('1720178-A.pdf', 'rb')))
]
headers = {
'Authorization': 'xxxxxxxxx-xxx5-4xxx-xxxx-xxxxxxxxx6',
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
返回以下错误:{"status":400,"message":"Bad Request"}
我在执行请求时的错误很明显,但我不知道我遗漏了什么。
我也尝试过 json 有效负载,结果相同:
payload = {"order_documents":[{"file_name":"1720178-A.pdf","type_code":"CUSTOMER_INVOICE"}]}
在我的日常工作中,我使用 Python 完成其他任务,但由于我将它用于此任务,所以我想以正确的方式完成它,而不依赖于 运行从 python.
卷曲
P.S。看了请愿书的正文,我看不出有什么不妥。
print(requests.Request("POST", url, headers=headers, files=files, data=payload).prepare().body.decode('US-ASCII', errors='ignore'))
--b54bd40f2809e798c2a04069686c35fc
Content-Disposition: form-data; name="order_documents"
{'file_name': '1720178-A.pdf', 'type_code': 'CUSTOMER_INVOICE'}
--b54bd40f2809e798c2a04069686c35fc
Content-Disposition: form-data; name="files"; filename="1720178-A.pdf"
Content-Type: application/pdf
%PDF-1.7
%
....
....
....
....
%%EOF
--b54bd40f2809e798c2a04069686c35fc--
我最近在 multipart/form 发送时遇到了类似的问题。这是我的解决方法。
我生成的 json 部分如下:
import os
data = {
'title': (None, "testFiles", 'application/json'),
"short": (None, "testFileShort", 'application/json'),
"ref_name_1": (None, "TestRef2", 'application/json'),
"upload_file_1" = (os.path.basename("test.txt"), open("test.txt", 'rb'), 'application/octet-stream')
}
我不完全确定,为什么 json 如此模糊,或者这是否是最优雅的方式,但它对我来说非常有效。
请求代码如下:
import requests
def POST(self, address, json=None, files=None):
url = self.URL + address
return requests.post(url=url, json=json, files=files)
try:
r = httpBackend.POST(
"/resources/create-files-item",
files=data)
except Exception:
return None
终于找到问题的根源了
为了实施 API 调用(不只是一个,而是多个),我下载了零售商向消费者提供的 Postman collection。
检查 Postman 调用是否正常后,我的失败是什么?使用软件提供的自动代码生成。虽然它是请求库的实现,但它设置了 content-type header,这会导致错误。请求正确自动生成它:
{
"User-Agent": "sitename.app",
"Accept-Encoding": "gzip, deflate",
"Accept": "application/json",
"Connection": "keep-alive",
"Authorization": "xxx-xxxx-xxx-xxx",
"Content-Length": "22680",
"Content-Type": "multipart/form-data; boundary=aea8e12ea4fd0c7d9debb64f69ad0718"
}
在下面的屏幕截图中,我展示了 collection 如何包含内容类型并将其带到实现中,即使它使用请求也是如此:
我正尝试在 Python 3.8 中进行 API 调用。
我在curl中实现了请求,如下:
curl --location --request POST 'https://url.mirakl.net/api/orders/1720178-A/documents' --header 'Authorization: 9xxxxxxxx-4xxx-4xxx-8xxx-xxxxxxxxxxx6' --header 'Accept: application/json' --header 'Content-Type: multipart/form-data' --frm 'files=@"1720178-A.pdf"' --form 'order_documents="<body><order_documents><order_document><file_name>1720178-A.pdf</file_name><type_code>CUSTOMER_INVOICE</type_code> </order_document></order_documents></body>";type=application/xml'
有效,但 Python 代码无效:
url = "https://url.mirakl.net/api/orders/1720178-A/documents"
payload = {"order_documents": '<body><order_documents><order_document><file_name>1720178-A.pdf</file_name>'
'<type_code>CUSTOMER_INVOICE</type_code></order_document></order_documents></body>'}
files = [
("files", ('1720178-A.pdf', open('1720178-A.pdf', 'rb')))
]
headers = {
'Authorization': 'xxxxxxxxx-xxx5-4xxx-xxxx-xxxxxxxxx6',
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
返回以下错误:{"status":400,"message":"Bad Request"}
我在执行请求时的错误很明显,但我不知道我遗漏了什么。
我也尝试过 json 有效负载,结果相同:
payload = {"order_documents":[{"file_name":"1720178-A.pdf","type_code":"CUSTOMER_INVOICE"}]}
在我的日常工作中,我使用 Python 完成其他任务,但由于我将它用于此任务,所以我想以正确的方式完成它,而不依赖于 运行从 python.
卷曲P.S。看了请愿书的正文,我看不出有什么不妥。
print(requests.Request("POST", url, headers=headers, files=files, data=payload).prepare().body.decode('US-ASCII', errors='ignore'))
--b54bd40f2809e798c2a04069686c35fc
Content-Disposition: form-data; name="order_documents"
{'file_name': '1720178-A.pdf', 'type_code': 'CUSTOMER_INVOICE'}
--b54bd40f2809e798c2a04069686c35fc
Content-Disposition: form-data; name="files"; filename="1720178-A.pdf"
Content-Type: application/pdf
%PDF-1.7
%
....
....
....
....
%%EOF
--b54bd40f2809e798c2a04069686c35fc--
我最近在 multipart/form 发送时遇到了类似的问题。这是我的解决方法。
我生成的 json 部分如下:
import os
data = {
'title': (None, "testFiles", 'application/json'),
"short": (None, "testFileShort", 'application/json'),
"ref_name_1": (None, "TestRef2", 'application/json'),
"upload_file_1" = (os.path.basename("test.txt"), open("test.txt", 'rb'), 'application/octet-stream')
}
我不完全确定,为什么 json 如此模糊,或者这是否是最优雅的方式,但它对我来说非常有效。
请求代码如下:
import requests
def POST(self, address, json=None, files=None):
url = self.URL + address
return requests.post(url=url, json=json, files=files)
try:
r = httpBackend.POST(
"/resources/create-files-item",
files=data)
except Exception:
return None
终于找到问题的根源了
为了实施 API 调用(不只是一个,而是多个),我下载了零售商向消费者提供的 Postman collection。
检查 Postman 调用是否正常后,我的失败是什么?使用软件提供的自动代码生成。虽然它是请求库的实现,但它设置了 content-type header,这会导致错误。请求正确自动生成它:
{
"User-Agent": "sitename.app",
"Accept-Encoding": "gzip, deflate",
"Accept": "application/json",
"Connection": "keep-alive",
"Authorization": "xxx-xxxx-xxx-xxx",
"Content-Length": "22680",
"Content-Type": "multipart/form-data; boundary=aea8e12ea4fd0c7d9debb64f69ad0718"
}
在下面的屏幕截图中,我展示了 collection 如何包含内容类型并将其带到实现中,即使它使用请求也是如此: