0%

FastAPI自学教程(23) - 请求文件处理

1. 基础文件上传

1
2
3
4
5
6
7
8
9
10
11
from fastapi import FastAPI, File, UploadFile

app = FastAPI()

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

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
return {"filename": file.filename}
  • 必须安装 python-multipart 依赖:pip install python-multipart
  • bytes 类型适合小文件(全部加载到内存)
  • UploadFile 类型支持大文件流式处理(默认 1MB 内存缓存,超过写入磁盘)

2. 带类型的文件参数

1
2
3
4
5
6
7
8
9
from typing import Annotated

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

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
return {"filename": file.filename}
  • Annotated 注解方式(推荐 Python 3.10+)
  • 支持以下特性:
    • 自动请求解析(multipart/form-data)
    • 数据验证(文件类型校验)
    • 错误自动生成(格式错误返回422)

3. 混合表单与文件

1
2
3
4
5
6
7
8
9
10
11
@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
}
  • 同时处理文件上传和表单字段
  • File()Form() 可组合使用
  • 支持多个文件字段(如 file1, file2

4. 多文件上传处理

1
2
3
4
5
6
7
8
9
@app.post("/uploadfiles/")
async def create_upload_files(files: list[UploadFile] = File(...)):
filenames = []
for file in files:
contents = await file.read()
with open(file.filename, "wb") as f:
f.write(contents)
filenames.append(file.filename)
return {"filenames": filenames}
  • 使用 List[UploadFile] 接收多个文件
  • 客户端需使用相同字段名多次提交文件(如 files=...&files=...
  • 支持混合文件类型(bytes与UploadFile可共存)

5. 注意事项

  • 文件字段必须显式声明 File(),否则会被识别为查询参数
  • 生产环境建议使用 UploadFile 处理大文件(避免内存溢出)
  • 上传文件默认限制:
    • 最大数量:1000个
    • 最大体积:无限制(需自行配置)
  • 安全建议:
    • 校验文件类型(通过filename后缀或魔数)
    • 限制文件体积(通过max_size参数)