LeonardoMdSA commited on
Commit
2c53c82
·
1 Parent(s): 944b0c5

dashboard, routes predict update

Browse files
app/api/routes.py CHANGED
@@ -11,6 +11,7 @@ from app.monitoring.drift import run_drift_check
11
  from app.monitoring.governance import run_governance_checks
12
 
13
  import pandas as pd
 
14
 
15
  templates = Jinja2Templates(directory="app/templates")
16
 
@@ -50,16 +51,52 @@ async def predict_file(
50
  )
51
  })
52
 
53
- # ---- Drift scheduled in background ----
54
  reference_df = pd.read_csv("models/v1/reference_data.csv")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  background_tasks.add_task(
56
- run_drift_check, df[predictor.features], reference_df[predictor.features], "v1"
 
 
 
57
  )
58
 
59
  return JSONResponse({
60
  "n_rows": len(results),
61
  "results": results,
62
- "drift": "scheduled"
63
  })
64
 
65
 
 
11
  from app.monitoring.governance import run_governance_checks
12
 
13
  import pandas as pd
14
+ import numpy as np # needed for handling list/nested drift scores
15
 
16
  templates = Jinja2Templates(directory="app/templates")
17
 
 
51
  )
52
  })
53
 
54
+ # ---- Drift: run once immediately to return chart data ----
55
  reference_df = pd.read_csv("models/v1/reference_data.csv")
56
+
57
+ # run_drift_check returns (report_path, drift_dict)
58
+ _, drift_dict = run_drift_check(df[predictor.features], reference_df[predictor.features], "v1")
59
+
60
+ # Handle float, list/array, or nested dict drift scores safely
61
+ drift_for_chart = []
62
+ for col, score in drift_dict.items():
63
+ score_value = 0.01 # default minimal value
64
+ if isinstance(score, dict):
65
+ numeric_values = []
66
+
67
+ def extract_numbers(d):
68
+ for v in d.values():
69
+ if isinstance(v, (int, float)):
70
+ numeric_values.append(v)
71
+ elif isinstance(v, dict):
72
+ extract_numbers(v)
73
+ elif isinstance(v, (list, np.ndarray)):
74
+ numeric_values.extend([float(x) for x in v if isinstance(x, (int, float))])
75
+
76
+ extract_numbers(score)
77
+ if numeric_values:
78
+ score_value = float(np.mean(numeric_values))
79
+ elif isinstance(score, (list, np.ndarray)):
80
+ score_value = float(np.mean([s for s in score if isinstance(s, (int, float))]))
81
+ elif isinstance(score, (int, float)):
82
+ score_value = float(score)
83
+
84
+ # ensure finite number
85
+ score_value = float(np.nan_to_num(score_value, nan=0.01, posinf=1.0, neginf=0.01))
86
+ drift_for_chart.append({"column": col, "score": max(score_value, 0.01)})
87
+
88
+ # Schedule full drift in background as before
89
  background_tasks.add_task(
90
+ run_drift_check,
91
+ df[predictor.features],
92
+ reference_df[predictor.features],
93
+ "v1"
94
  )
95
 
96
  return JSONResponse({
97
  "n_rows": len(results),
98
  "results": results,
99
+ "drift": drift_for_chart
100
  })
101
 
102
 
app/templates/dashboard.html CHANGED
@@ -32,11 +32,10 @@
32
 
33
  const data = await response.json();
34
 
35
- /* ---- Predictions (FIXED) ---- */
36
  document.getElementById("predictions").innerHTML =
37
- `<pre>${JSON.stringify(data.predictions, null, 2)}</pre>`;
38
 
39
- /* ---- Drift (GUARDED) ---- */
40
  const driftContainer = document.getElementById("drift-chart");
41
  driftContainer.innerHTML = "";
42
 
@@ -65,4 +64,3 @@
65
  </script>
66
  </body>
67
  </html>
68
-
 
32
 
33
  const data = await response.json();
34
 
35
+ /* FIX: API returns `results`, not `predictions` */
36
  document.getElementById("predictions").innerHTML =
37
+ `<pre>${JSON.stringify(data.results, null, 2)}</pre>`;
38
 
 
39
  const driftContainer = document.getElementById("drift-chart");
40
  driftContainer.innerHTML = "";
41
 
 
64
  </script>
65
  </body>
66
  </html>
 
reports/evidently/drift_report.html CHANGED
The diff for this file is too large to render. See raw diff