Files
Profeto/docs/03-api.md
T
WorkBuddy 80616cf459 docs: 全套文档与代码对齐(P1-1,数据源收敛 bzzoiro 后的存量漂移清理)
- 数据源:全部文档统一为 bzzoiro 唯一来源,删除 understat/api-football
  作为现行数据源的表述(仅保留历史注记);.env.example/docs/06 移除
  失效的 API_FOOTBALL_KEY
- 多 Agent:injuries 阵容完整性 → standings 联赛排名
  (README/01/04 的专家表、数据流图、no_data 示例、agent_weights、
  prompt 清单全部对齐 form/stats/home_away/standings/h2h)
- 数据库:6 张表 → 12 张表,补 standings/app_settings/schedules 与
  4 张治理表说明(标注 raw_events/data_quality_checks/data_lineage
  为预留未启用,ingest_failures 已启用),predictions 补 agent_weights 列
- API 文档(03):新增鉴权模型三档表;context/standings/leagues 公开端点
  补全;predictions/eval/backtest 标注需管理员;ingest/bzzoiro 补
  task/limit/season 参数契约,删除 understat/injuries 端点小节
- 目录树(README/01/07):与真实 src/、frontend/src 结构一致
  (core 7 文件、data 7 文件、移除不存在的 retry.py)
- 采集命令(02/05):understat 回填 → task=stats/standings;
  补管理员凭据提示;docs/08 文首标注历史/过时
2026-09-21 20:55:48 +08:00

7.6 KiB
Raw Blame History

03 · API 参考

Base URL: http://localhost:8000 · 交互式文档: /docs(Swagger)与 /redoc

所有数据端点返回 JSON。错误统一为 {"detail": "<message>"} + 对应 HTTP 状态码。

鉴权模型

