Spaces:
Running
Running
Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
|
@@ -19,10 +19,10 @@ from charts import (
|
|
| 19 |
chart_outcome_breakdown,
|
| 20 |
chart_queue_efficiency,
|
| 21 |
chart_resource_sizing,
|
|
|
|
| 22 |
chart_usage_by_system,
|
| 23 |
-
chart_wasted_spend,
|
| 24 |
)
|
| 25 |
-
from config import ALLOCATIONS,
|
| 26 |
from data_loader import filter_jobs, load_data
|
| 27 |
|
| 28 |
st.set_page_config(page_title="OSC Usage Dashboard", layout="wide")
|
|
@@ -110,17 +110,7 @@ interactive_dollars = filtered[filtered["launch_method"].isin(INTERACTIVE_METHOD
|
|
| 110 |
].sum()
|
| 111 |
interactive_pct = interactive_dollars / total_spend * 100 if total_spend > 0 else 0
|
| 112 |
|
| 113 |
-
|
| 114 |
-
if "outcome_category" in filtered.columns:
|
| 115 |
-
avoidable_waste = filtered.loc[
|
| 116 |
-
filtered["outcome_category"].isin(AVOIDABLE_WASTE_CATEGORIES), "dollars_used"
|
| 117 |
-
].sum()
|
| 118 |
-
else:
|
| 119 |
-
avoidable_waste = filtered.loc[
|
| 120 |
-
filtered["last_state"].isin({"FAILED", "TIMEOUT", "OUT_OF_MEMORY"}), "dollars_used"
|
| 121 |
-
].sum()
|
| 122 |
-
|
| 123 |
-
m1, m2, m3, m4, m5 = st.columns(5)
|
| 124 |
m1.metric("Total Spend", f"${total_spend:,.2f}", help="Sum of all job costs in the filtered period")
|
| 125 |
m2.metric("Total Jobs", f"{total_jobs:,}", help="Number of jobs in the filtered period")
|
| 126 |
m3.metric(
|
|
@@ -133,11 +123,6 @@ m4.metric(
|
|
| 133 |
f"{interactive_pct:.1f}%",
|
| 134 |
help="% of total dollars spent on interactive sessions (Jupyter, Desktop, Code Server, etc.)",
|
| 135 |
)
|
| 136 |
-
m5.metric(
|
| 137 |
-
"Avoidable Waste",
|
| 138 |
-
f"${avoidable_waste:,.0f}",
|
| 139 |
-
help="Dollars from Quick Exit + Failed + Batch Timed Out + Out of Memory — actionable items only",
|
| 140 |
-
)
|
| 141 |
|
| 142 |
st.divider()
|
| 143 |
|
|
@@ -217,7 +202,7 @@ with tab_health:
|
|
| 217 |
if fig:
|
| 218 |
st.plotly_chart(fig, use_container_width=True)
|
| 219 |
with right:
|
| 220 |
-
fig =
|
| 221 |
if fig:
|
| 222 |
st.plotly_chart(fig, use_container_width=True)
|
| 223 |
|
|
@@ -262,20 +247,11 @@ with tab_user:
|
|
| 262 |
u_batch_total = len(u_batch)
|
| 263 |
u_batch_completed = (u_batch["last_state"] == "COMPLETED").sum()
|
| 264 |
u_batch_pct = u_batch_completed / u_batch_total * 100 if u_batch_total > 0 else 0
|
| 265 |
-
if "outcome_category" in user_df.columns:
|
| 266 |
-
u_waste = user_df.loc[
|
| 267 |
-
user_df["outcome_category"].isin(AVOIDABLE_WASTE_CATEGORIES), "dollars_used"
|
| 268 |
-
].sum()
|
| 269 |
-
else:
|
| 270 |
-
u_waste = user_df.loc[
|
| 271 |
-
user_df["last_state"].isin({"FAILED", "TIMEOUT", "OUT_OF_MEMORY"}), "dollars_used"
|
| 272 |
-
].sum()
|
| 273 |
|
| 274 |
-
um1, um2, um3
|
| 275 |
um1.metric("User Spend", f"${u_spend:,.2f}")
|
| 276 |
um2.metric("User Jobs", f"{u_jobs:,}")
|
| 277 |
um3.metric("Batch Completion %", f"{u_batch_pct:.1f}%")
|
| 278 |
-
um4.metric("Avoidable Waste", f"${u_waste:,.0f}")
|
| 279 |
|
| 280 |
# User charts
|
| 281 |
left, right = st.columns(2)
|
|
|
|
| 19 |
chart_outcome_breakdown,
|
| 20 |
chart_queue_efficiency,
|
| 21 |
chart_resource_sizing,
|
| 22 |
+
chart_spend_by_outcome,
|
| 23 |
chart_usage_by_system,
|
|
|
|
| 24 |
)
|
| 25 |
+
from config import ALLOCATIONS, INTERACTIVE_METHODS, PROJECT_CODES
|
| 26 |
from data_loader import filter_jobs, load_data
|
| 27 |
|
| 28 |
st.set_page_config(page_title="OSC Usage Dashboard", layout="wide")
|
|
|
|
| 110 |
].sum()
|
| 111 |
interactive_pct = interactive_dollars / total_spend * 100 if total_spend > 0 else 0
|
| 112 |
|
| 113 |
+
m1, m2, m3, m4 = st.columns(4)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
m1.metric("Total Spend", f"${total_spend:,.2f}", help="Sum of all job costs in the filtered period")
|
| 115 |
m2.metric("Total Jobs", f"{total_jobs:,}", help="Number of jobs in the filtered period")
|
| 116 |
m3.metric(
|
|
|
|
| 123 |
f"{interactive_pct:.1f}%",
|
| 124 |
help="% of total dollars spent on interactive sessions (Jupyter, Desktop, Code Server, etc.)",
|
| 125 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
|
| 127 |
st.divider()
|
| 128 |
|
|
|
|
| 202 |
if fig:
|
| 203 |
st.plotly_chart(fig, use_container_width=True)
|
| 204 |
with right:
|
| 205 |
+
fig = chart_spend_by_outcome(filtered)
|
| 206 |
if fig:
|
| 207 |
st.plotly_chart(fig, use_container_width=True)
|
| 208 |
|
|
|
|
| 247 |
u_batch_total = len(u_batch)
|
| 248 |
u_batch_completed = (u_batch["last_state"] == "COMPLETED").sum()
|
| 249 |
u_batch_pct = u_batch_completed / u_batch_total * 100 if u_batch_total > 0 else 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 250 |
|
| 251 |
+
um1, um2, um3 = st.columns(3)
|
| 252 |
um1.metric("User Spend", f"${u_spend:,.2f}")
|
| 253 |
um2.metric("User Jobs", f"{u_jobs:,}")
|
| 254 |
um3.metric("Batch Completion %", f"{u_batch_pct:.1f}%")
|
|
|
|
| 255 |
|
| 256 |
# User charts
|
| 257 |
left, right = st.columns(2)
|