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,
    }
相关推荐
喵手2 分钟前
Spring Boot 异常处理:从全局捕获到优化用户体验!
spring boot·python·ux
魂尾ac4 分钟前
因为想开发新项目了~~要给老Python项目整个虚拟环境
开发语言·python
LYue~10 分钟前
7月31号打卡
python
神仙别闹20 分钟前
基于JSP+MySQL 实现(Web)毕业设计题目收集系统
java·前端·mysql
yj155820 分钟前
装修风格怎么选
python
前端李二牛20 分钟前
Web字体使用最佳实践
前端·http
YGY_Webgis糕手之路21 分钟前
Cesium 快速入门(六)实体类型介绍
前端·gis·cesium
Jacob023421 分钟前
UI 代码不写也行?我用 MCP Server 和 ShadCN 自动生成前端界面
前端·llm·ai编程
泰Tai22 分钟前
【YOLOv8学习】WSL2中安装标注软件X-AnyLabeling
python·图像识别
爱泡脚的鸡腿23 分钟前
Vue第五次笔记
前端·vue.js