级别 端点 说明
公开只读 GET /leaguesGET /matchesGET /matches/{id}GET /matches/{id}/contextGET /standingsGET /health* 无需任何凭据;公开站直接调用
公开 + 限流 POST /predict 内存滑动窗口限流(10 次/分钟/IP)
需管理员 GET /predictions*POST /ingest/bzzoiro/eval/*POST /backtest/admin/** Cookie 会话(POST /auth/login 颁发)或 X-API-Key

管理端点在生产环境未配置鉴权时 fail-closed(503),不会静默放行。


数据查询(公开只读)

GET /api/v1/leagues

列出已入库联赛(P1-3: 公开站联赛筛选动态加载来源)。

[{"id": 1, "code": "E0", "name": "Premier League", "country": "England"}]

仅返回 id/code/name/country 四个展示字段,不含任何配置或密钥信息。

GET /api/v1/matches

比赛列表,游标分页。

参数 说明
league 联赛代码,如 E0 / SP1 / D1 / I1 / F1
status scheduled / finished(不传 = 全部)
date YYYY-MM-DD,当天比赛
cursor 上一页返回的 next_cursor
limit 1100,默认 50

响应(倒序,含双方中文名与 xG):

{
  "items": [
    {"id": 42, "league_code": "E0", "season": "2026-2027",
     "home_team": "Arsenal", "away_team": "Manchester United",
     "home_team_zh": null, "away_team_zh": null,
     "match_date": "2026-09-15T19:00:00Z", "match_status": "scheduled",
     "home_goals": null, "away_goals": null,
     "match_stage": "第 5 轮", "home_xg": null, "away_xg": null}
  ],
  "next_cursor": "2026-09-15T19:00:00+00:00|41",
  "has_more": true
}

GET /api/v1/matches/{id}

单场比赛详情,字段同上,另含 stats(统计)与 recent_predictions(最近 5 条预测摘要)。

GET /api/v1/matches/{id}/context

比赛上下文(公开只读,P1-2: 公开站详情页「近况/交锋」数据来源;不触发 LLM):

  • home_recent: 主队最近 5 场已完赛
  • away_recent: 客队最近 5 场已完赛
  • h2h: 双方最近 5 次交手
{
  "home_recent": [
    {"match_date": "2026-09-12T14:00:00+00:00", "home_team": "阿森纳",
     "away_team": "切尔西", "home_goals": 2, "away_goals": 1}
  ],
  "away_recent": [],
  "h2h": []
}

数据不足时对应列表为空(前端展示空态)。比赛不存在返回 404。

GET /api/v1/standings

联赛积分榜(公开只读)。参数:league(联赛代码,空 = 全部)、season(空 = 各联赛最新赛季)。

{"leagues": [
  {"league_code": "E0", "league_name": "Premier League", "season": "2026-2027",
   "retrieved_at": "2026-09-20T08:00:00+00:00",
   "rows": [{"position": 1, "team": "阿森纳", "team_en": "Arsenal",
             "played": 5, "won": 4, "drawn": 1, "lost": 0,
             "goals_for": 11, "goals_against": 3, "goal_diff": 8,
             "points": 13, "xg_for": 9.8, "xg_against": 3.9,
             "form": "WWWDW", "zone": "UEFA Champions League"}]}
]}

预测

POST /api/v1/predict

对一场比赛做 LLM 预测。核心端点。

请求:

{
  "match_id": 42,
  "mode": "multi",
  "model": "gpt-4o",
  "prompt_version": "v1"
}
字段 默认 说明
match_id 必填 比赛 ID
mode multi multi = 5 专家 + 终裁;single = 单次调用
model 配置值 覆盖本次模型(single 模式下生效)
prompt_version v1 prompt 版本(multi 模式即 agent prompt 版本)

响应(multi 模式):

{
  "prediction_id": 7,
  "provider": "openai",
  "model": "gpt-4o",
  "prompt_version": "multi_v1",
  "mode": "multi",
  "pred_home_goals": 2.1,
  "pred_away_goals": 1.0,
  "pred_1x2": "1",
  "subjective_confidence": 0.68,
  "reasoning": "综合 xg 报告的进球期望 2.1-1.0 与 form 报告的三连胜势头……",
  "agent_outputs": [
    {"agent": "h2h", "status": "ok", "data_sufficiency": "medium",
     "analysis": "近 5 次交锋主队 3 胜……", "home_edge": 0.4,
     "subjective_confidence": 0.7, "key_evidence": ["近5次交锋主队3胜", "主场交锋3连胜"],
     "exp_home_goals": null, "exp_away_goals": null, "probable_score": null,
     "model": "gpt-4o-mini", "latency_ms": 2100,
     "prompt_tokens": 380, "completion_tokens": 120},
    {"agent": "standings", "status": "no_data", "data_sufficiency": "none",
     "analysis": "该维度无数据,跳过分析。", "home_edge": null, "subjective_confidence": null,
     "key_evidence": [], "exp_home_goals": null, "exp_away_goals": null,
     "probable_score": null, "model": "", "latency_ms": null,
     "prompt_tokens": null, "completion_tokens": null}
  ],
  "agent_weights": {"form": 0.9, "stats": 0.8, "home_away": 0.7, "standings": 0.8, "h2h": 0.8},
  "context": "[5 份报告的 JSON 串]",
  "latency_ms": 9800
}

agent.status 取值:ok / no_data(维度无数据,已跳过 LLM)/ error(调用失败,fail-open 不阻断)/ parse_error

错误:404 比赛不存在;502 LLM 调用失败(终裁失败时整体失败,专家失败不会)。

GET /api/v1/predictions?match_id=&limit=(需管理员)

预测历史(倒序),含 settled 与实际比分回填状态。

GET /api/v1/predictions/{id}(需管理员)

单条预测详情(含完整 agent_outputs)。


数据采集

POST /api/v1/ingest/bzzoiro(需管理员)

从 bzzoiro(唯一数据源)采集数据并入库(幂等,重复跑安全)。任务在后台异步执行,请求立即返回。

{"task": "all", "leagues": ["E0", "SP1"], "date_from": "2025-08-01", "date_to": "2026-09-08", "status": "finished"}
字段 默认 说明
task events 采集任务:events(比赛)/ standings(积分榜)/ stats(统计回填,含 xG)/ all
leagues 全部已知联赛 联赛代码列表,如 ["E0", "SP1"]
date_from / date_to 日期范围(YYYY-MM-DD)
status 空(两者都采) finished(已完赛)/ scheduled(未来赛程)
season 当前赛季 standings 赛季,如 "2026-2027"
limit 100 stats 回填单次最大比赛数(1500)
  • 响应含每联赛 inserted/updated/errors 统计
  • task=stats 只补空字段、不创建比赛(xG/射门/控球等统计回填)

历史版本曾有独立的 understat(xG)与 injuries(伤停)采集端点, 已随数据源收敛为 bzzoiro 唯一来源而移除。


评估

POST /api/v1/eval/settle(需管理员)

赛后回填实际比分:

{"prediction_id": 7, "home_goals": 2, "away_goals": 1}

GET /api/v1/eval/summary(需管理员)

provider × model 聚合已结算预测:

{"summary": [
  {"provider": "openai", "model": "gpt-4o", "total": 12,
   "accuracy_1x2": 58.3, "avg_score_rmse": 1.21, "avg_subjective_confidence": 0.65}
]}

提示:multi 模式存的 model 是终裁模型、prompt_versionmulti_v1, 因此 summary 里天然可对比 multi vs single、以及不同 prompt 版本的效果。


基础

端点 权限 说明
GET /health 公开 存活检查
GET /docsGET /redoc 公开 Swagger UI / ReDoc
POST /auth/loginPOST /auth/logoutGET /auth/me 公开 管理员 Cookie 会话登录/登出/当前用户
POST /auth/change-password 需管理员 修改管理员密码
POST /backtest 需管理员 历史回测(对已完赛比赛批量预测并评估)