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]}

 

正確傳參的請求結果

 

查看 Swagger API 文檔

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM