如何向FastAPI接口同时传输JSON负载与图片并读取附加字段?
FastAPI 图片上传接口附带附加字段的实现方案
接收逻辑核心
当接口需要同时接收上传文件和附加文本数据时,请求的传输格式为multipart/form-data(也就是requests库用files参数发请求时的格式),这类请求中的非文件字段,必须通过Form类型的参数声明接收,无法从UploadFile对象中读取。
改造后的服务端代码
在原有代码基础上,新增Form模块的导入,把要接收的some_other_data作为接口参数声明即可,参数名需要和客户端传递的字段名完全一致:
import cv2 import numpy as np from fastapi import FastAPI, File, UploadFile, Form app = FastAPI() @app.post('/file') def _file_upload( my_file: UploadFile = File(...), some_other_data: str = Form(...) ): image_bytes = my_file.file.read() decoded = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), -1) # 可直接使用some_other_data字段开展业务逻辑 return { "uploaded_file_name": my_file.filename, "received_extra_data": some_other_data, "image_decode_status": decoded is not None }
客户端传参优化
你当前编写的客户端代码可以正常连通改造后的服务端,但存在两个可优化点:
- 直接打开的文件句柄没有自动关闭机制,容易造成资源泄漏
- 非文件类的普通表单字段,按照requests官方规范可以放在
data参数中传递,和写在files字典里的最终请求结构完全一致,服务端可正常识别
优化后的客户端示例:
import requests filename = "test_image.jpeg" with open(filename, 'rb') as img_file: upload_files = {'my_file': (filename, img_file)} form_extra = {'some_other_data': 'hello'} response = requests.post( 'http://127.0.0.1:8000/file', files=upload_files, data=form_extra ) print(response.json())
常见踩坑提醒
- 文件上传场景下的请求Content-Type为
multipart/form-data,不能用Body类型参数接收附加数据,该格式下FastAPI不会将请求体解析为JSON结构,必须用Form参数接收普通字段 - 所有
File、Form声明的参数名必须和客户端传递的字段名严格匹配,否则会触发422参数缺失错误 - 原示例代码的返回值存在笔误,把上传的文件名赋值给了
file_size字段,实际使用时可根据业务需求调整返回结构
内容的提问来源于stack exchange,提问作者Dawny33
相关产品推荐
相关产品推荐

