aiohttp.ClientSession multipart/form-data

aiohttp.ClientSession multipart/form-data

我有一个 curl 请求:

# form data: id = 247, name = Test
curl '{HOST}' \
  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundarywiBIWjWR7osAkgFI' \
  --data-raw $'------WebKitFormBoundarywiBIWjWR7osAkgFI\r\nContent-Disposition: form-data; name="id"\r\n\r\n247\r\n' \
              '------WebKitFormBoundarywiBIWjWR7osAkgFI\r\nContent-Disposition: form-data; name="name"\r\n\r\nTest\r\n' \
              '------WebKitFormBoundarywiBIWjWR7osAkgFI--\r\n'

使用 requests + requests_toolbelt 发送相同的请求:

mp = MultipartEncoder(
   fields={'id': '247', 'name': 'Test'},
   boundary='----WebKitFormBoundarywiBIWjWR7osAkgFI'
)

answer = requests.post(
    '{HOST}',
    data=mp,
    headers={'Content-Type': mp.content_type })

但是如何使用 aiohttp.ClientSession 发送相同的请求?我尝试使用 MultipartWriter + set_content_disposition()FormData + add_field() 但显然我做错了什么

在我的情况下工作正常:

boundary = '----WebKitFormBoundarywiBIWjWR7osAkgFI'
with aiohttp.MultipartWriter('form-data', boundary) as writer:
    # custom headers...
    # writer.headers['User-Agent'] = '...'

    data = {'id': '247', 'name': 'Test'}
    for key, value in data.items():
        part = writer.append(value, {'content-type': 'form-data'})
        part.set_content_disposition('form-data', name=key)

    async with session.post('{HOST}', data=writer) as resp:
        data = await resp.json()

仅供参考:如果需要发送表单字段,可以使用 quote_fields=False

part = writer.append('VALUE', {'content-type': 'form-data'})
part.set_content_disposition('form-data', False, name='form_fields[field_0]')

结果:

------WebKitFormBoundaryGWdKpzFAElN34726\r\nContent-Disposition: form-data; name="form_fields[field_0]"\r\n\r\nVALUE\r\n