Python使用FastAPI實(shí)現(xiàn)文件上傳接口的最佳方案
引言
在現(xiàn)代 Web 應(yīng)用中,文件上傳幾乎是所有系統(tǒng)的標(biāo)配功能:無(wú)論是頭像上傳、文檔提交,還是批量導(dǎo)入數(shù)據(jù)。 本文將詳細(xì)介紹如何使用 FastAPI 快速、高效地實(shí)現(xiàn)文件上傳接口,并給出進(jìn)階場(chǎng)景(如多文件上傳、限制文件大小、異步保存文件等)的最佳實(shí)踐。
一、FastAPI 文件上傳的核心機(jī)制
FastAPI 內(nèi)置了強(qiáng)大的文件上傳支持,基于 starlette 的 UploadFile 對(duì)象實(shí)現(xiàn)。 它的底層使用 Python 的異步文件處理機(jī)制,性能優(yōu)于傳統(tǒng)的同步文件讀取。
在 FastAPI 中,文件上傳參數(shù)可以通過(guò)以下兩種類型聲明:
File(...):用于聲明表單中的文件字段。UploadFile:封裝上傳文件對(duì)象,包含filename、content_type、file等屬性。
二、單文件上傳示例
先看一個(gè)最簡(jiǎn)單的例子:上傳一個(gè)文件并保存到服務(wù)器。
from fastapi import FastAPI, File, UploadFile
import shutil
import os
app = FastAPI()
UPLOAD_DIR = "uploads"
os.makedirs(UPLOAD_DIR, exist_ok=True)
@app.post("/upload/")
async def upload_file(file: UploadFile = File(...)):
file_path = os.path.join(UPLOAD_DIR, file.filename)
# 保存文件
with open(file_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
return {"filename": file.filename, "content_type": file.content_type}
說(shuō)明:
UploadFile是一個(gè)異步文件對(duì)象(底層為SpooledTemporaryFile)。file.file是標(biāo)準(zhǔn)的類文件對(duì)象,可直接讀寫(xiě)。shutil.copyfileobj()用于高效復(fù)制二進(jìn)制數(shù)據(jù)流。
訪問(wèn)接口:
curl -F "file=@example.png" http://127.0.0.1:8000/upload/
返回:
{
"filename": "example.png",
"content_type": "image/png"
}
三、多文件上傳
FastAPI 支持一次性上傳多個(gè)文件,只需將類型改為 List[UploadFile]:
from typing import List
from fastapi import UploadFile, File
@app.post("/upload/multiple/")
async def upload_multiple(files: List[UploadFile] = File(...)):
saved_files = []
for file in files:
file_path = os.path.join(UPLOAD_DIR, file.filename)
with open(file_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
saved_files.append(file.filename)
return {"uploaded_files": saved_files}
上傳多個(gè)文件:
curl -F "files=@a.png" -F "files=@b.jpg" http://127.0.0.1:8000/upload/multiple/
四、異步寫(xiě)入與性能優(yōu)化
上面的寫(xiě)入方式是同步的。如果文件較大,可能阻塞事件循環(huán)。 可以使用異步文件寫(xiě)入方式提升性能(推薦在高并發(fā)或大文件場(chǎng)景):
import aiofiles
@app.post("/upload/async/")
async def upload_file_async(file: UploadFile = File(...)):
file_path = os.path.join(UPLOAD_DIR, file.filename)
async with aiofiles.open(file_path, 'wb') as out_file:
while content := await file.read(1024):
await out_file.write(content)
await file.close()
return {"filename": file.filename}
提示:aiofiles 是一個(gè)異步文件操作庫(kù),可與 FastAPI 無(wú)縫協(xié)作。
安裝依賴:
pip install aiofiles
五、限制上傳文件大小與類型
限制大小(Nginx / Uvicorn 層)
FastAPI 本身不限制文件大小。建議在 網(wǎng)關(guān)層(如 Nginx)限制上傳大小:
client_max_body_size 10M;
校驗(yàn)文件類型
你可以在接口中檢查文件類型:
ALLOWED_TYPES = ["image/png", "image/jpeg"]
@app.post("/upload/image/")
async def upload_image(file: UploadFile = File(...)):
if file.content_type not in ALLOWED_TYPES:
return {"error": "Unsupported file type"}
# 繼續(xù)保存邏輯...
return {"filename": file.filename}
六、結(jié)合 Pydantic 校驗(yàn)表單 + 文件混合上傳
在實(shí)際業(yè)務(wù)中,文件上傳通常伴隨表單數(shù)據(jù)(如用戶ID、描述等)。 FastAPI 支持文件與表單字段混合處理:
from fastapi import Form
@app.post("/upload/with_form/")
async def upload_with_form(
user_id: int = Form(...),
description: str = Form(""),
file: UploadFile = File(...)
):
file_path = os.path.join(UPLOAD_DIR, file.filename)
with open(file_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
return {"user_id": user_id, "description": description, "filename": file.filename}
七、實(shí)際應(yīng)用場(chǎng)景建議
| 場(chǎng)景 | 推薦方案 |
|---|---|
| 上傳頭像、小文件 | 使用 UploadFile + 異步保存 |
| 批量導(dǎo)入Excel、CSV | 使用 aiofiles 逐行讀取,解析后入庫(kù) |
| 上傳到云存儲(chǔ)(如OSS、S3) | 直接使用 boto3 或 oss2 SDK,將文件流轉(zhuǎn)存至云端 |
| 接口網(wǎng)關(guān)安全限制 | 使用 Nginx / Traefik 限制文件大小和MIME類型 |
| 文件命名沖突 | 使用 UUID 或時(shí)間戳重命名文件 |
八、總結(jié)
FastAPI 讓文件上傳的實(shí)現(xiàn)變得異常簡(jiǎn)單且高效。 通過(guò)本文的實(shí)踐,你已經(jīng)學(xué)會(huì)了:
- ? 基本文件上傳與保存
- ? 多文件與異步寫(xiě)入
- ? 文件類型與大小校驗(yàn)
- ? 表單與文件混合上傳
- ? 性能與安全最佳實(shí)踐
接下來(lái),你可以嘗試:
- 實(shí)現(xiàn)一個(gè)圖片上傳 + 自動(dòng)壓縮接口
- 結(jié)合 JWT 用戶認(rèn)證,構(gòu)建安全的文件上傳系統(tǒng)
- 將文件元數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫(kù)中,實(shí)現(xiàn)可追蹤的文件管理系統(tǒng)
建議
在實(shí)際項(xiàng)目中,推薦將文件上傳邏輯封裝為獨(dú)立的服務(wù)模塊(如 services/file_service.py), 結(jié)合日志(如 loguru)和異常處理中間件,讓系統(tǒng)更加可維護(hù)與可追蹤。
以上就是Python使用FastAPI實(shí)現(xiàn)文件上傳接口的最佳方案的詳細(xì)內(nèi)容,更多關(guān)于Python FastAPI文件上傳接口的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python打印特殊符號(hào)及對(duì)應(yīng)編碼解析
這篇文章主要介紹了Python打印特殊符號(hào)及對(duì)應(yīng)編碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
python發(fā)送byte數(shù)據(jù)組到tcp的server問(wèn)題
這篇文章主要介紹了python發(fā)送byte數(shù)據(jù)組到tcp的server問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
Python英文單詞大小寫(xiě)轉(zhuǎn)換常用方法示例
這篇文章主要為大家介紹了Python英文單詞大小寫(xiě)轉(zhuǎn)換常用方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Python使用concurrent.futures模塊實(shí)現(xiàn)多進(jìn)程多線程編程
Python的concurrent.futures模塊可以很方便的實(shí)現(xiàn)多進(jìn)程、多線程運(yùn)行,減少了多進(jìn)程帶來(lái)的的同步和共享數(shù)據(jù)問(wèn)題,下面就跟隨小編一起了解一下concurrent.futures模塊的具體使用吧2023-12-12
Django values()和value_list()的使用
這篇文章主要介紹了Django values()和value_list()的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03
python PyAUtoGUI庫(kù)實(shí)現(xiàn)自動(dòng)化控制鼠標(biāo)鍵盤(pán)
這篇文章主要介紹了python PyAUtoGUI庫(kù)實(shí)現(xiàn)自動(dòng)化控制鼠標(biāo)鍵盤(pán),幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-09-09
利用Python查看微信共同好友功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了利用Python查看微信共同好友功能的實(shí)現(xiàn)代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-04-04

