Skip to content

Latest commit

 

History

History
355 lines (257 loc) · 12.8 KB

File metadata and controls

355 lines (257 loc) · 12.8 KB

PolyWeather API 文档(v1.8.1)

最后更新:2026-05-28

本文档描述当前对外可用 API 口径(web/app.py + web/routes.py + frontend/app/api/*)。

1. 基础信息

  • 后端直连:http://127.0.0.1:8000
  • 前端 BFF:https://polyweather.top/api/*
  • 返回格式:application/json

2. 请求链路

flowchart LR
    FE["Browser / Dashboard"] --> BFF["Next.js Route Handlers (/api/*)"]
    BFF --> API["FastAPI (/web/app.py + /web/routes.py)"]
    API --> WX["Weather Collector"]
    API --> ANA["DEB + Hourly Consensus + Probability + Market Scan"]
    API --> SSE["Realtime SSE (/api/events)"]
    SSE --> EVENT["Redis Stream / SQLite Event Log"]
    API --> PAY["Payment Intent + Event + Confirm Loops"]
    API --> OBS["healthz / system status / metrics"]
Loading

3. 天气分析接口

接口 方法 用途
/api/cities GET 监控城市列表
/api/city/{name} GET 城市主分析
/api/city/{name}/summary GET 轻量摘要
/api/city/{name}/detail GET 聚合详情(含 market_scan)
/api/history/{name} GET 历史对账
/api/events GET SSE 实时观测事件流
/api/internal/collector-patch POST 采集器内部写入实时观测 patch

GET /api/events

浏览器实时图表入口,使用 text/event-stream

参数:

  • cities=shanghai,hong kong:可选,逗号分隔城市列表;为空表示订阅全部城市。
  • since_revision=<int>:可选,断线重连后从指定 revision 之后 replay。
  • replay_limit=<int>:可选,默认 500,后端会做上限保护。

事件:

  • connected:连接建立,包含当前 latest_revision
  • city_observation_patch.v1:标准实时观测 patch,包含城市、序列、温度、观测 UTC 时间、城市时区、revision。
  • resync_required:replay 窗口不足或事件存储不可用,前端应回到 HTTP snapshot 重建画面。
  • heartbeat:保活。

生产环境推荐 POLYWEATHER_EVENT_STORE=redis,以 Redis Stream 保存短窗口事件并支持多 worker fanout;本地或单进程可使用 SQLite event log。

GET /api/city/{name}/detail

可选参数:

  • force_refresh=true|false
  • market_slug=<slug>
  • target_date=YYYY-MM-DD

重点字段:

  • market_scan.available
  • market_scan.signal_label
  • market_scan.edge_percent
  • market_scan.anchor_model / anchor_high / anchor_settlement
  • market_scan.yes_buy / no_buy
  • market_scan.primary_market.tradable
  • probabilities.engine / calibration_mode / calibration_version
  • probabilities.raw_mu / raw_sigma / calibrated_mu / calibrated_sigma
  • probabilities.shadow_distribution
  • deb.hourly_consensus / deb.hourly_path.base_source
  • intraday_meteorology.headline / confidence
  • intraday_meteorology.base_case_bucket / upside_bucket / downside_bucket
  • intraday_meteorology.next_observation_time
  • intraday_meteorology.invalidation_rules / confirmation_rules / signal_contributions
  • peak.first_h / peak.last_h / peak.status
  • vertical_profile_signal.heating_setup / suppression_risk / trigger_risk / mixing_strength
  • taf.signal.peak_window / suppression_level / disruption_level / markers

城市决策卡市场层口径

  • 前端会请求完整 market_scan / all_buckets,而不是只取 lite 结果。
  • 温度桶匹配按今日预计最高温中枢映射,并区分 exact、range、or higher、or lower,避免把 30°C 附近的天气中枢误配到不合理尾部桶。
  • 模型-市场差 = 模型概率 - 市场隐含概率。正值表示天气概率高于市场报价;负值表示市场已经更充分计价。
  • 温度桶标签会统一规范化 C/F/°C/°F,避免前端重复显示单位。

detail 新增结构信号说明

/api/city/{name}/detail 现在会返回一组更偏交易场景的结构字段:

1. intraday_meteorology

今日日内分析的专业气象判断层。该字段只做派生,不改变路由和缓存策略。

重点字段:

  • headline:今日主判断,例如“峰值仍有上修空间 / 峰值受云雨压制”
  • confidencelow | medium | high
  • base_case_bucket:基准温度档位
  • upside_bucket:上修路径档位
  • downside_bucket:下修路径档位
  • next_observation_time:下一次应重点看的本地时间
  • invalidation_rules:2-4 条失效条件
  • confirmation_rules:1-3 条确认条件
  • signal_contributions:气象因子列表,含 labeldirectionstrengthsummary

前端如果该字段暂缺,会降级使用现有 paceViewboundaryRiskViewupperAirCueprobabilitySummary 等字段。

2. probabilities

概率层基于 legacy 高斯分桶,以 DEB 融合预测 mu 和 ensemble spread sigma 生成 1°C 粒度概率分布。前端图表将 legacy 高斯展示为水平概率温度带和 mu 参考线,不把概率分布渲染成时间序列曲线。

概率字段:

  • engine:固定为 legacy
  • mu:DEB 融合预测中心值
  • distribution:当天合约桶概率分布
  • distribution_all:包含外围桶的完整分布

2.1 deb.hourly_consensus

DEB hourly consensus 是当前图表与峰值窗口的优先小时路径。

重点字段:

  • version:当前为 deb_hourly_consensus.v1
  • base_sourcemulti_model_hourly_deb_weights
  • times / temps:城市当地日的小时路径
  • model_weights:DEB 权重折叠后的模型权重

说明:

  • 该路径是预测曲线,不是实测来源。
  • 图表默认展示全天;“高温”视图仅根据该路径推导 peak-centric 窗口。

3. detail_depth

detail_depth 用于区分轻量 detail 与完整 detail。前端如果发现:

  • detail_depth != "full"
  • forecast.daily 只有当天一张卡
  • 或模型层只剩单模型

会触发强刷完整 detail,并在 UI 上显示同步状态 / 占位卡,避免用户把中间态误判成完整分析。

4. peak

  • first_h:预计峰值窗口起始小时
  • last_h:预计峰值窗口结束小时
  • statusbefore_peak | near_peak | after_peak

这组字段用于让日内结构信号围绕真实峰值窗口分析,而不是固定只看下午。

5. vertical_profile_signal

重点字段:

  • source
  • window
  • cape_max
  • cin_min
  • lifted_index_min
  • boundary_layer_height_max
  • shear_10m_180m_max
  • suppression_risk
  • trigger_risk
  • mixing_strength
  • shear_risk
  • heating_setup
  • heating_score
  • summary_zh
  • summary_en

这组字段对应前端“高空结构信号 / Upper-Air Structure”卡片。

6. taf.signal

仅对非香港机场城市启用。当前已支持解析:

  • FM
  • TEMPO
  • BECMG
  • PROB30
  • PROB40

重点字段:

  • peak_window
  • segments
  • markers
  • suppression_level
  • disruption_level
  • wind_shift
  • summary_zh
  • summary_en

markers 会被前端温度走势图拿来做 TAF 时段 / TAF Timing 标记。

7. 结算锚点口径

  • 多数机场市场以 METAR / 机场主站实况为结算锚点。
  • Wunderground 是历史页面或参考入口,不应在产品文案里被描述成“站”。
  • MGM / NMC / JMA / AMOS / HKO / CWA 等官方站网属于增强层或明确官方站点层;只有合约规则明确指定时,才作为最终结算站点。

4. 鉴权与账户接口

接口 方法 用途
/api/auth/me GET 当前登录态、积分、订阅状态

/api/auth/me 关键字段:

  • authenticated
  • user_id, email
  • points, weekly_points, weekly_rank
  • subscription_active, subscription_plan_code, subscription_expires_at

5. 支付接口

接口 方法 用途
/api/payments/config GET 支付配置、代币列表、套餐、积分抵扣规则
/api/payments/runtime GET 支付运行态、RPC 状态、event loop 状态、最近审计事件
/api/payments/wallets GET 当前用户已绑定钱包
/api/payments/wallets/challenge POST 获取绑定签名 challenge
/api/payments/wallets/verify POST 提交签名并绑定钱包
/api/payments/intents POST 创建支付意图(intent)
/api/payments/intents/{intent_id} GET 查询 intent 最新状态
/api/payments/intents/{intent_id}/submit POST 提交交易哈希
/api/payments/intents/{intent_id}/confirm POST 手动触发确认
/api/payments/reconcile-latest POST 对当前登录用户最近一笔 intent 做恢复性确认

支付状态建议

POST /api/payments/intents 支持的关键字段:

  • plan_code:套餐,例如 pro_monthly
  • payment_modewalletdirect
  • chain_id:可选;多链支付时前端传用户选择的链,例如 Polygon 137 或 Ethereum 1
  • token_address:可选;指定该链上的 USDC / USDC.e 合约地址

前端流程建议:

  1. POST /intents
  2. 钱包发链上交易
  3. POST /submit
  4. POST /confirm
  5. 若 pending,轮询 GET /intents/{id} 直到 confirmed

6. 运维与观测接口

接口 方法 用途
/healthz GET 基础健康检查
/api/system/status GET 系统状态、功能开关、rollout 状态、轻量指标摘要
/metrics GET Prometheus 风格指标导出

/api/system/status 当前会包含:

  • features.state_storage_mode
  • probability.decision
  • probability.ready_for_primary
  • metrics

/metrics 当前会导出:

  • polyweather_http_requests_total
  • polyweather_http_request_duration_ms_*
  • polyweather_source_requests_total
  • polyweather_source_request_duration_ms_*

7. Ops 管理接口

这些接口主要给 /ops 管理后台使用,默认要求:

  • 已登录
  • 当前邮箱位于 POLYWEATHER_OPS_ADMIN_EMAILS
接口 方法 用途
/api/ops/users GET 按 Telegram ID / 用户名 / 邮箱查询用户
/api/ops/leaderboard/weekly GET 本周积分榜
/api/ops/memberships GET 当前有效会员(已按用户去重,保留最晚到期)
/api/ops/users/grant-points POST 手动补分
/api/ops/payments/incidents GET 支付异常单(仅 payment_intent_failed
/api/ops/payments/incidents/{event_id}/resolve POST 标记支付异常单已处理

/api/ops/payments/incidents 当前支持:

  • reason=<receiver_mismatch|sender_mismatch|event_mismatch|tx_reverted>
  • 默认不返回已标记处理的记录
  • 重点用于排查“已付款未开通”“打到旧收款地址”等事故

8. 缓存策略(当前)

  • cities / summary / history:BFF 支持 ETag + 304
  • summary?force_refresh=trueCache-Control: no-store
  • 详情接口与支付接口:no-store
  • METAR / TAF / settlement current 由后端各自维护短 TTL 缓存
  • 实时事件层:POLYWEATHER_EVENT_STORE=redis 时使用 Redis Stream;未启用 Redis 时使用 SQLite observation_patch_events 作为 replay fallback
  • 前端终端图表:HTTP detail 仍是完整 snapshot,SSE patch 只做增量观测追加;长连接断开或后台恢复时前端会按 since_revision replay 或强刷 detail
  • 前端打开今日日内分析时,如果 full detail 或 market scan 正在同步,会先显示刷新锁,不展示可交互的旧内容
  • 城市决策卡 AI 解读前端缓存键为 city + local_date + locale + METAR signature;signature 优先使用原始 METAR,缺失时回退到报文时间、观测时间和温度
  • 城市决策卡 AI 解读使用两层前端缓存:页面内存缓存保存 loading / 流式进度 / 最终 payload,localStorage 保存最终成功 payload,默认 TTL 1 小时
  • 后端城市 AI 缓存不使用 local_time 作为 key,避免同一观测因当前时钟变化反复失效
  • 城市市场扫描完整桶缓存按 city + local_date + full 存储,默认 TTL 10 分钟

9. 调试示例

查询未来日期 market_scan

curl -s "http://127.0.0.1:8000/api/city/ankara/detail?force_refresh=true&target_date=2026-03-12"

校验支付配置

curl -s http://127.0.0.1:8000/api/payments/config | python3 -m json.tool

查看支付运行态

curl -s http://127.0.0.1:8000/api/payments/runtime | python3 -m json.tool

查看支付异常单

curl -s "http://127.0.0.1:8000/api/ops/payments/incidents?reason=receiver_mismatch" | python3 -m json.tool

查看系统状态

curl -s http://127.0.0.1:8000/api/system/status | python3 -m json.tool

观察支付自动补单

docker compose logs -f polyweather | egrep "payment event loop started|payment confirm loop started|payment auto-confirmed"

10. AGPL 与公开口径说明

本仓库代码自 2026-03-30 起采用 AGPL-3.0-only。对外公开文档仅覆盖通用 API 契约;生产商业策略参数、私有运营阈值与托管服务能力不在公开文档披露。

详见:AGPL-3.0 与商用边界