akg-factor-bridge/api.py

65 lines
2.3 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.

"""桥侧计划 API07-30 用户需求):对外提供每日选股计划。
容器常驻命令改为 uvicorn 后随容器启动docker-compose 已配端口,默认 8300
cron 的 docker exec 构建/出计划照旧互不影响。局域网内部服务v1 无鉴权。
GET /health 存活 + 最新计划日
GET /plan 最新一天的计划JSON
GET /plan?date=2026-07-30 指定日期
GET /plan?format=md Markdown 原文(浏览器直接可读)
GET /plan/dates 可用日期列表
POST /plan/refresh?date=... 重新生成该日计划文件data/plan/*.md
将来接 XXL-JOB / 事件回调,触发器打这层即可,不必进容器。
"""
import pandas as pd
from fastapi import FastAPI, HTTPException
from fastapi.responses import PlainTextResponse
import db
import plan
app = FastAPI(title="akg-factor-bridge · 每日选股计划", version="0.1")
@app.get("/health")
def health():
try:
d = plan._latest_date("t_factor_akg_score") # noqa: SLF001 —— 桥内自用
except Exception as e: # noqa: BLE001 —— 库连不上也要能回答"我还活着"
return {"ok": False, "error": repr(e)}
return {"ok": True, "latest_plan_date": d}
@app.get("/plan/dates")
def plan_dates(limit: int = 30):
df = db.read_mysql(
"factor", "SELECT DISTINCT trade_date FROM t_factor_akg_score "
"ORDER BY trade_date DESC LIMIT %s", (int(limit),))
if df.empty:
return {"dates": []}
return {"dates": [pd.Timestamp(x).date().isoformat()
for x in df["trade_date"]]}
@app.get("/plan")
def get_plan(date: str | None = None, format: str = "json",
top: int = 20, obs_top: int = 10, theme_cap: int = 5):
try:
data = plan.collect(date, top, obs_top, theme_cap)
except RuntimeError as e:
raise HTTPException(status_code=404, detail=str(e))
if format == "md":
return PlainTextResponse(plan.render_md(data),
media_type="text/markdown; charset=utf-8")
return data
@app.post("/plan/refresh")
def refresh(date: str | None = None):
try:
out = plan.generate(date)
except SystemExit as e:
raise HTTPException(status_code=404, detail=str(e))
return {"ok": True, "file": out}