Python 请求“不支持内容类型应用程序/八位字节流”

问题描述 投票:0回答:1

我在邮递员中有一些工作正常的请求。它使用 multipart/form-data,当我尝试将请求迁移到 Python 时,我遇到了一些问题。 (使用导入请求)。

所以,我的问题是Postman可以为不同类型的正文设置content-type。例子如下:(https://i.stack.imgur.com/iChLo.png)

但是在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。例子如下:(https://i.stack.imgur.com/iChLo.png)

但是在Python中却不是这样工作的。我可以为文件(application/pdf)设置内容类型,但不能为有效负载(json)设置内容类型。所以我从 api 收到错误“不支持内容类型应用程序/八位字节流”。

尝试过此操作,错误“内容类型'不支持”

data = MultipartEncoder(
fields={
    'input': ('{ some_json }', 'application/json'),

    'file': ('contractFile.pdf', open('contractFile.pdf', 'rb'), 'application/pdf')
})

我尝试了一些不同的事情:

  1. 设置 'Content-type': 'application/json', 'Content-type': 'multipart/form-data;', 'Content-type': 'multipart/form-data;边界='***',以及类似的东西。 (不在一起);这没有帮助。

  2. 我还认为在请求中将“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 文件。

希望有人能给我建议,谢谢!

python python-3.x python-requests
1个回答
0
投票

我希望我正确理解了你的问题。以下是如何构建多部分请求表单文件并使用任何其他来源的

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--

© www.soinside.com 2019 - 2024. All rights reserved.