Sling Academy
Home/FastAPI/FastAPI Error: Expected UploadFile, received ‘str’

FastAPI Error: Expected UploadFile, received ‘str’

Last updated: January 02, 2024

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.

Next Article: FastAPI Error: 307 Temporary Redirect – Causes and Solutions

Previous Article: Fixing Common Swagger UI Errors in FastAPI

Series: Fixing Common Errors in FastAPI

FastAPI

You May Also Like

  • Popular useful built-in Jinja filters you should know
  • How to remove consecutive whitespace in rendered Jinja pages
  • How to format large numbers with thousand separators in Jinja template
  • How to format date time in Jinja templates
  • FastAPI + Jinja: How to create custom filters
  • How to pass variables from Python (FastAPI) to Jinja
  • How to decode Jinja response to string
  • How to create and use macros in Jinja
  • How to use namespace in Jinja
  • How to use if/ else in Jinja
  • How to use loops in Jinja
  • FastAPI + SQLAlchemy: Using cursor-based pagination
  • FastAPI: How to use macros in Jinja templates
  • Fixing Common Swagger UI Errors in FastAPI
  • FastAPI Error: 307 Temporary Redirect – Causes and Solutions
  • Resolving FastAPI ImportError: No Known Parent Package
  • FastAPI Error: No module named ‘pydantic_core._pydantic_core’
  • Resolving FastAPI 422 Error: Value is not a valid dict
  • Resolving the FastAPI Circular References Error