fastapi之上传文件

语言: CN / TW / HK

theme: healer-readable

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情

使用File实现文件上传

  • 使用Form表单上传文件,fastapi使用File获取上传的文件。
  • 指定了参数类型是bytes:file: bytes = File(),此时会将文件内容全部读取到内存,比较适合小文件。
  • 使用File需要提前安装 python-multipart

from fastapi import FastAPI, File  ​  app = FastAPI()  ​  ​  @app.post("/files/")  async def create_file(file: bytes = File()):      return {"file_size": len(file)}

  • 只要在路径操作函数中声明了变量的类型是bytes且使用了File,则fastapi会将上传文件的内容全部去读到参数中。

使用UploadFile实现文件上传

  • 对于大文件,不适合将文件内容全部读取到内存中,此时使用UploadFile

from fastapi import FastAPI, UploadFile  ​  app = FastAPI()  ​  ​  @app.post("/uploadfile/")  async def create_upload_file(file: UploadFile):      return {"filename": file.filename}

  • bytes相比,使用UploadFile有如下好处:

    • 不需要在使用File()作为路径操作函数中参数的默认值
    • 不会把文件内容全部加载到内存中,而是批量读取一定量的数据,边读边存硬盘。
    • 可以获取文件的元数据。
    • 该类型的变量可以像文件变量一样操作。

UploadFile的属性

  • filename:类型是str,用来获取文件的名字,比如:myimage.png
  • content_type: 类型是str, 用来获取文件的类型,比如:image/png
  • file: 类文件对象,是一个标准的python文件对象

除了这四个基础属性外,UploadFile还有三个async方法:

  • write, 将str或者bytes写到文件中
  • read: 读文件
  • seek: 移动光标
  • close: 关闭文件

# 获取文件内容  contents = await myfile.read()

设置上传文件是可选的

  • 设置默认值是None即可

from typing import Union  ​  from fastapi import FastAPI, File, UploadFile  ​  app = FastAPI()  ​  ​  @app.post("/files/")  async def create_file(file: Union[bytes, None] = File(default=None)):      if not file:          return {"message": "No file sent"}      else:          return {"file_size": len(file)}  ​  ​  @app.post("/uploadfile/")  async def create_upload_file(file: Union[UploadFile, None] = None):      if not file:          return {"message": "No upload file sent"}      else:          return {"filename": file.filename}

上传多个文件

  • 参数的参数的类型是列表:列表元素是bytes或者UploadFile

from typing import List  ​  from fastapi import FastAPI, File, UploadFile  ​  app = FastAPI()  ​  ​  @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]):      return {"filenames": [file.filename for file in files]}

「其他文章」