本文主要记录表单的数据请求以及上传不同大小的文件、上传多个文件、获取文件信息等相关内容。
表单请求
@app07.post("/stu07/form")
def stu07_form(
param1: str = Form(),
param2: str = Form(),
param3: int = Form()
):
return {
"param1": param1,
"param2": param2,
"param3": param3
}
同路径参数和查询参数一致,利用fastapi内置的Form方法进行声明即可;
上传一个bytes文件
@app07.post("/stu07/files")
def stu07_files(
file: bytes = File()
):
return {
"files_size": len(file)
}
上传文件都是以Form形式进行上传,上面代码中的File也是继承至Form;
如果把路径操作函数参数的类型声明为
bytes
,FastAPI 将以 bytes 形式读取和接收文件内容。这种方式把文件的所有内容都存储在内存里,适用于小型文件。
使用UploadFile上传文件
@app07.post("/stu07/uploadfile/")
def stu07_uploadfile(
file: UploadFile
):
return {
"文件名": file.filename,
"内容类型": file.content_type
}
UploadFile
与bytes
相比有更多优势;更适于处理图像、视频、二进制文件等大型文件,好处是不会占用所有内存;使用
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()
:关闭文件。注意:
上述方法都是
async
方法,要搭配「await」使用;如在
async
路径操作函数内,就需要用以下方式读取内容contents = await myfile.read()
在普通
def
路径操作函数 内,则可以直接访问UploadFile.file
contents = myfile.file.read()
可选文件上传
@app07.post("/stu07/optionalfile")
def stu07_optional_file(
file: Optional[bytes] = File(None)
):
if not file:
return {"message": "未上传文件"}
else:
return {"filesize": len(file)}
同样利用Optional或者Union进行设置即可;
设置元数据
@app07.post("/stu07/uploadfile/metadata/")
def stu07_uploadfile_metadata(
file: UploadFile = File(None, description="一个UploadFile文件")
):
if not file:
return {"message": "未上传文件"}
else:
return {"filename": file.filename}
这部分内容和路径参数和查询参数一致,根据需求进行设置即可;
上传多文件
@app07.post("/stu07/fileslist")
def stu07_files_list(
byteslist: List[bytes] = File(...),
uploadfilelist: List[UploadFile] = File(...)
):
return {
"bytes_files_size": [len(file) for file in byteslist],
"upload_filesname": [file.filename for file in uploadfilelist]
}
上传多个文件,设置对应参数为
List
类型即可;
同时上传表单参数和文件
@app07.post("/stu07/form_file/")
def stu07_form_file(
file: UploadFile,
form: str = Form()
):
return {
"filename": file.filename,
"form": form
}
混合上传,即在对应的路径函数中声明不同的参数即可;
源码
# -*- coding: utf-8 -*-
# @Time: 2022/11/30 18:09
# @Author: MinChess
# @File: stu07.py
# @Software: PyCharm
from fastapi import APIRouter, Form, File, UploadFile
from typing import List, Optional
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
from datetime import datetime
app07 = APIRouter()
# 一个form请求
@app07.post("/stu07/form")
def stu07_form(
param1: str = Form(),
param2: str = Form(),
param3: int = Form()
):
return {
"param1": param1,
"param2": param2,
"param3": param3
}
# 上传一个bytes类型的文件
@app07.post("/stu07/files")
def stu07_files(
file: bytes = File()
):
return {
"files_size": len(file)
}
# 使用UploadFile
@app07.post("/stu07/uploadfile/")
def stu07_uploadfile(
file: UploadFile
):
return {
"文件名": file.filename,
"内容类型": file.content_type
}
# 可选文件上传
@app07.post("/stu07/optionalfile")
def stu07_optional_file(
file: Optional[bytes] = File(None)
):
if not file:
return {"message": "未上传文件"}
else:
return {"filesize": len(file)}
# 设置UploadFile元数据
@app07.post("/stu07/uploadfile/metadata/")
def stu07_uploadfile_metadata(
file: UploadFile = File(None, description="一个UploadFile文件")
):
if not file:
return {"message": "未上传文件"}
else:
return {"filename": file.filename}
# 多文件上传
@app07.post("/stu07/fileslist")
def stu07_files_list(
byteslist: List[bytes] = File(...),
uploadfilelist: List[UploadFile] = File(...)
):
return {
"bytes_files_size": [len(file) for file in byteslist],
"upload_filesname": [file.filename for file in uploadfilelist]
}
# 同时上传表单和文件
@app07.post("/stu07/form_file/")
def stu07_form_file(
file: UploadFile,
form: str = Form()
):
return {
"filename": file.filename,
"form": form
}
感谢阅读!
评论区