P0-05: confidence → subjective_confidence 改名(15 文件)
LLM 主观置信度与概率分离
P0-02: predictions 增加 cutoff_at + input_hash(轻量快照)
MatchContext 暴露 match_dt
单/多 Agent 路径均记录快照元数据
P2-05: 数据库 CHECK 约束
- pred_home_goals >= 0
- pred_away_goals >= 0
- subjective_confidence 0~1
- pred_1x2 IN (1,X,2)
- mode IN (single,multi)
P2-06: limit 分页约束(ge=1, le=200)
P2-01: 新增 /health/ready 就绪检查
123 lines
2.8 KiB
Python
123 lines
2.8 KiB
Python
"""Pydantic schemas。"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class LeagueOut(BaseModel):
|
|
id: int
|
|
code: str
|
|
name: str
|
|
country: str | None
|
|
|
|
|
|
class MatchOut(BaseModel):
|
|
id: int
|
|
league_code: str | None
|
|
season: str | None
|
|
home_team: str
|
|
away_team: str
|
|
home_team_zh: str | None
|
|
away_team_zh: str | None
|
|
match_date: datetime
|
|
match_status: str
|
|
home_goals: int | None
|
|
away_goals: int | None
|
|
match_stage: str | None
|
|
home_xg: float | None = None
|
|
away_xg: float | None = None
|
|
|
|
|
|
class MatchListOut(BaseModel):
|
|
items: list[MatchOut]
|
|
next_cursor: str | None
|
|
has_more: bool
|
|
|
|
|
|
class PredictRequest(BaseModel):
|
|
match_id: int
|
|
provider: str | None = None
|
|
model: str | None = None
|
|
prompt_version: str | None = None
|
|
mode: str = "multi" # multi(默认, 5专家+终裁) | single(单次调用)
|
|
|
|
|
|
class PredictOut(BaseModel):
|
|
prediction_id: int
|
|
provider: str
|
|
model: str
|
|
prompt_version: str | None = None
|
|
mode: str = "single"
|
|
pred_home_goals: float | None
|
|
pred_away_goals: float | None
|
|
pred_1x2: str | None
|
|
subjective_confidence: float | None
|
|
reasoning: str | None
|
|
agent_outputs: list[dict] | None = None
|
|
agent_weights: dict | None = None
|
|
context: str
|
|
latency_ms: int | None
|
|
|
|
|
|
class PredictionOut(BaseModel):
|
|
id: int
|
|
match_id: int
|
|
provider: str
|
|
model: str
|
|
prompt_version: str
|
|
mode: str = "single"
|
|
pred_home_goals: float | None
|
|
pred_away_goals: float | None
|
|
pred_1x2: str | None
|
|
subjective_confidence: float | None
|
|
reasoning: str | None
|
|
agent_outputs: list[dict] | None = None
|
|
created_at: datetime
|
|
actual_home_goals: int | None
|
|
actual_away_goals: int | None
|
|
settled: bool
|
|
|
|
|
|
class IngestBzzoiroRequest(BaseModel):
|
|
leagues: list[str] = Field(..., description="联赛代码列表,如 ['E0','SP1']")
|
|
date_from: str | None = None
|
|
date_to: str | None = None
|
|
status: str = "finished"
|
|
|
|
|
|
class IngestResponse(BaseModel):
|
|
leagues: dict
|
|
total_inserted: int
|
|
total_updated: int
|
|
errors: list[str] = []
|
|
|
|
|
|
class IngestUnderstatRequest(BaseModel):
|
|
league: str = Field(..., description="联赛代码,如 'E0'")
|
|
season: int = Field(..., description="赛季起始年,如 2025 表示 2025-2026 赛季")
|
|
|
|
|
|
class IngestInjuriesRequest(BaseModel):
|
|
date: str | None = Field(None, description="日期 YYYY-MM-DD,为空则采集当天")
|
|
|
|
|
|
class IngestSimpleResponse(BaseModel):
|
|
count: int = 0
|
|
updated: int = 0
|
|
skipped: int = 0
|
|
unmatched: int = 0
|
|
errors: list[str] = []
|
|
|
|
|
|
class SettleRequest(BaseModel):
|
|
prediction_id: int
|
|
home_goals: int = Field(ge=0, le=30)
|
|
away_goals: int = Field(ge=0, le=30)
|
|
|
|
|
|
class EvalSummaryOut(BaseModel):
|
|
summary: list[dict[str, Any]]
|