feat(screener): POST /snapshot/refresh-news-sentiment with telegram_text
This commit is contained in:
@@ -276,6 +276,30 @@ def list_runs(limit: int = 30):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- /snapshot/refresh-news-sentiment ----------
|
||||||
|
|
||||||
|
from .ai_news import pipeline as _ai_pipeline
|
||||||
|
from .ai_news import telegram as _ai_telegram
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/snapshot/refresh-news-sentiment")
|
||||||
|
async def post_refresh_news_sentiment(asof: Optional[str] = None):
|
||||||
|
asof_date = dt.date.fromisoformat(asof) if asof else dt.date.today()
|
||||||
|
if asof_date.weekday() >= 5:
|
||||||
|
return {"asof": asof_date.isoformat(), "status": "skipped_weekend"}
|
||||||
|
if _is_holiday(asof_date):
|
||||||
|
return {"asof": asof_date.isoformat(), "status": "skipped_holiday"}
|
||||||
|
with _conn() as c:
|
||||||
|
summary = await _ai_pipeline.refresh_daily(c, asof_date)
|
||||||
|
summary["telegram_text"] = _ai_telegram.build_message(
|
||||||
|
asof=summary["asof"],
|
||||||
|
top_pos=summary["top_pos"], top_neg=summary["top_neg"],
|
||||||
|
tokens_input=summary["tokens_input"],
|
||||||
|
tokens_output=summary["tokens_output"],
|
||||||
|
)
|
||||||
|
return summary
|
||||||
|
|
||||||
|
|
||||||
@router.get("/runs/{run_id}")
|
@router.get("/runs/{run_id}")
|
||||||
def get_run(run_id: int):
|
def get_run(run_id: int):
|
||||||
with _conn() as c:
|
with _conn() as c:
|
||||||
|
|||||||
36
stock-lab/tests/test_ai_news_router.py
Normal file
36
stock-lab/tests/test_ai_news_router.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import datetime as dt
|
||||||
|
from unittest.mock import AsyncMock, patch
|
||||||
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
|
from app.main import app
|
||||||
|
|
||||||
|
|
||||||
|
def test_refresh_news_sentiment_weekend_skip():
|
||||||
|
# 2026-05-16 = Saturday
|
||||||
|
client = TestClient(app)
|
||||||
|
resp = client.post(
|
||||||
|
"/api/stock/screener/snapshot/refresh-news-sentiment?asof=2026-05-16"
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert resp.json()["status"] == "skipped_weekend"
|
||||||
|
|
||||||
|
|
||||||
|
def test_refresh_news_sentiment_weekday_invokes_pipeline():
|
||||||
|
fake_summary = {
|
||||||
|
"asof": "2026-05-13", "updated": 3, "failures": [],
|
||||||
|
"duration_sec": 1.0, "tokens_input": 100, "tokens_output": 20,
|
||||||
|
"top_pos": [], "top_neg": [], "model": "m",
|
||||||
|
}
|
||||||
|
with patch("app.screener.router._ai_pipeline") as mp, \
|
||||||
|
patch("app.screener.router._ai_telegram") as mt:
|
||||||
|
mp.refresh_daily = AsyncMock(return_value=fake_summary)
|
||||||
|
mt.build_message = lambda **kw: "BUILT_TEXT"
|
||||||
|
client = TestClient(app)
|
||||||
|
resp = client.post(
|
||||||
|
"/api/stock/screener/snapshot/refresh-news-sentiment?asof=2026-05-13"
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
body = resp.json()
|
||||||
|
assert body["asof"] == "2026-05-13"
|
||||||
|
assert body["updated"] == 3
|
||||||
|
assert body["telegram_text"] == "BUILT_TEXT"
|
||||||
Reference in New Issue
Block a user