Fastapi File Upload
FastAPI provides two ways to handle file uploads: `File` and `UploadFile`, supporting single file uploads as well as mixed form and file uploads.
* * *
## Install Dependencies
File uploads also depend on `python-multipart`:
pip install python-multipart
* * *
## Using UploadFile
`UploadFile` is the recommended approach, providing richer file information access interfaces:
## Example
from fastapi import FastAPI, UploadFile
app = FastAPI()
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
# UploadFile provided properties and methods
return {
"filename": file.filename, # file name
"content_type": file.content_type, # file MIME type
"size": file.size, # file size (bytes)
}
`UploadFile` properties and methods:
| Property/Method | Type | Description |
| --- | --- | --- |
| `filename` | `str | None` | Original filename of the uploaded file |
| `content_type` | `str | None` | File MIME type (e.g., `image/png`) |
| `file` | `SpooledTemporaryFile` | File-like object, can read file content |
| `size` | `int | None` | File size (bytes) |
| `read()` | Method | Read file content as `bytes` |
| `write()` | Method | Write content to file |
| `seek()` | Method | Move file pointer position |
| `close()` | Method | Close file |
> `UploadFile` uses "SpooledTemporaryFile" to store file content. Small files are kept in memory, while large files are automatically written to disk, making it more memory-efficient than `bytes`.
* * *
## Using File to Receive File Content
`File` directly reads file content as `bytes`, suitable for small files:
## Example
from fastapi import FastAPI, File
app = FastAPI()
@app.post("/files/")
async def create_file(file: bytes = File()):
# file is the raw byte data of the file
return {"file_size": len(file)}
Comparison between `File` and `UploadFile`:
| Comparison Item | `File` | `UploadFile` |
| --- | --- | --- |
| Data type | `bytes` | File object |
| Memory usage | Entire file loaded into memory | Large files automatically written to disk |
| File information | None (only content) | Has filename, type, size |
| Applicable scenarios | Small files | Large files, scenarios requiring file information |
* * *
## Optional File Upload
Use default value `None` to make file upload optional:
## Example
from fastapi import FastAPI, UploadFile
app = FastAPI()
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile | None = None):
if not file:
return {"message": "No file uploaded"}
return {"filename": file.filename}
* * *
## Multiple File Upload
Use a list to receive multiple files:
## Example
from fastapi import FastAPI, UploadFile
app = FastAPI()
@app.post("/uploadfiles/")
async def create_upload_files(files: list):
return {"filenames": [file.filename for file in files]}
* * *
## Mixed Form and File Upload
You can receive form data and files in the same route:
## Example
from fastapi import FastAPI, File, UploadFile, Form
app = FastAPI()
@app.post("/items/")
async def create_item(
# Form fields
name: str = Form(...),
description: str | None = Form(None),
# File upload
file: UploadFile | None = None,
):
result = {"name": name, "description": description}
if file:
result = file.filename
return result
* * *
## Saving Uploaded Files
The following example shows how to save uploaded files to disk:
## Example
import shutil
from fastapi import FastAPI, UploadFile
app = FastAPI()
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
# Save uploaded file to specified path
with open(f"uploads/{file.filename}", "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
return {"filename": file.filename, "message": "File upload successful"}
> In actual projects, when uploading files, pay attention to: 1) Validate file type and size; 2) Use secure filenames (avoid path traversal attacks); 3) Limit upload directory permissions; 4) Use streaming for large files instead of reading all at once.
* * *
## Summary
- Recommended to use `UploadFile`, it saves more memory and provides rich file information
- `File` is suitable for small file scenarios, directly reading as `bytes`
- Use `list` to receive multiple file uploads
- Forms (`Form`) and files (`UploadFile`) can be used in the same route
- Pay attention to security when uploading files: validate file type, use secure filenames, limit size
YouTip