Jitendra12421 commited on
Commit
70f6e35
·
verified ·
1 Parent(s): 1e8bf4c

Upload 5 files

Browse files
app.py CHANGED
@@ -22,6 +22,7 @@ from nifty_backend.runtime import (
22
  refresh_daily_data,
23
  refresh_first5_prediction,
24
  seconds_until_next_ist_run,
 
25
  )
26
 
27
 
@@ -204,6 +205,13 @@ async def refresh_current_session_once() -> None:
204
  print(f"[startup] daily refresh failed: {exc}", flush=True)
205
 
206
 
 
 
 
 
 
 
 
207
  @app.on_event("startup")
208
  async def start_scheduler() -> None:
209
  global market_status
@@ -224,6 +232,7 @@ async def start_scheduler() -> None:
224
  market_status = "Prediction Pending"
225
 
226
  asyncio.create_task(refresh_current_session_once())
 
227
  asyncio.create_task(daily_ist_refresh_loop())
228
 
229
 
 
22
  refresh_daily_data,
23
  refresh_first5_prediction,
24
  seconds_until_next_ist_run,
25
+ warm_dashboard_payload_cache,
26
  )
27
 
28
 
 
205
  print(f"[startup] daily refresh failed: {exc}", flush=True)
206
 
207
 
208
+ async def warm_dashboard_payload_cache_once() -> None:
209
+ try:
210
+ await asyncio.to_thread(warm_dashboard_payload_cache)
211
+ except Exception as exc:
212
+ print(f"[startup] dashboard payload warmup failed: {exc}", flush=True)
213
+
214
+
215
  @app.on_event("startup")
216
  async def start_scheduler() -> None:
217
  global market_status
 
232
  market_status = "Prediction Pending"
233
 
234
  asyncio.create_task(refresh_current_session_once())
235
+ asyncio.create_task(warm_dashboard_payload_cache_once())
236
  asyncio.create_task(daily_ist_refresh_loop())
237
 
238
 
nifty_backend/__pycache__/runtime.cpython-311.pyc CHANGED
Binary files a/nifty_backend/__pycache__/runtime.cpython-311.pyc and b/nifty_backend/__pycache__/runtime.cpython-311.pyc differ
 
nifty_backend/runtime.py CHANGED
@@ -1,9 +1,12 @@
1
  from __future__ import annotations
2
 
3
  import json
 
4
  import sys
 
5
  from dataclasses import dataclass
6
  from datetime import date, datetime, time, timedelta
 
7
  from pathlib import Path
8
  from typing import Any
9
  from zoneinfo import ZoneInfo
@@ -46,7 +49,10 @@ DECISION_OVERLAYS = [
46
  },
47
  ]
48
 
 
49
 
 
 
50
  def _nse_calendar():
51
  if mcal is None:
52
  return None
@@ -58,6 +64,7 @@ def _nse_calendar():
58
  return None
59
 
60
 
 
61
  def trading_schedule(start: date, end: date) -> pd.DataFrame:
62
  calendar = _nse_calendar()
63
  if calendar is None:
@@ -344,7 +351,30 @@ def predict_row(row: pd.DataFrame) -> Prediction:
344
  return prediction
345
 
346
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
  def latest_saved_prediction() -> dict[str, Any]:
 
 
 
 
348
  if LATEST_PATH.exists():
349
  return pd.read_csv(LATEST_PATH).iloc[-1].to_dict()
350
  summary_path = MODEL_DIR / "summary.json"
@@ -387,8 +417,27 @@ def load_test_predictions() -> pd.DataFrame:
387
 
388
 
389
  def dashboard_payload() -> dict[str, Any]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  summary = load_model_summary()
391
- latest = latest_saved_prediction()
392
  test = load_test_predictions()
393
  daily = pd.read_parquet(NIFTY_1D_PATH)
394
  daily["date"] = pd.to_datetime(daily["date"], errors="coerce")
 
1
  from __future__ import annotations
2
 
3
  import json
4
+ import copy
5
  import sys
6
+ import threading
7
  from dataclasses import dataclass
8
  from datetime import date, datetime, time, timedelta
9
+ from functools import lru_cache
10
  from pathlib import Path
11
  from typing import Any
12
  from zoneinfo import ZoneInfo
 
49
  },
50
  ]
51
 
52
+ _dashboard_payload_lock = threading.Lock()
53
 
54
+
55
+ @lru_cache(maxsize=1)
56
  def _nse_calendar():
57
  if mcal is None:
58
  return None
 
64
  return None
65
 
66
 
67
+ @lru_cache(maxsize=64)
68
  def trading_schedule(start: date, end: date) -> pd.DataFrame:
69
  calendar = _nse_calendar()
70
  if calendar is None:
 
351
  return prediction
352
 
353
 
354
+ def _file_cache_key(path: Path) -> tuple[str, int | None, int | None]:
355
+ try:
356
+ stat = path.stat()
357
+ except FileNotFoundError:
358
+ return (str(path), None, None)
359
+ return (str(path), stat.st_mtime_ns, stat.st_size)
360
+
361
+
362
+ @lru_cache(maxsize=16)
363
+ def _latest_saved_prediction_cached(latest_key: tuple[str, int | None, int | None], summary_key: tuple[str, int | None, int | None]) -> dict[str, Any]:
364
+ latest_path = Path(latest_key[0])
365
+ if latest_path.exists():
366
+ return pd.read_csv(latest_path).iloc[-1].to_dict()
367
+ summary_path = Path(summary_key[0])
368
+ if summary_path.exists():
369
+ return json.loads(summary_path.read_text(encoding="utf-8"))
370
+ raise FileNotFoundError("No latest prediction is available yet.")
371
+
372
+
373
  def latest_saved_prediction() -> dict[str, Any]:
374
+ return dict(_latest_saved_prediction_cached(_file_cache_key(LATEST_PATH), _file_cache_key(MODEL_DIR / "summary.json")))
375
+
376
+
377
+ def _latest_saved_prediction_uncached() -> dict[str, Any]:
378
  if LATEST_PATH.exists():
379
  return pd.read_csv(LATEST_PATH).iloc[-1].to_dict()
380
  summary_path = MODEL_DIR / "summary.json"
 
417
 
418
 
419
  def dashboard_payload() -> dict[str, Any]:
420
+ key = (
421
+ _file_cache_key(MODEL_DIR / "summary.json"),
422
+ _file_cache_key(LATEST_PATH),
423
+ _file_cache_key(TEST_PREDICTIONS_PATH),
424
+ _file_cache_key(NIFTY_1D_PATH),
425
+ _file_cache_key(OPENING_DATASET_PATH),
426
+ _file_cache_key(MODEL_DIR / "candidate_results.csv"),
427
+ _file_cache_key(NIFTY_1M_PATH),
428
+ )
429
+ with _dashboard_payload_lock:
430
+ return copy.deepcopy(_dashboard_payload_cached(key))
431
+
432
+
433
+ def warm_dashboard_payload_cache() -> None:
434
+ dashboard_payload()
435
+
436
+
437
+ @lru_cache(maxsize=4)
438
+ def _dashboard_payload_cached(key: tuple[tuple[str, int | None, int | None], ...]) -> dict[str, Any]:
439
  summary = load_model_summary()
440
+ latest = _latest_saved_prediction_uncached()
441
  test = load_test_predictions()
442
  daily = pd.read_parquet(NIFTY_1D_PATH)
443
  daily["date"] = pd.to_datetime(daily["date"], errors="coerce")