表单
接收的不是json格式,而是表单字段,要使用Form
需要先安装python-multipart,pip install python-multipart
使用Form可以使用于Query,Path,Body等相同的验证和元数据
from fastapi import FastAPI, Formapp = FastAPI()@app.post("/login/")
async def login(username: str = Form(), password: str = Form()):return {"username": username}
OAuth2 规范的 "密码流" 模式规定要通过表单字段发送 username 和 password。
该规范要求字段必须命名为 username 和 password,并通过表单字段发送,不能用 JSON
文件
文件上传也是需要使用表单形式发送,也需要安装python-multipart
创建文件参数File()和Query,Path,Body有相同的验证和元数据
from fastapi import FastAPI, Fileapp = FastAPI()@app.post("/files/")
async def create_file(file: bytes = File()):return {"file_size": len(file)}
FastAPI 将以bytes形式读取和接收文件内容这种方式把文件的所有内容都存储在内存里,适用于小型文件
使用UploadFile参数
from fastapi import FastAPI,UploadFileapp = FastAPI()@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):return {"filename": file.filename}
UploadFile比Bytes更有优势,更适于处理图像、视频、二进制文件等大型文件,好处是不会占用所有内存
UploadFile的属性
filename:上传文件名
content_type:内容类型(MIME 类型 / 媒体类型)。例如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()
:关闭文件
async方法需要搭配await使用
contents = await myfile.read()
在普通def路径操作函数 内,则可以直接访UploadFile.file
contents = myfile.file.read()
可选文件参数
from fastapi import FastAPI, File, UploadFileapp = FastAPI()@app.post("/files/")
async def create_file(file: 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: UploadFile | None = None):if not file:return {"message": "No upload file sent"}else:return {"filename": file.filename}
带有额外元数据的文件上传
from fastapi import FastAPI, File, UploadFileapp = 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}
多文件上传
上传多个文件时,要声明含 bytes
或 UploadFile
的列表(List
)
from fastapi import FastAPI, File, UploadFileapp = 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]}
带有额外元数据的多文件上传
from fastapi import FastAPI, File, UploadFileapp = FastAPI()@app.post("/files/")
async def create_files(files: list[bytes] = File(description="Multiple files as bytes"),
):return {"file_sizes": [len(file) for file in files]}@app.post("/uploadfiles/")
async def create_upload_files(files: list[UploadFile] = File(description="Multiple files as UploadFile"),
):return {"filenames": [file.filename for file in files]}
表单和文件同时使用
from fastapi import FastAPI, File, Form, UploadFileapp = 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,}