使用 aiohttp 将数据和文件作为多部分请求发送

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

我正在尝试通过 aiohttp 发送“multipart/form-data”请求。我已经尝试过使用请求并且请求工作正常。 我有一个类,其中

self.files
是一个
io.BytesIO
对象,而
self.data
是字符串值的字典。

这是我在此类中的代码的相关部分:

params = {
    "url": self.url,
    "headers": self.headers,
    "timeout": self.timeout,
    "proxy": self.proxy
}
# No data is allowed in the body for GET requests
if self.method != "get":
    if self.header_content_type == "multipart/form-data":
        with aiohttp.MultipartWriter("form-data") as mp:
            if self.data:
                for key, value in self.data.items():
                    part = mp.append(value, {'content-type': 'form-data'})
                    part.set_content_disposition('form-data', name=key)
            if self.files:
                for key, value in self.files.items():
                    part = mp.append(value.read(), {'content-type': 'form-data'})
                    part.set_content_disposition('form-data', name=key)

            params["data"] = mp

            async with aiohttp.ClientSession(trust_env=False) as session:
                async with session.post(**params) as response:
                    print(params)
                    return response

但是,调用的 API 会出现 422 错误,这意味着数据格式不正确。

我上面打印的参数的输出如下:

{'url': 'http://localhost:9999/v2/toing', 'headers': {'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkY200Y2hlZSIsImV4cCI6MTcxODI4MzAyMX0.6d5XcxucVLvml4O0Z-JBfOvrJLtz254371aQ0XKiCuI'}, 'timeout': 500, 'proxy': None, 'data': <aiohttp.multipart.MultipartWriter object at 0x1149aff40>}

“数据”部分的格式似乎不正确,并且缺少文件属性。

以下是我使用 requests.post 时适用的参数:

('http://localhost:9999/v2/toing', {'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkY200Y2hlZSIsImV4cCI6MTcxODMwMjQyMH0.lpAfQKISeIhUIcSf1OdM9ZN3eOUB0YHwcfVshY7y0VQ'}) {'data': {'request_data': '{"kk_shape": [2595, 2826], "algorithm_type": "trauma", "age": "33", "center": "toing", "is_spx": false, "detected_xx": "yyy", "kk": "hand"}'}, 'files': {'image_arr': <_io.BytesIO object at 0x116faed90>}, 'header_content_type': 'multipart/form-data'}

是否可以使用aiohttp分别发送

files
data
,因为看起来
aiohttp.ClientSession.session.post
没有像requests.post中那样的
files
参数? 我做错了什么?

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

这确实可以通过使用

aiohttp.FormData
而不是
aiohttp.MultipartWriter
来实现。 这是代码的有效修改:

params = {
    "method": self.method,
    "url": self.url,
    "headers": self.headers,
    "timeout": self.timeout,
    "proxy": self.proxy
}
# No data is allowed in the body for GET requests
if self.method != "get":
    form_data = aiohttp.FormData()
    if self.header_content_type == "multipart/form-data":
        if self.data:
            for key, value in self.data.items():
                form_data.add_field(name=key, value=value)
        if self.files:
            for key, value in self.files.items():
                form_data.add_field(name=key, value=value)

        params["data"] = form_data
    else:
        params["data"] = self.data

async with aiohttp.ClientSession(trust_env=False) as session:
    async with session.request(**params) as response:
        print(params)
        return response
© www.soinside.com 2019 - 2024. All rights reserved.