Ned U
Ned U

Reputation: 431

FastAPI File(s) must be put before form in function parameters

I have an endpoint that takes a file and a string parameter that I pass through a Form parameter. But I noticed when debugging that:

import uvicorn
from fastapi import FastAPI, File, Form

app = FastAPI()


@app.post('/test')
def test(test_item: str = Form(...), test_file: bytes = File(...)):
    return {
        "test_item": test_item,
        "test_file_len": len(test_file),
        "test_file_contents": test_file.decode('utf-8')
    }


if __name__ == '__main__':
    uvicorn.run(app, host="0.0.0.0", port=8000)

using this simple curl command with the test_file.txt having some text in it:

curl localhost:8000/test -X POST -F test_file=@"test_file.txt" -F test_item="test"

didn't work with this error:

{
    "detail": [
        {
            "loc": [
                "body",
                "test_file"
            ],
            "msg": "byte type expected",
            "type": "type_error.bytes"
        }
    ]
}

but interestingly, this did work:

import uvicorn
from fastapi import FastAPI, File, Form

app = FastAPI()


@app.post('/test')
def test(test_file: bytes = File(...), test_item: str = Form(...)):
    return {
        "test_item": test_item,
        "test_file_len": len(test_file),
        "test_file_contents": test_file.decode('utf-8')
    }


if __name__ == '__main__':
    uvicorn.run(app, host="0.0.0.0", port=8000)

The only difference being that you get the File before the Form element. Does anybody know why that would happen? Looks like it's required to upload files before forms. Maybe the file gets killed when Form parses the request body. I didn't see anything on the FastAPI documentation about this for Form and Files.

Upvotes: 6

Views: 973

Answers (1)

Thomasleveil
Thomasleveil

Reputation: 104155

This was working in FastAPI 0.43.0.

This is a regression introduced in https://github.com/tiangolo/fastapi/commit/ab2b86fe2ce8fe15e91aaec179438e24ff7b7ed0

Upvotes: 1

Related Questions