0

I am trying to write a test for a multi-file upload endpoint built with FastAPI. The test uses Python Requests. Make sure you have multipart installed: pip install python-multipart. I am able to test upload for a single file but this endpoint that takes multiple uploads fails.

The fastAPI App:


from typing import List
from fastapi import FastAPI, File, UploadFile

app = FastAPI()

@app.post("/uploadfiles/")
async def create_upload_files(files: List[UploadFile] = File(...)):
    return {"filenames": [file.filename for file in files]}

What I have tried:

import requests

testapi = ''
with open("profile.jpeg", "rb") as image_file:
    response = requests.post(
        f"{testapi}/uploadfiles",
        files={
            "uploads": [
                ("profile.jpeg", image_file),
                ("profile2.jpeg", image_file),
            ]
        },
    )
    assert response.status_code == 200

It throws:

Traceback (most recent call last):
  File "test_uploads.py", line XYZ, in test_multi_upload
    response = client.post(
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 590, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/starlette/testclient.py", line 415, in request
    return super().request(
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 528, in request
    prep = self.prepare_request(req)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 456, in prepare_request
    p.prepare(
  File "/usr/local/lib/python3.9/site-packages/requests/models.py", line 319, in prepare
    self.prepare_body(data, files, json)
  File "/usr/local/lib/python3.9/site-packages/requests/models.py", line 512, in prepare_body
    (body, content_type) = self._encode_files(files, data)
  File "/usr/local/lib/python3.9/site-packages/requests/models.py", line 166, in _encode_files
    rf.make_multipart(content_type=ft)
  File "/usr/local/lib/python3.9/site-packages/urllib3/fields.py", line 268, in make_multipart
    self._render_parts(
  File "/usr/local/lib/python3.9/site-packages/urllib3/fields.py", line 226, in _render_parts
    parts.append(self._render_part(name, value))
  File "/usr/local/lib/python3.9/site-packages/urllib3/fields.py", line 206, in _render_part
    return self.header_formatter(name, value)
  File "/usr/local/lib/python3.9/site-packages/urllib3/fields.py", line 117, in format_header_param_html5
    value = _replace_multiple(value, _HTML5_REPLACEMENTS)
  File "/usr/local/lib/python3.9/site-packages/urllib3/fields.py", line 90, in _replace_multiple
    result = pattern.sub(replacer, value)
TypeError: expected string or bytes-like object
Edison
  • 870
  • 1
  • 13
  • 28
  • try adding `'content-type': 'multipart/form-data'` to your headers: `requests.post(...headers={'content-type': 'multipart/form-data'})` and adding `{'Expires': '0'}` to your `uploads`: `("profile.jpeg", image_file, {'Expires': '0'})` – It_is_Chris Oct 22 '21 at 15:49
  • Have tried that, didn't fix it. Thanks – Edison Oct 22 '21 at 16:00
  • Does this answer your question? [Upload Image using POST form data in Python-requests](https://stackoverflow.com/questions/29104107/upload-image-using-post-form-data-in-python-requests) – bwdm Oct 22 '21 at 16:02
  • Have you tried opening the file twice? The first entry that you give the your file like object to will exhaust the file - meaning that when the second entry tries to read the file, it'll hit eof at once. – MatsLindh Oct 22 '21 at 17:24
  • @bwdm No, It doesn't fix my issue. – Edison Oct 23 '21 at 21:49

0 Answers0