Spaces:
Sleeping
Sleeping
| 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})" | |
| ) |