Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File upload using FastAPI returns error 422

I am using the example from the official documentation: https://fastapi.tiangolo.com/tutorial/request-files/#import-file

Server code:

@app.post("/uploadfile")
async def create_upload_file(data: UploadFile = File(...)):
    print("> uploaded file:",data.filename)
    return {"filename": data.filename}

Client code:

files = {'upload_file': open('config.txt', 'rb')}
resp = requests.post(
        url = URL,
        files = files)
print(resp.json())

The problem is that the server always responds with error 422:

{'detail': [{'loc': ['body', 'data'], 'msg': 'field required', 'type': 'value_error.missing'}]}

I am using Python 3 on both server and client and the python-multipart package is already installed.

Can someone please tell me what I am doing wrong, what am I missing, how should I fix the code?

Any hints are much appreciated.

like image 623
stev Avatar asked Sep 16 '25 00:09

stev


2 Answers

On client side you should use the same name given for the parameter on server side, when adding the file. In your case, that parameter is called data, as shown below:

@app.post('/uploadfile')
async def create_upload_file(data: UploadFile = File(...)):
                             ^^^^

Hence, you should replace upload_file with data on client side, as shown below:

url = 'http://127.0.0.1:8000/uploadfile'
files = {'data': open('config.txt', 'rb')}
r = requests.post(url=url, files=files)

More details and examples on how to upload file(s) using Python requests and FastAPI can be found in this answer, as well as here, here and here.

like image 177
Chris Avatar answered Sep 18 '25 15:09

Chris


Well, I just realized my error (which is not immediately obvious for newbies like me :))

The parameter you pass on client side ('upload_file')

files = {'upload_file': open('config.txt', 'rb')}

must match the parameter on the server side ('data'):

async def create_upload_file(data: UploadFile = File(...)):

So in order to work I had to rename on client side 'upload_file' to 'data':

files = {'data': open('config.txt', 'rb')} # renamed 'upload_file' to 'data'

That's it. Hopefully this helps some others as well.

like image 20
stev Avatar answered Sep 18 '25 14:09

stev