intent-classifier / app /pages /monitoring.py
Prince012's picture
fix: use importlib to load api_client directly from file
556524e
Raw
History Blame Contribute Delete
3.29 kB
import importlib.util
from pathlib import Path
_client_path = Path(__file__).parent.parent / "api_client.py"
_spec = importlib.util.spec_from_file_location("api_client", _client_path)
_module = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(_module)
api_ab_stats = _module.api_ab_stats
api_drift = _module.api_drift
api_reset_monitoring = _module.api_reset_monitoring
require_api = _module.require_api
import streamlit as st
require_api()
st.title("Monitoring Dashboard")
st.caption("Live A/B test stats and data drift detection.")
st.subheader("A/B Test Stats")
if st.button("Refresh stats"):
st.rerun()
try:
stats = api_ab_stats()
col1, col2 = st.columns(2)
with col1:
st.markdown(f"### Model A — `{stats['model_a']['model_name']}`")
st.metric("Requests", stats["model_a"]["request_count"])
st.metric("Avg Latency", f"{stats['model_a']['avg_latency_ms']:.2f} ms")
st.metric("Avg Confidence", f"{stats['model_a']['avg_confidence']:.2%}")
st.metric("OOS Rate", f"{stats['model_a']['oos_rate']:.2%}")
with col2:
st.markdown(f"### Model B — `{stats['model_b']['model_name']}`")
st.metric("Requests", stats["model_b"]["request_count"])
st.metric("Avg Latency", f"{stats['model_b']['avg_latency_ms']:.2f} ms")
st.metric("Avg Confidence", f"{stats['model_b']['avg_confidence']:.2%}")
st.metric("OOS Rate", f"{stats['model_b']['oos_rate']:.2%}")
st.caption(f"Configured split: {stats['split']:.0%} to model B")
except Exception as e:
st.warning(f"No A/B stats yet. Make some predictions on the Predict page first. ({e})")
if st.button("Reset A/B stats"):
api_reset_monitoring()
st.success("Stats reset.")
st.rerun()
st.divider()
st.subheader("Data Drift Report")
st.caption("Compares reference traffic (initial baseline) against recent production traffic.")
if st.button("Run drift check"):
try:
with st.spinner("computing drift..."):
drift = api_drift()
col1, col2, col3 = st.columns(3)
col1.metric("Drifted Columns", int(drift["drift_summary"].get("drifted_columns_count", 0)))
col2.metric(
"Confidence Drop",
f"{drift['confidence_drift']['confidence_drop']:.2%}",
delta=f"{-drift['confidence_drift']['confidence_drop']:.2%}",
)
col3.metric("OOS Rate Increase", f"{drift['oos_rate_drift']['oos_rate_increase']:.2%}")
if drift["confidence_drift"]["is_degraded"]:
st.error("Confidence has degraded significantly vs reference traffic.")
else:
st.success("Confidence is stable vs reference traffic.")
if drift["oos_rate_drift"]["is_anomalous"]:
st.error("OOS rate has increased anomalously — possible topic drift in incoming queries.")
else:
st.success("OOS rate is within normal range.")
with st.expander("Raw drift details"):
st.json(drift)
except Exception as e:
st.warning(
"No reference/current data available yet. Run `verify_phase11.py` first to "
f"generate baseline monitoring data. ({e})"
)