FastAPI StreamingResponse 與 FileResponse
當處理大型檔案或需要即時回傳資料時,我們不能一次將所有內容讀入記憶體再回傳,這時就需要使用串流 (Streaming) 或專用的檔案回應 (File Response)。
StreamingResponse (串流回應)
StreamingResponse 接受一個生成器 (Generator) 或非同步生成器。它會邊讀邊傳,非常適合處理大型 CSV、日誌檔案或即時產生的內容。
import io
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
app = FastAPI()
def fake_video_streamer():
for i in range(10):
yield b"some fake video bytes"
@app.get("/video")
async def main():
return StreamingResponse(fake_video_streamer(), media_type="video/mp4")
傳回大型內容
範例:建立一個虛擬的大型檔案。
def generate_large_data():
for i in range(1000):
yield f"some data line {i}\n"
@app.get("/large-data")
async def get_large_data():
return StreamingResponse(generate_large_data())
FileResponse (檔案下載)
FileResponse 是提供檔案服務的最佳方式。它能有效率地回傳磁碟上的檔案,並處理 HTTP 的範圍請求 (Range requests, 常用於影音播放)。
from fastapi import FastAPI
from fastapi.responses import FileResponse
app = FastAPI()
@app.get("/download/{file_id}")
async def download_file(file_id: str):
file_path = f"files/{file_id}.pdf"
# media_type 會自動判斷,也可以手動指定
# filename 設定後,瀏覽器會將其視為下載檔案
return FileResponse(
path=file_path,
filename=f"user_guide_{file_id}.pdf"
)
參數說明
path: 檔案在伺服器磁碟上的完整路徑。filename: 瀏覽器下載時顯示的預設檔名。media_type: MIME 類型。如果沒設定,FastAPI 會嘗試根據副檔名判斷。
總結
StreamingResponse: 用於串流回傳資料,避免佔用大量記憶體。FileResponse: 用於將預先存在的檔案回傳給使用者。- 這兩種回應方式能極大提升系統在處理大數據時的效率與穩定性。