modify: 上报接口 422 问题
This commit is contained in:
@@ -12,7 +12,8 @@ import json
|
||||
import uuid
|
||||
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 .models.video_models import VideoUploadResponse, VideoUploadResult
|
||||
@@ -99,16 +100,18 @@ async def video_upload(
|
||||
description="接收盒子告警报文(JSON),所有字段已在 OpenAPI 中声明,未知字段自动保留",
|
||||
response_model=AlarmReportResponse,
|
||||
)
|
||||
async def alarm_report(body: AlarmReportRequest) -> AlarmReportResponse:
|
||||
async def alarm_report(
|
||||
request: Request,
|
||||
payload: dict = Body(..., description="告警报文 JSON 对象"),
|
||||
) -> AlarmReportResponse:
|
||||
"""
|
||||
告警上报接口
|
||||
|
||||
盒子检测到违规事件后,先上传视频再上报 JSON 告警报文。
|
||||
请求体所有字段已在 Pydantic 模型中声明(含默认值),
|
||||
model_config extra=allow 确保盒子固件升级新增字段不会丢失。
|
||||
使用手动 Pydantic 验证以便在验证失败时记录完整请求体,便于排查。
|
||||
|
||||
业务处理:
|
||||
1. Pydantic 验证基础字段类型
|
||||
1. 手动 Pydantic 验证基础字段类型(验证失败时记录原始 JSON)
|
||||
2. model_dump() 获取完整 dict(含额外字段)
|
||||
3. 提取关键索引字段存入 alarm_record 表
|
||||
4. 完整报文 JSON 字符串存入 alarm_data
|
||||
@@ -116,6 +119,17 @@ async def alarm_report(body: AlarmReportRequest) -> AlarmReportResponse:
|
||||
返回格式:{"Result": {"Code": 0, "Desc": ""}}
|
||||
仅当 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)
|
||||
full_data = body.model_dump(exclude_none=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user