1

Code snippet for file upload

router = APIRouter()
@router.post("/uploadfiles/")
async def create_upload_files(files: List[UploadFile] = File(...)):

    for file in files:
        file_name = os.getcwd()+"/uploads/"+file.filename.replace(" ", "-")
        with open(file_name,'wb+') as f:
            f.write(file.file.read())
            f.close()

    return {"filenames": [file.filename for file in files]}

The code for uploading multiple files using the requests module. All the files in the input directory are to be uploaded

doc_list = os.listdir(input_dir)
files = []
for doc in doc_list:
    files.append(UploadFile(filename = doc, file = open(input_dir + doc)))

r = requests.post('http://127.0.0.1:8080/uploadfiles/', files=files)

The above code throws an error in the requests.post line. Part of the error traceback is given below

F:\Anaconda\Anaconda3\envs\deep\lib\site-packages\requests\models.py in _encode_files(files, data)
    139                          v.encode('utf-8') if isinstance(v, str) else v))
    140 
--> 141         for (k, v) in files:
    142             # support for explicit filename
    143             ft = None

TypeError: 'UploadFile' object is not iterable

I have tried uploading the files using the below code

doc_list = os.listdir(input_dir)
files = []
for doc in doc_list[:50]:
    files.append((input_dir + doc, open(input_dir + doc)))
    #files.append({"file_name" : doc, "file" : open(input_dir + doc, "rb")})
r = requests.post('http://127.0.0.1:8080/uploadfiles/', files=files)

Sending a list of tuples gives 400 Bad Request and sending a list of dictionary (commented line) gave 422 Unprocessable Entity

Hari Krishnan
  • 2,049
  • 2
  • 18
  • 29
  • `UploadFile` is meant to _represent an uploaded file_ on the FastAPI server side. It's not mean to be used for posting files to a resource with requests. See https://stackoverflow.com/a/20769921/137650 for an example of how to upload multiple files in a single call to `requests`. – MatsLindh Oct 26 '21 at 13:18
  • I tried implementing the answer that you have tagged in your comment. Now it throws a `400 Bad Request` from the server side – Hari Krishnan Oct 26 '21 at 13:30
  • Then the error message given with the response (and with the error on the serveri side) will give you more context for what the cause of the error is. – MatsLindh Oct 26 '21 at 16:16
  • But all I get from the error is `422 Unprocessable Entity`. There is no other error message in the response or any traceback. If there was more information on the error message I could have gotten the context. – Hari Krishnan Oct 26 '21 at 16:30
  • If you look at the actual response from the server, FastAPI includes a JSON message describing which fields are missing or failing validation. It usually includes a `loc` key that indicates which of the required fields are missing. For example, the FastAPI parameter seems to be named `files` and neither of the examples you've given follows the syntax given in the linked answer with `('key_name', ('filename', open('actual_file.png', 'rb'), 'content/type')` for each entry. Since you expect a `List` named `files`, you'll need to have multiple tuples with `files` as the key name. – MatsLindh Oct 26 '21 at 17:16
  • Sorry for the misunderstanding, This is the response I got `{"detail":[{"loc":["body","files"],"msg":"field required","type":"value_error.missing"}]}` – Hari Krishnan Oct 26 '21 at 17:19
  • @MatsLindh, Thanks changing the syntax to `('key_name', ('filename', open('actual_file.png', 'rb'), 'content/type')` solved the issue – Hari Krishnan Oct 26 '21 at 17:34

0 Answers0