Spaces:
Sleeping
Sleeping
Upload 2 files
Browse files- app.py +15 -0
- t5_engine.py +16 -0
app.py
CHANGED
|
@@ -79,6 +79,18 @@ def cron_trigger(background_tasks: BackgroundTasks):
|
|
| 79 |
return {"status": "triggered", "message": "Update and forecast pipeline started in the background."}
|
| 80 |
|
| 81 |
# ββ NEW: T5 Forecaster Endpoints βββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
|
| 83 |
@app.get("/t5/predictions")
|
| 84 |
def get_t5_predictions():
|
|
@@ -88,6 +100,9 @@ def get_t5_predictions():
|
|
| 88 |
|
| 89 |
with open(T5_PREDICTIONS_FILE, "r") as f:
|
| 90 |
data = json.load(f)
|
|
|
|
|
|
|
|
|
|
| 91 |
|
| 92 |
return data
|
| 93 |
|
|
|
|
| 79 |
return {"status": "triggered", "message": "Update and forecast pipeline started in the background."}
|
| 80 |
|
| 81 |
# ββ NEW: T5 Forecaster Endpoints βββββββββββββββββββββββββββββββββββββββββββββ
|
| 82 |
+
import math
|
| 83 |
+
from fastapi.responses import JSONResponse
|
| 84 |
+
|
| 85 |
+
def _sanitize_for_json(obj):
|
| 86 |
+
"""Recursively replace NaN/Inf floats with None for JSON compliance."""
|
| 87 |
+
if isinstance(obj, dict):
|
| 88 |
+
return {k: _sanitize_for_json(v) for k, v in obj.items()}
|
| 89 |
+
elif isinstance(obj, list):
|
| 90 |
+
return [_sanitize_for_json(v) for v in obj]
|
| 91 |
+
elif isinstance(obj, float) and (math.isnan(obj) or math.isinf(obj)):
|
| 92 |
+
return None
|
| 93 |
+
return obj
|
| 94 |
|
| 95 |
@app.get("/t5/predictions")
|
| 96 |
def get_t5_predictions():
|
|
|
|
| 100 |
|
| 101 |
with open(T5_PREDICTIONS_FILE, "r") as f:
|
| 102 |
data = json.load(f)
|
| 103 |
+
|
| 104 |
+
# Sanitize NaN/Inf values that break FastAPI's JSON serializer
|
| 105 |
+
data = _sanitize_for_json(data)
|
| 106 |
|
| 107 |
return data
|
| 108 |
|
t5_engine.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
import os
|
| 2 |
import json
|
|
|
|
| 3 |
import time
|
| 4 |
import requests
|
| 5 |
import pandas as pd
|
|
@@ -8,6 +9,18 @@ from zoneinfo import ZoneInfo
|
|
| 8 |
import pandas_market_calendars as mcal
|
| 9 |
import numpy as np
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
IST = ZoneInfo("Asia/Kolkata")
|
| 12 |
BASE_DIR = os.path.dirname(__file__)
|
| 13 |
DATA_DIR = os.path.join(BASE_DIR, "data")
|
|
@@ -130,6 +143,9 @@ def run_t5_pipeline():
|
|
| 130 |
features['hl_spread'] = (high_5m - low_5m) / open_5m if open_5m else 0
|
| 131 |
features['prev_ret'] = (prev_close - prev_open) / prev_open if prev_open else 0
|
| 132 |
|
|
|
|
|
|
|
|
|
|
| 133 |
# Evaluate rule
|
| 134 |
rule_item = rules_dict.get(ticker)
|
| 135 |
if rule_item:
|
|
|
|
| 1 |
import os
|
| 2 |
import json
|
| 3 |
+
import math
|
| 4 |
import time
|
| 5 |
import requests
|
| 6 |
import pandas as pd
|
|
|
|
| 9 |
import pandas_market_calendars as mcal
|
| 10 |
import numpy as np
|
| 11 |
|
| 12 |
+
|
| 13 |
+
def _sanitize_value(v):
|
| 14 |
+
"""Replace NaN/Inf floats with 0 so JSON serialization doesn't break."""
|
| 15 |
+
if isinstance(v, float) and (math.isnan(v) or math.isinf(v)):
|
| 16 |
+
return 0.0
|
| 17 |
+
return v
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def _sanitize_dict(d):
|
| 21 |
+
"""Recursively sanitize a dict of float values."""
|
| 22 |
+
return {k: _sanitize_dict(v) if isinstance(v, dict) else _sanitize_value(v) for k, v in d.items()}
|
| 23 |
+
|
| 24 |
IST = ZoneInfo("Asia/Kolkata")
|
| 25 |
BASE_DIR = os.path.dirname(__file__)
|
| 26 |
DATA_DIR = os.path.join(BASE_DIR, "data")
|
|
|
|
| 143 |
features['hl_spread'] = (high_5m - low_5m) / open_5m if open_5m else 0
|
| 144 |
features['prev_ret'] = (prev_close - prev_open) / prev_open if prev_open else 0
|
| 145 |
|
| 146 |
+
# Sanitize NaN/Inf values that break JSON serialization
|
| 147 |
+
features = _sanitize_dict(features)
|
| 148 |
+
|
| 149 |
# Evaluate rule
|
| 150 |
rule_item = rules_dict.get(ticker)
|
| 151 |
if rule_item:
|