如何在FastAPI中为IP摄像头POST请求配置Pydantic模型?
解决FastAPI接收IP摄像头multipart请求的问题
先搞定422错误:正确处理JSON文件与图片
你碰到的422错误,核心原因是FastAPI不会自动解析event这个UploadFile里的JSON内容,必须手动读取后转成字典再处理。直接上可运行的代码示例:
from fastapi import FastAPI, UploadFile, File import json from pydantic import BaseModel app = FastAPI() # 定义Pydantic模型(用于校验结构化数据) class CameraEvent(BaseModel): license_plate: str camera_id: str timestamp: str # 若数据是标准时间格式,可改用datetime类型 @app.post("/camera-event/") async def receive_camera_event(event: UploadFile = File(...), image: UploadFile = File(...)): # 读取并解析event文件中的JSON内容 event_raw = await event.read() try: event_data = json.loads(event_raw.decode("utf-8")) except json.JSONDecodeError: return {"error": "Invalid JSON in event file"} # 用Pydantic校验数据(可选,但推荐生产环境使用) try: validated_event = CameraEvent(**event_data) except Exception as e: return {"error": "Event data validation failed", "details": str(e)} # 处理图片文件(示例:读取内容,可自行扩展保存/识别逻辑) image_content = await image.read() return { "validated_event": validated_event.dict(), "image_info": {"filename": image.filename, "size_bytes": len(image_content)} }
要确认IP摄像头发送的multipart/form-data里,字段名确实是event和image——字段名不匹配是触发422的常见原因之一。
Pydantic模型:严格定义VS灵活解析
两种方式FastAPI都支持,按需选择:
1. 严格定义字段(生产环境推荐)
像上面的CameraEvent模型,明确指定每个字段的类型,FastAPI会自动做数据校验,返回清晰的错误提示,避免脏数据流入。如果IP摄像头的输出格式固定,强烈建议这么做。
2. 灵活接收任意数据(类似Flask的自由模式)
如果暂时不确定字段,或需要兼容多种格式:
- 直接用
dict接收解析后的JSON:event_data: dict = json.loads(event_raw.decode("utf-8")) - 用Pydantic的
Extra.allow允许额外字段:from pydantic import BaseModel, Extra class FlexibleCameraEvent(BaseModel): license_plate: str # 保留核心必填字段 class Config: extra = Extra.allow # 允许接收未定义的字段 - 注意:如果想让FastAPI自动解析JSON,不能用UploadFile,需让客户端把JSON作为表单字段传递,但你的场景是JSON文件,所以必须通过UploadFile读取后手动解析。
额外提示
- 若JSON文件编码不是UTF-8,调整
decode的参数(比如gbk)即可适配。 - UploadFile会自动处理文件关闭,无需手动调用
close()。
内容的提问来源于stack exchange,提问作者Source Matters
相关产品推荐
相关产品推荐

