我在邮递员中有一些工作正常的请求。它使用 multipart/form-data,当我尝试将请求迁移到 Python 时,我遇到了一些问题。 (使用导入请求)。
所以,我的问题是Postman可以为不同类型的正文设置content-type。例子如下:()
但是在Python中却不是这样工作的。我可以为文件(application/pdf)设置内容类型,但不能为有效负载(json)设置内容类型。所以我从 api 收到错误“不支持内容类型应用程序/八位字节流”。
这是我的代码
import requests
url = "{host}:{port}/{end_point}"
payload = {'input': '{ "name": "-", "name2": "-", "name3": ["-", "-"]}'}
files = [('file', ('contractFile.pdf', open('contractFile.pdf', 'rb'), 'application/pdf'))]
headers = {'Authorization': 'Basic ---'}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
所以我在一个请求中有两个身体:
请求正文:
file(文件):包含索赔模板的文件。 -> 这应该是 application/pdf
输入(文本):索赔模板的附加输入数据。 -> 这应该是 application/json
我在邮递员中有一些工作正常的请求。它使用 multipart/form-data,当我尝试将请求迁移到 Python 时,我遇到了一些问题。 (使用导入请求)。
所以,我的问题是Postman可以为不同类型的正文设置content-type。例子如下:()
但是在Python中却不是这样工作的。我可以为文件(application/pdf)设置内容类型,但不能为有效负载(json)设置内容类型。所以我从 api 收到错误“不支持内容类型应用程序/八位字节流”。
尝试过此操作,错误“内容类型'不支持”
data = MultipartEncoder(
fields={
'input': ('{ some_json }', 'application/json'),
'file': ('contractFile.pdf', open('contractFile.pdf', 'rb'), 'application/pdf')
})
我尝试了一些不同的事情:
设置 'Content-type': 'application/json', 'Content-type': 'multipart/form-data;', 'Content-type': 'multipart/form-data;边界='***',以及类似的东西。 (不在一起);这没有帮助。
我还认为在请求中将“data”更改为“json”会有所帮助,但是使用它API无法看到我的JSON密钥,即“输入”,mb对JSON做了一些错误的事情,但经过大约30次尝试后我给出了向上。
有预期请求的示例
------WebKitFormBoundaryvwEtOpAEPX1EGWtN
Content-Disposition: form-data; name="input"; filename="blob"
Content-Type: application/json
{
JSON_BODY
}
------WebKitFormBoundaryvwEtOpAEPX1EGWtN
Content-Disposition: form-data; name="file"; filename="---"
Content-Type: application/pdf
------WebKitFormBoundaryvwEtOpAEPX1EGWtN--
备注:我的回复应该是.text,没有问题。我期待的是 text/plain;charset=UTF-8,而不是 PDF 文件。
希望有人能给我建议,谢谢!
我希望我正确理解了你的问题。以下是如何构建多部分请求表单文件并使用任何其他来源的
io.BytesIO
的示例:
import json
from io import BytesIO
import requests
files = [
("file", ("data.csv", open("data.csv", "rb"), "text/csv")),
(
"input",
(
None,
BytesIO(json.dumps({"arr": [1, 2, 3]}).encode("utf-8")),
"application/json",
),
),
]
def pretty_print_POST(req):
"""
At this point it is completely built and ready
to be fired; it is "prepared".
However pay attention at the formatting used in
this function because it is programmed to be pretty
printed and may differ from the actual request.
"""
print(
"{}\n{}\r\n{}\r\n\r\n{}".format(
"-----------START-----------",
req.method + " " + req.url,
"\r\n".join("{}: {}".format(k, v) for k, v in req.headers.items()),
req.body.decode("utf-8"),
)
)
req = requests.Request("POST", "https://httpbin.org/post", files=files)
prepared = req.prepare()
pretty_print_POST(prepared)
打印:
-----------START-----------
POST https://httpbin.org/post
Content-Length: 321
Content-Type: multipart/form-data; boundary=0b2953123572d5765857399a85a2e3c3
--0b2953123572d5765857399a85a2e3c3
Content-Disposition: form-data; name="file"; filename="data.csv"
Content-Type: text/csv
col1,col2
1,2
3,4
--0b2953123572d5765857399a85a2e3c3
Content-Disposition: form-data; name="input"
Content-Type: application/json
{"arr": [1, 2, 3]}
--0b2953123572d5765857399a85a2e3c3--