FastAPI入门:表单数据、表单模型、请求文件、请求表单与文件

表单数据

接收的不是 JSON,而是表单字段时,要使用 Form。要使用表单,需预先安装 python-multipart。

bash 复制代码
pip install python-multipart

创建表单(Form)参数的方式与 Body 和 Query 一样

python 复制代码
from fastapi import FastAPI, Form

app = FastAPI()


@app.post("/login/")
async def login(username: str = Form(), password: str = Form()):
    return {"username": username}

表单模型

使用pydantic声明一个数据模型,并在请求中声明它为Form()对象

python 复制代码
from fastapi import FastAPI, Form
from pydantic import BaseModel
from typing import Annotated

app = FastAPI()

class FormData(BaseModel):
    username: str
    password: str
    
@app.post("/login")
async def login(data: Annotated[FormData, Form()]):
    return data

禁止额外的表单字段

使用 Pydantic 的模型配置来禁止( forbid )任何额外( extra )字段

python 复制代码
 model_config = {"extra": "forbid"}

请求文件

File 用于定义客户端的上传文件

创建文件(File)参数的方式与 Body 和 Form 一样。如果把路径操作函数参数的类型声明为 bytes,FastAPI 将以 bytes 形式读取和接收文件内容。

这种方式把文件的所有内容都存储在内存里,适用于小型文件

python 复制代码
from fastapi import FastAPI, File, UploadFile


app = FastAPI()

@app.post("/files")
async def create_file(file: bytes = File()):
    return {"file_size": len(file)}

UploadFile 与 bytes 相比有更多优势:

  • 使用 spooled 文件:
    • 存储在内存的文件超出最大上限时,FastAPI 会把文件存入磁盘;
  • 这种方式更适于处理图像、视频、二进制文件等大型文件,好处是不会占用所有内存;
  • 可获取上传文件的元数据;
  • 自带 file-like async 接口;
  • 暴露的 Python SpooledTemporaryFile 对象,可直接传递给其他预期「file-like」对象的库。

UploadFile 的属性如下:##

  • filename:上传文件名字符串(str),例如, myimage.jpg;
  • content_type:内容类型(MIME 类型 / 媒体类型)字符串(str),例如,image/jpeg;
  • file: SpooledTemporaryFile( file-like 对象)。其实就是 Python文件,可直接传递给其他预期 file-like 对象的函数或支持库。

UploadFile 支持以下 async 方法,(使用内部 SpooledTemporaryFile)可调用相应的文件方法。

  • write(data):把 data (str 或 bytes)写入文件;
  • read(size):按指定数量的字节或字符(size (int))读取文件内容;
  • seek(offset):移动至文件 offset (int)字节处的位置;
    • 例如,await myfile.seek(0) 移动到文件开头;
    • 执行 await myfile.read() 后,需再次读取已读取内容时,这种方法特别好用;
  • close():关闭文件。

可选文件上传

可以通过使用标准类型注解并将 None 作为默认值的方式将一个文件参数设为可选

python 复制代码
async def create_file(file: bytes | None = File(default=None)):

带有额外元数据的 UploadFile

也可以将 File() 与 UploadFile 一起使用,例如,设置额外的元数据

python 复制代码
from fastapi import FastAPI, File, UploadFile

app = FastAPI()


@app.post("/files/")
async def create_file(file: bytes = File(description="A file read as bytes")):
    return {"file_size": len(file)}


@app.post("/uploadfile/")
async def create_upload_file(
    file: UploadFile = File(description="A file read as UploadFile"),
):
    return {"filename": file.filename}

这里File(...)用于配置额外元数据和验证规则

多文件上传

FastAPI 支持同时上传多个文件。

可用同一个「表单字段」发送含多个文件的「表单数据」。

上传多个文件时,要声明含 bytes 或 UploadFile 的列表(List)

python 复制代码
@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]}

请求表单与文件

FastAPI 支持同时使用 File 和 Form 定义文件和表单字段

python 复制代码
from fastapi import FastAPI, File, Form, UploadFile

app = FastAPI()


@app.post("/files/")
async def create_file(
    file: bytes = File(), fileb: UploadFile = File(), token: str = Form()
):
    return {
        "file_size": len(file),
        "token": token,
        "fileb_content_type": fileb.content_type,
    }
相关推荐
LostSpeed19 小时前
openpnp - python2.7 script - 中文显示乱码,只能显示英文
python·openpnp
C澒19 小时前
前端监控系统的最佳实践
前端·安全·运维开发
xiaoxue..20 小时前
React 手写实现的 KeepAlive 组件
前端·javascript·react.js·面试
hhy_smile20 小时前
Class in Python
java·前端·python
whale fall20 小时前
celery -A tool.src.main worker --loglevel=info --queues=worker1_queue & 什么意思
python·学习·apache
naruto_lnq20 小时前
使用Fabric自动化你的部署流程
jvm·数据库·python
喵手20 小时前
Python爬虫实战:采集博客园 Cnblogs文章标题、发布日期、标签以及HTML正文等(附 Markdown 文档格式预览)!
爬虫·python·爬虫实战·python爬虫工程化实战·零基础python爬虫教学·博客园文章采集·博客园文章采集转md格式
小邓吖20 小时前
自己做了一个工具网站
前端·分布式·后端·中间件·架构·golang
OLOLOadsd12320 小时前
柑橘类水果病害识别与分级_faster-rcnn_hrnetv2p-w32-1x_coco实现
python
南风知我意95720 小时前
【前端面试2】基础面试(杂项)
前端·面试·职场和发展