1. 程式人生 > 其它 >FastAPI(24)- 詳解 File,上傳檔案

FastAPI(24)- 詳解 File,上傳檔案

FastAPI(24)- 詳解 File,上傳檔案

前言

可以使用 FastAPI 提供的 File 定義客戶端要上傳的檔案

學習 File 前最好先學習 Form:https://www.cnblogs.com/poloyy/p/15311533.html

安裝 python-multipart

要用 File,需要先安裝這個庫

pip install python-multipart

FIle

File 是繼承 Form,所以可以定義和 Form 相同的元資料以及額外的驗證

上傳單個檔案的栗子

#!usr/bin/env python
# -*- coding:utf-8 _*-
""" # author: 小菠蘿測試筆記 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/9/22 9:52 上午 # file: 21_File.py """ import uvicorn from fastapi import FastAPI, File, UploadFile app = FastAPI() # file 引數型別是位元組 bytes @app.post("/files/") async def create_file(file: bytes = File(...)): return {"file_size": len
(file)} # file 引數型別是 UploadFile @app.post("/uploadfile/") async def create_upload_file(file: UploadFile = File(...)): result = { "filename": file.filename, "content-type": file.content_type, "read": await file.read() } return result if __name__ == "__main__": uvicorn.run(app="21_File:app"
, host="127.0.0.1", port=8080, reload=True, debug=True)

重點

  • 因為 UploadFile 物件提供的方法都是 async 非同步的,所以呼叫的時候都要加 await 比如await file.read()(後面會詳解 async/await )
  • 當使用非同步方法時,FastAPI 線上程池中執行檔案方法並等待它們

不加 await 呼叫 async 方法會報錯

    raise ValueError(errors)
ValueError: [TypeError("'coroutine' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]
WARNING:  StatReload detected file change in '21_File.py'. Reloading...

file: bytes 的請求結果

file: UploadFile 的請求結果

檢視 Swagger API 文件

這樣就可以直接在 Swagger API 文件上測試上傳檔案功能啦

file: bytes

  • FastAPI 將會讀取檔案,接收到的內容就是檔案位元組
  • 會將整個內容儲存在記憶體中,更適用於小檔案

file: UploadFile

FastAPI 的 UploadFile 直接繼承了 Starlette 的 UploadFile,但增加了一些必要的部分,使其與 Pydantic 和 FastAPI 的其他部分相容

UploadFile 相比 bytes 的優勢

  • 儲存在記憶體中的檔案達到最大大小限制,超過此限制後,它將儲存在磁碟中,可以很好地處理大檔案,如影象、視訊、大型二進位制檔案等,而不會消耗所有記憶體
  • 可以從上傳的檔案中獲取元資料
  • 有一個類似檔案的 async 非同步介面
  • 它公開了一個 Python SpooledTemporaryFile 物件,可以將它傳遞給其他需要檔案的庫

UploadFile 具有以下屬性

  • filename:str,上傳的原始檔名,例如myimage.jpg
  • content_type:str,包含 content-type(MIME type / media type),例如image/jpeg
  • file:一個 SpooledTemporaryFile(一個類似檔案的物件)。 這是實際的 Python 檔案,可以將其直接傳遞給其他需要“類檔案”物件的函式或庫

UploadFIle 具有以下 async 非同步方法

  • write(data):寫入data ( str或 bytes ) 到檔案
  • read(size):讀取檔案的 size (int) 個位元組/字元
  • seek(offset):轉到檔案中的位元組位置 offset(int),如:await myfile.seek(0)將轉到檔案的開頭
  • close():關閉檔案

上傳多個檔案的栗子

from typing import List


@app.post("/files/")
async def create_files(files: List[bytes] = File(...)):
    return {"file_sizes": [len(file) for file in files]}


@app.post("/uploadfiles/")
async def create_upload_files(files: List[UploadFile] = File(...)):
    return {"filenames": [file.filename for file in files]}

正確傳參的請求結果

檢視 SwaggerAPI 文件