Spaces:
Runtime error
Runtime error
Update app_routes.py
Browse files- app_routes.py +27 -19
app_routes.py
CHANGED
|
@@ -86,10 +86,10 @@ async def api_ticker_chart(ticker: str, period: str = "1mo"):
|
|
| 86 |
return {"ticker": ticker, "period": period, "data": MarketDataFetcher.fetch_chart_data(ticker, period)}
|
| 87 |
@router.get("/api/trading/leaderboard")
|
| 88 |
async def api_trading_leaderboard(limit: int = 30):
|
| 89 |
-
return await get_trading_leaderboard(_DB_PATH, min(limit, 50))
|
| 90 |
@router.get("/api/trading/stats")
|
| 91 |
async def api_trading_stats():
|
| 92 |
-
return await get_trading_stats(_DB_PATH)
|
| 93 |
@router.get("/api/trading/tickers")
|
| 94 |
async def api_trading_tickers():
|
| 95 |
return {"stocks": STOCK_TICKERS, "crypto": CRYPTO_TICKERS}
|
|
@@ -99,7 +99,7 @@ async def api_strategies():
|
|
| 99 |
return {"strategies": strats, "identity_map": {k: v for k, v in IDENTITY_STRATEGY_MAP.items()}}
|
| 100 |
@router.get("/api/hall-of-fame")
|
| 101 |
async def api_hall_of_fame(period: str = "3d"):
|
| 102 |
-
return await get_hall_of_fame_data(_DB_PATH, period=period, limit=30)
|
| 103 |
@router.post("/api/hall-of-fame/snapshot")
|
| 104 |
async def api_force_snapshot():
|
| 105 |
return {"recorded": await record_profit_snapshots(_DB_PATH)}
|
|
@@ -140,17 +140,20 @@ async def api_target_price(ticker: str):
|
|
| 140 |
return {"ticker": ticker, "error": "no data"}
|
| 141 |
@router.get("/api/news/feed")
|
| 142 |
async def api_news_feed(ticker: str = None, limit: int = 50):
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
|
|
|
|
|
|
|
|
|
| 154 |
@router.post("/api/news/react")
|
| 155 |
async def api_news_react(request: Request):
|
| 156 |
body = await request.json(); email = body.get("email", ""); news_id = body.get("news_id"); emoji = body.get("emoji", "")
|
|
@@ -200,6 +203,9 @@ async def api_deep_analysis(ticker: str):
|
|
| 200 |
except Exception as e: return {"success": False, "error": str(e)}
|
| 201 |
@router.get("/api/analysis/all/summary")
|
| 202 |
async def api_all_analyses():
|
|
|
|
|
|
|
|
|
|
| 203 |
analyses = await load_all_analyses_from_db(_DB_PATH)
|
| 204 |
async with get_db_read(_DB_PATH) as db:
|
| 205 |
col_cursor = await db.execute("PRAGMA table_info(market_prices)")
|
|
@@ -342,11 +348,13 @@ async def api_evolution_leaderboard(limit: int = 20):
|
|
| 342 |
@router.get("/api/sec/dashboard")
|
| 343 |
async def api_sec_dashboard():
|
| 344 |
try:
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
|
|
|
|
|
|
|
| 350 |
except Exception as e:
|
| 351 |
logger.error(f"SEC dashboard error: {e}")
|
| 352 |
return {"stats": {"total_violations": 0, "total_fines_gpu": 0, "active_suspensions": 0, "pending_reports": 0}, "announcements": [], "top_violators": [], "recent_reports": []}
|
|
|
|
| 86 |
return {"ticker": ticker, "period": period, "data": MarketDataFetcher.fetch_chart_data(ticker, period)}
|
| 87 |
@router.get("/api/trading/leaderboard")
|
| 88 |
async def api_trading_leaderboard(limit: int = 30):
|
| 89 |
+
return await _cache.get(f'leaderboard_{min(limit,50)}', 30.0, lambda: get_trading_leaderboard(_DB_PATH, min(limit, 50)))
|
| 90 |
@router.get("/api/trading/stats")
|
| 91 |
async def api_trading_stats():
|
| 92 |
+
return await _cache.get('trading_stats', 30.0, lambda: get_trading_stats(_DB_PATH))
|
| 93 |
@router.get("/api/trading/tickers")
|
| 94 |
async def api_trading_tickers():
|
| 95 |
return {"stocks": STOCK_TICKERS, "crypto": CRYPTO_TICKERS}
|
|
|
|
| 99 |
return {"strategies": strats, "identity_map": {k: v for k, v in IDENTITY_STRATEGY_MAP.items()}}
|
| 100 |
@router.get("/api/hall-of-fame")
|
| 101 |
async def api_hall_of_fame(period: str = "3d"):
|
| 102 |
+
return await _cache.get(f'hof_{period}', 45.0, lambda: get_hall_of_fame_data(_DB_PATH, period=period, limit=30))
|
| 103 |
@router.post("/api/hall-of-fame/snapshot")
|
| 104 |
async def api_force_snapshot():
|
| 105 |
return {"recorded": await record_profit_snapshots(_DB_PATH)}
|
|
|
|
| 140 |
return {"ticker": ticker, "error": "no data"}
|
| 141 |
@router.get("/api/news/feed")
|
| 142 |
async def api_news_feed(ticker: str = None, limit: int = 50):
|
| 143 |
+
cache_key = f'news_feed_{ticker}_{limit}'
|
| 144 |
+
async def _nf_impl():
|
| 145 |
+
news = await load_news_from_db(_DB_PATH, ticker, limit)
|
| 146 |
+
try:
|
| 147 |
+
async with get_db_read(_DB_PATH) as db:
|
| 148 |
+
for n in news:
|
| 149 |
+
nid = n.get('id')
|
| 150 |
+
if nid:
|
| 151 |
+
rc = await db.execute("SELECT emoji, COUNT(*) FROM news_reactions WHERE news_id=? GROUP BY emoji", (nid,))
|
| 152 |
+
n['reactions'] = {r[0]: r[1] for r in await rc.fetchall()}
|
| 153 |
+
else: n['reactions'] = {}
|
| 154 |
+
except: pass
|
| 155 |
+
return {"news": news, "count": len(news)}
|
| 156 |
+
return await _cache.get(cache_key, 30.0, _nf_impl)
|
| 157 |
@router.post("/api/news/react")
|
| 158 |
async def api_news_react(request: Request):
|
| 159 |
body = await request.json(); email = body.get("email", ""); news_id = body.get("news_id"); emoji = body.get("emoji", "")
|
|
|
|
| 203 |
except Exception as e: return {"success": False, "error": str(e)}
|
| 204 |
@router.get("/api/analysis/all/summary")
|
| 205 |
async def api_all_analyses():
|
| 206 |
+
return await _cache.get('all_analyses_summary', 45.0, _all_analyses_impl)
|
| 207 |
+
|
| 208 |
+
async def _all_analyses_impl():
|
| 209 |
analyses = await load_all_analyses_from_db(_DB_PATH)
|
| 210 |
async with get_db_read(_DB_PATH) as db:
|
| 211 |
col_cursor = await db.execute("PRAGMA table_info(market_prices)")
|
|
|
|
| 348 |
@router.get("/api/sec/dashboard")
|
| 349 |
async def api_sec_dashboard():
|
| 350 |
try:
|
| 351 |
+
async def _sec_impl():
|
| 352 |
+
data = await get_sec_dashboard(_DB_PATH)
|
| 353 |
+
if data.get('stats', {}).get('total_violations', 0) == 0:
|
| 354 |
+
seed_r = await api_sec_seed()
|
| 355 |
+
if seed_r.get('success'): data = await get_sec_dashboard(_DB_PATH)
|
| 356 |
+
return data
|
| 357 |
+
return await _cache.get('sec_dashboard', 45.0, _sec_impl)
|
| 358 |
except Exception as e:
|
| 359 |
logger.error(f"SEC dashboard error: {e}")
|
| 360 |
return {"stats": {"total_violations": 0, "total_fines_gpu": 0, "active_suspensions": 0, "pending_reports": 0}, "announcements": [], "top_violators": [], "recent_reports": []}
|