modify: 上报接口 422 问题

This commit is contained in:
2026-07-28 15:52:21 +08:00
parent a12ceec221
commit e3552228b6
+19 -5
View File
@@ -12,7 +12,8 @@ import json
import uuid import uuid
import logging import logging
from fastapi import APIRouter, UploadFile, File, Form, Request from fastapi import APIRouter, UploadFile, File, Form, Request, Body, HTTPException
from pydantic import ValidationError
from aiofile import AIOFile from aiofile import AIOFile
from .models.video_models import VideoUploadResponse, VideoUploadResult from .models.video_models import VideoUploadResponse, VideoUploadResult
@@ -99,16 +100,18 @@ async def video_upload(
description="接收盒子告警报文(JSON),所有字段已在 OpenAPI 中声明,未知字段自动保留", description="接收盒子告警报文(JSON),所有字段已在 OpenAPI 中声明,未知字段自动保留",
response_model=AlarmReportResponse, response_model=AlarmReportResponse,
) )
async def alarm_report(body: AlarmReportRequest) -> AlarmReportResponse: async def alarm_report(
request: Request,
payload: dict = Body(..., description="告警报文 JSON 对象"),
) -> AlarmReportResponse:
""" """
告警上报接口 告警上报接口
盒子检测到违规事件后,先上传视频再上报 JSON 告警报文。 盒子检测到违规事件后,先上传视频再上报 JSON 告警报文。
请求体所有字段已在 Pydantic 模型中声明(含默认值), 使用手动 Pydantic 验证以便在验证失败时记录完整请求体,便于排查。
model_config extra=allow 确保盒子固件升级新增字段不会丢失。
业务处理: 业务处理:
1. Pydantic 验证基础字段类型 1. 手动 Pydantic 验证基础字段类型(验证失败时记录原始 JSON)
2. model_dump() 获取完整 dict(含额外字段) 2. model_dump() 获取完整 dict(含额外字段)
3. 提取关键索引字段存入 alarm_record 表 3. 提取关键索引字段存入 alarm_record 表
4. 完整报文 JSON 字符串存入 alarm_data 4. 完整报文 JSON 字符串存入 alarm_data
@@ -116,6 +119,17 @@ async def alarm_report(body: AlarmReportRequest) -> AlarmReportResponse:
返回格式:{"Result": {"Code": 0, "Desc": ""}} 返回格式:{"Result": {"Code": 0, "Desc": ""}}
仅当 HTTP 200 + Code 非 0 时,盒子认为上报失败。 仅当 HTTP 200 + Code 非 0 时,盒子认为上报失败。
""" """
# 手动 Pydantic 验证,失败时记录完整原始请求体
try:
body = AlarmReportRequest.model_validate(payload)
except ValidationError as e:
logger.error(
f"[AlarmReport] Pydantic 验证失败:\n"
f" 错误: {e.errors()}\n"
f" 请求体: {json.dumps(payload, ensure_ascii=False)[:3000]}"
)
raise HTTPException(status_code=422, detail=e.errors())
# 获取完整报文(含 extra 字段,排除 None 值以生成整洁 JSON) # 获取完整报文(含 extra 字段,排除 None 值以生成整洁 JSON)
full_data = body.model_dump(exclude_none=True) full_data = body.model_dump(exclude_none=True)