Files
xian_algorithm_new/app/schemas/api_schemas.py
T
2026-06-28 09:26:13 +08:00

129 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
API 请求/响应数据模型
"""
from datetime import datetime
from typing import List, Optional, Dict, Any
from pydantic import BaseModel, Field, model_validator
# ============================================================
# 暴雨预测
# ============================================================
class RainfallPredictRequest(BaseModel):
"""
暴雨灾害链预测请求
参数规则(二选一):
1. 自动推演模式:rainfall、duration、region_code 全部不传 → 从气象表自动获取,不限区域
2. 指定条件模式:rainfall、duration、region_code 全部传入 → 按指定条件预测
"""
disaster_name: str = Field(min_length=1, max_length=255)
point_ids: Optional[List[int]] = Field(None, max_length=500,
description="点位ID列表,不传则查询所有点")
region_code: Optional[str] = Field(None, description="行政区划代码(如 '610104'")
rainfall: Optional[float] = Field(None, ge=0, description="累计降雨量(mm)")
duration: Optional[float] = Field(None, ge=0, description="降雨持续时间(h)")
occurred_time: Optional[datetime] = Field(None, description="事件发生时间,不传则为当前时间")
operation_type: str = Field("模拟", min_length=1, max_length=50,
description="操作类型(如 '模拟', '实时监测', '应急评估'")
@model_validator(mode='after')
def validate_mode_exclusivity(self):
"""校验 rainfall / duration / region_code 必须要么全不传,要么全传"""
trio = (self.rainfall, self.duration, self.region_code)
none_count = sum(1 for v in trio if v is None)
if none_count not in (0, 3):
raise ValueError(
"rainfall、duration、region_code 必须全部传入或全部不传,"
"不允许只传部分参数"
)
return self
# ============================================================
# 地震预测
# ============================================================
class EarthquakePredictRequest(BaseModel):
"""地震灾害链预测请求"""
disaster_name: str = Field(min_length=1, max_length=255)
point_ids: Optional[List[int]] = Field(None, max_length=500,
description="点位ID列表,不传则查询所有点")
region_code: Optional[str] = Field(None, description="行政区划代码(如 '610104'),不传则不限区域")
magnitude: float = Field(..., ge=0, le=10, description="震级(Richter)")
depth: float = Field(10.0, gt=0, le=700, description="震源深度(km),默认10km")
epicenter_lon: float = Field(..., ge=-180, le=180, description="震中经度")
epicenter_lat: float = Field(..., ge=-90, le=90, description="震中纬度")
occurred_time: Optional[datetime] = Field(None, description="地震发生时间,不传则为当前时间")
operation_type: str = Field("模拟", min_length=1, max_length=50,
description="操作类型(如 '模拟', '实时监测', '应急评估'")
# ============================================================
# 专题图产出
# ============================================================
class QgisMapExportRequest(BaseModel):
"""专题图导出请求"""
inferenceId: int = Field(..., description="推理结果IDxian_inference_result.id")
class QgisMapExportResponse(BaseModel):
"""专题图导出响应"""
code: int = Field(200, description="状态码")
message: str = Field("success", description="提示信息")
data: Optional[str] = Field(None, description="导出图片的访问路径")
# ============================================================
# 通用响应
# ============================================================
class PredictData(BaseModel):
"""预测数据"""
record_id: Optional[int] = Field(None, description="推理结果记录ID")
list: Dict[str, Dict[str, Any]] = Field(default_factory=dict, description="预测结果列表,包含概率和经纬度")
class PredictResponse(BaseModel):
"""预测响应"""
code: int = Field(200, description="状态码")
message: str = Field("success", description="提示信息")
data: Optional[PredictData] = Field(None, description="预测数据")
class UpdateMonitoringTimeRequest(BaseModel):
"""更新监测时间请求"""
query_time: str = Field(..., description="查询时间,格式: YYYY-MM-DD HH:mm:ss,如 '2025-09-16 20:00:00'")
class HealthResponse(BaseModel):
"""健康检查响应"""
status: str = "ok"
rainfall_model_loaded: bool = False
earthquake_model_loaded: bool = False
# ============================================================
# 各区降雨概况
# ============================================================
class DistrictSummaryRequest(BaseModel):
"""各区降雨概况请求"""
inference_id: int = Field(..., ge=1, description="推理结果IDxian_inference_result.id")
class DistrictSummaryItem(BaseModel):
"""单个区的降雨概况"""
district_name: str = Field(..., description="行政区名称(如 '碑林区'")
district_code: str = Field(..., description="行政区划代码(如 '610103'")
rainfall: float = Field(..., description="累计降雨量(mm)")
duration_hours: float = Field(..., description="持续降雨时间(h)")
class DistrictSummaryResponse(BaseModel):
"""各区降雨概况响应"""
code: int = Field(200, description="状态码")
message: str = Field("success", description="提示信息")
data: Optional[List[DistrictSummaryItem]] = Field(None, description="各区降雨概况列表")