試試 FastAPI 打造高效上傳/下載接口!
在現代 Web 項目中,文件上傳與下載幾乎是所有后端開發者都繞不開的基礎功能,比如用戶頭像上傳、Excel 報表導出、圖片預覽等。
而你可能還在使用傳統的 Flask、Django 來處理這些接口 —— 今天我帶你用 FastAPI 實現一個更高效、更清晰的文件上傳與下載服務。
我們將實現以下功能:
- 支持上傳任意文件
- 自動生成唯一文件名,防止覆蓋沖突
- 返回下載地址供前端訪問
- 提供下載接口
- 代碼結構清晰、可擴展性強
文件上傳與下載完整實現
我們先創建一個 api/file.py 文件模塊,封裝上傳和下載接口。
完整代碼如下:
import os
import uuid
from fastapi import APIRouter, File, UploadFile, HTTPException
from starlette.responses import FileResponse
# 模擬統一響應格式(可根據項目實際結構更換)
class Result:
@staticmethod
def ok(data):
return {"code": 0, "msg": "success", "data": data}
# 創建路由對象
router = APIRouter(prefix="/file", tags=["文件上傳下載"])
# 文件保存路徑
UPLOAD_DIRECTORY = "uploads"
os.makedirs(UPLOAD_DIRECTORY, exist_ok=True)
@router.post("/upload", summary="上傳文件")
async def upload_file(file: UploadFile = File(...)):
"""
上傳文件,返回唯一 key 和下載鏈接。
"""
# 提取后綴,拼接唯一 key
file_extension = os.path.splitext(file.filename)[1]
file_key = f"{uuid.uuid4().hex}{file_extension}"
file_path = os.path.join(UPLOAD_DIRECTORY, file_key)
try:
# 寫入磁盤
with open(file_path, "wb") as f:
content = await file.read()
f.write(content)
except Exception as e:
raise HTTPException(status_code=500, detail=f"文件保存失敗: {str(e)}")
file_url = f"http://localhost:8800/file/download/{file_key}"
return Result.ok({
"key": file_key,
"url": file_url
})
@router.get("/download/{key}", summary="下載文件")
async def download_file(key: str):
"""
根據 key 下載文件。
"""
file_path = os.path.join(UPLOAD_DIRECTORY, key)
if not os.path.exists(file_path):
raise HTTPException(status_code=404, detail="文件不存在")
return FileResponse(file_path, filename=key)
主程序注冊路由
在你的 main.py 中注冊路由模塊:
from fastapi import FastAPI
from api import file
app = FastAPI()
app.include_router(file.router)
啟動服務:
uvicorn main:app --reload --port 8800
測試效果
(1) 上傳文件
可以通過 Postman 或 curl 測試上傳:
curl -F "file=@test.png" http://localhost:8800/file/upload
返回:
{
"code": 0,
"msg": "success",
"data": {
"key": "aa3121df01954a0c830c591f317f5f59.png",
"url": "http://localhost:8800/file/download/aa3121df01954a0c830c591f317f5f59.png"
}
}
(2) 下載文件
瀏覽器訪問返回的 url 即可直接下載文件。
總結
FastAPI 提供了原生支持異步文件讀取和返回,非常適合構建現代 Web API。相比 Flask、Django 等傳統框架,開發體驗更現代化,性能也更高。
如果你還沒在項目中使用 FastAPI,這可能是一個非常合適的起點。短短幾十行代碼,就可以實現一個高效、優雅的文件上傳下載接口。