DEV Community

Cover image for FastAPI for AI Engineers - Part 8: Uploading Files with FastAPI
Ananya S
Ananya S

Posted on

FastAPI for AI Engineers - Part 8: Uploading Files with FastAPI

In the previous article, we learned how to secure our APIs using JWT Authentication and protect routes from unauthorized access.

Now let's explore another feature used in almost every AI application—file uploads.

If you've built applications like ChatGPT, document Q&A systems, resume analyzers, legal contract reviewers, or medical report analyzers, one thing is common across all of them:

The user uploads a file.

Without file uploads, there is nothing for the AI model to process.

If you haven't read the previous article, check it out first to continue the series:
Protecting routes with JWT Tokens


Why Do We Need File Uploads?

Consider some popular AI applications:

  • ChatGPT allows you to upload PDFs and images.
  • Resume analyzers require your resume.
  • Legal AI assistants analyze contracts.
  • Medical AI systems analyze lab reports.
  • RAG applications build knowledge bases from documents.

The workflow usually looks like this:

  User
   │
   ▼
Upload File
   │
   ▼
FastAPI
   │
   ▼
Save / Read File
   │
   ▼
Process using AI
Enter fullscreen mode Exit fullscreen mode

FastAPI makes uploading files extremely simple.


Installing Required Package

FastAPI uses python-multipart to process uploaded files.

Install it using:

pip install python-multipart
Enter fullscreen mode Exit fullscreen mode

Your First File Upload API

FastAPI provides two important classes:

  • File
  • UploadFile

Let's import them.

from fastapi import FastAPI, File, UploadFile

app = FastAPI()
Enter fullscreen mode Exit fullscreen mode

Creating the Upload Endpoint

@app.post("/upload")
def upload_file(file: UploadFile):

    return {
        "filename": file.filename
    }
Enter fullscreen mode Exit fullscreen mode

Run the application.

Open Swagger UI.

Click POST /upload.

You'll notice FastAPI automatically provides a file picker.

Upload a file.

Showing FastAPI docs for upload file

Response:

{
    "filename": "resume.pdf"
}
Enter fullscreen mode Exit fullscreen mode

Our API successfully received the uploaded file.


Understanding UploadFile

You might wonder:

Why didn't we simply use a string or bytes?

FastAPI provides the UploadFile class because it contains useful information about the uploaded file.

Some commonly used attributes are:

file.filename
Enter fullscreen mode Exit fullscreen mode

Returns:

resume.pdf
Enter fullscreen mode Exit fullscreen mode
file.content_type
Enter fullscreen mode Exit fullscreen mode

Returns:

application/pdf
Enter fullscreen mode Exit fullscreen mode
await file.read()
Enter fullscreen mode Exit fullscreen mode

Reads the file contents.

These attributes become extremely useful when building AI applications.


Reading File Contents

Suppose we want to know how many bytes were uploaded.

@app.post("/upload")
async def upload_file(file: UploadFile):

    contents = await file.read()

    return {
        "filename": file.filename,
        "size": len(contents)
    }
Enter fullscreen mode Exit fullscreen mode

Example response:

{
    "filename": "contract.pdf",
    "size": 254321
}
Enter fullscreen mode Exit fullscreen mode

Showing pdf upload with name

Showing pdf name and bytes of pdf

Notice that we changed the function to:

async def
Enter fullscreen mode Exit fullscreen mode

This is because file.read() is an asynchronous operation.


Saving Uploaded Files

In many applications, we don't just read the file.

We save it for later processing.

@app.post("/upload")
async def upload_file(file: UploadFile):

    contents = await file.read()

    with open(file.filename, "wb") as f:
        f.write(contents)

    return {
        "message": "File uploaded successfully."
    }
Enter fullscreen mode Exit fullscreen mode

Uploading pdf

PDF upload successful
Let's understand the code.

contents = await file.read()
Enter fullscreen mode Exit fullscreen mode

Reads the uploaded file into memory.

with open(file.filename, "wb")
Enter fullscreen mode Exit fullscreen mode

Creates a new file.

The "wb" mode means:

  • w → Write
  • b → Binary mode

Binary mode is important because PDFs, images, Word documents, and many other files are not plain text.

f.write(contents)
Enter fullscreen mode Exit fullscreen mode

Writes the uploaded data to disk.


AI Workflow Example

Suppose a user uploads a legal contract.

   contract.pdf
        │
        ▼
FastAPI Upload Endpoint
        │
        ▼
     Save PDF
        │
        ▼
    Extract Text
        │
        ▼
Create Embeddings
        │
        ▼
Store in Vector Database
        │
        ▼
   Ask Questions
Enter fullscreen mode Exit fullscreen mode

This is the same workflow followed by many Retrieval-Augmented Generation (RAG) applications.

Similarly,

Resume Analyzer:

Resume.pdf
      │
      ▼
Extract Text
      │
      ▼
Skill Extraction
      │
      ▼
  ATS Score
Enter fullscreen mode Exit fullscreen mode

Medical Report Analyzer:

Blood_Report.pdf
        │
        ▼
OCR / Text Extraction
        │
        ▼
  LLM Analysis
        │
        ▼
  Health Summary
Enter fullscreen mode Exit fullscreen mode

File uploads are the entry point for almost every document-based AI application.


UploadFile vs bytes

FastAPI also allows uploading files as raw bytes.

@app.post("/upload")
async def upload(file: bytes = File()):

    return {
        "size": len(file)
    }
Enter fullscreen mode Exit fullscreen mode

Although this works, it is rarely used for large files.

UploadFile is generally preferred because:

  • It provides metadata such as filename and content type.
  • It is optimized for larger uploads.
  • It is more memory efficient.

For most production applications, UploadFile is the recommended choice.


Complete Example

from fastapi import FastAPI, UploadFile

app = FastAPI()

@app.post("/upload")
async def upload_file(file: UploadFile):

    contents = await file.read()

    with open(file.filename, "wb") as f:
        f.write(contents)

    return {
        "filename": file.filename,
        "content_type": file.content_type,
        "size": len(contents),
        "message": "Upload Successful"
    }
Enter fullscreen mode Exit fullscreen mode

Workflow Recap

User Uploads File
        │
        ▼
FastAPI Receives Upload
        │
        ▼
UploadFile Object Created
        │
        ▼
    Read File
        │
        ▼
    Save File
        │
        ▼
AI Processing Begins
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

Uploading files is one of the most important capabilities of modern AI backends.

Whether you're building a chatbot over PDFs, a resume analyzer, a legal contract assistant, or a medical report analyzer, every application begins with accepting user files.

Today we learned how to:

  • Upload files using FastAPI
  • Understand the UploadFile object
  • Read uploaded files
  • Save files locally
  • Understand where file uploads fit into AI workflows

It's been some time since I've uploaded. We will continue with our FastAPI series in the upcoming posts.

Top comments (1)

Collapse
 
zeroshotanu profile image
Ananya S

Do comment down any doubts you have, or which is the next topic you would like me to take?