FastAPI Error: Expected UploadFile, received ‘str’

Updated: January 2, 2024 By: Guest Contributor Post a comment

Overview

While developing with FastAPI, handling file uploads can often be a source of confusion and errors, particularly the error message Expected UploadFile, received: <class 'str'>. This can occur when the endpoint expects a file object but receives a string instead. This post explains why this error happens and offers solutions to resolve it.

Solution 1: Correct Field Type

The most common reason for this error is incorrectly defining the field type for the incoming file. In FastAPI, file uploads should use the UploadFile type, provided by fastapi. When another type is mistakenly used, such as str, FastAPI will raise an error.

Steps to implement the solution:

  1. Locate the endpoint that handles the file upload in your FastAPI application code.
  2. Make sure the function parameter corresponding to the file upload is of type UploadFile from the fastapi module.
  3. Update the parameter to use File(...) as the default value, ensuring the file is read as multipart/form-data.

Example:

from fastapi import FastAPI, File, UploadFile

app = FastAPI()

@app.post("/upload")
def upload_file(file: UploadFile = File(...)):
    return {"filename": file.filename}

Advantages and limitations:

  • Advantage: This is the standard and intended way to handle file uploads in FastAPI; thus, it integrates seamlessly with the framework functionalities.
  • Limitation: It requires a clear understanding of FastAPI’s request model and data types.

Solution 2: Use Form Data for Strings

If you intend to receive both files and text fields in the same request, you must separately handle them using UploadFile for files and Form from fastapi for string fields. Mixing these up may lead to the discussed error.

Steps to implement the solution:

  1. Identify the endpoint in your code expecting a multipart request with files and string data.
  2. Ensure you are using UploadFile for file parameters and Form for string parameters.
  3. Remember to import Form from fastapi.

Example:

from fastapi import FastAPI, File, UploadFile, Form

app = FastAPI()

@app.post("/upload")
def upload_file(file: UploadFile = File(...), description: str = Form(...)):
  return {"filename": file.filename, "description": description}

Advantages and limitations:

  • Advantage: Allows handling of multiple types of data in a multipart form request correctly.
  • Limitation: It adds complexity to the endpoint, requiring a clear design of form handling.

Solution 3: Use Dependency Injection

You can refactor the endpoint using FastAPI’s dependency injection system to ensure proper file handling. This abstracts away some of the complexities involved in parsing request data

Steps to implement the solution:

  1. Create a dependency function that ensures you get an UploadFile object.
  2. Inject this dependency into your endpoint function.

Example:

from fastapi import FastAPI, File, UploadFile, Depends

app = FastAPI()

def file_uploader(file: UploadFile = File(...)):
    return file

@app.post("/upload")
def upload_file(file: UploadFile = Depends(file_uploader)):
    return {"filename": file.filename}

Advantages and limitations:

  • Advantage: Dependency injection can make code more modular and clear, separating concerns within your application.
  • Limitation: This approach might be overkill for simple use cases and can make tracing code more difficult for developers not familiar with dependency injection.

Conclusion

Understanding the cause of and solutions to the Expected UploadFile, received: <class 'str'> error in FastAPI is essential for developers handling file uploads. The three solutions provided can help you resolve the error, whether it stems from a typo or misuse of FastAPI’s request parsing features.