1

I'm trying to test uploading a file to FastApi, but I keep getting 422 Validation Error. The file upload works in OpenApi interface, but not with the test below.

The router:

@router.post("/files")
def file_contents(files: List[UploadFile]):
    return someprocessing(files)

The test (using TestClient from FastApi):

response = client.post(
    url="/files",
    files={"files": ("file.xlsx", open("./test_files/file.xlsx", "rb"))},
    headers={**auth_headers, **{"Content-Type": "multipart/form-data"}},
)

The error:

{"detail":[{"loc":["body"],"msg":"value is not a valid dict","type":"type_error.dict"}]}

Update: All good I was sending files to a different url...

Alin Climente
  • 117
  • 1
  • 2
  • 14

2 Answers2

3

I guess the problem here is with passed content type, this example works:

from typing import List

from fastapi import FastAPI, UploadFile

app = FastAPI()


@app.post("/files")
def file_contents(files: List[UploadFile]):
    return {"filenames": [file.filename for file in files]}

tests:

from fastapi.testclient import TestClient

from fast_example import app

client = TestClient(app)
files = [('files', open('so.py', 'rb')), ('files', open('main.py', 'rb'))]
response = client.post(
    url="/files",
    files=files
)

print(response.json())
# {'filenames': ['so.py', 'main.py']}
funnydman
  • 9,083
  • 4
  • 40
  • 55
0

This code works for me, I am sending multiple csv's to an endpoint which receives a list of UploadFile

import json
import uvicorn
from fastapi.testclient import TestClient
from dotenv import load_dotenv

load_dotenv()
from main import app

client = TestClient(app)


def test_user_profiles_csv():
files = [("files", open("profiles_csv_1.csv", "rb")),
         ("files", open("profiles_csv_2.csv", "rb"))]

response = client.post(
    "/api/v1/profiles/csv",
    files=files,
    headers={"Authorization": f"Bearer {get_access_token()}"},
)
assert response.status_code == 201

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
Aldo Matus
  • 61
  • 6