Update src/streamlit_app.py
Browse files🚀 Stable HF Deployment: SteelAI EAF Intelligence Explorer v3.0
- Added persistent session log separator (timestamped runs)
- Unified tab creation (Download & Logs tabs included upfront)
- Fixed safe metadata filtering for minimal JSONs (no KeyError)
- Fully removed bibliography PDF generation; replaced with clickable URLs
- Enabled self-contained logging inside ./logs with auto-run history
- Updated Streamlit width syntax (compliant with post-2025 deprecation)
- Added sidebar session info (timestamp + directory)
- Dataset + model artifacts remain reproducible & downloadable
- src/streamlit_app.py +19 -3
src/streamlit_app.py
CHANGED
|
@@ -45,6 +45,7 @@ LOG_PATH = os.path.join(LOG_DIR, "run_master.log")
|
|
| 45 |
def log(msg: str):
|
| 46 |
stamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
| 47 |
with open(LOG_PATH, "a", encoding="utf-8") as f:
|
|
|
|
| 48 |
f.write(f"[{stamp}] {msg}\n")
|
| 49 |
print(msg)
|
| 50 |
|
|
@@ -353,13 +354,30 @@ if meta_df["feature_name"].isna().all():
|
|
| 353 |
# Build sidebar safely
|
| 354 |
feat_types = sorted(meta_df["source_type"].dropna().unique().tolist())
|
| 355 |
selected_types = st.sidebar.multiselect("Feature type", feat_types, default=feat_types)
|
| 356 |
-
|
|
|
|
|
|
|
|
|
|
| 357 |
|
| 358 |
numeric_cols = df.select_dtypes(include=[np.number]).columns.tolist()
|
| 359 |
|
| 360 |
# -------------------------
|
| 361 |
# Features tab (robust)
|
| 362 |
# -------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 363 |
with tabs[0]:
|
| 364 |
st.subheader("Feature metadata")
|
| 365 |
st.dataframe(
|
|
@@ -911,7 +929,6 @@ st.markdown("**Notes:** This dataset is synthetic and for demo/prototyping. Real
|
|
| 911 |
|
| 912 |
|
| 913 |
# ----- Download tab
|
| 914 |
-
tabs.append("Download Saved Files")
|
| 915 |
with tabs[-1]:
|
| 916 |
st.subheader(" Download Saved Files (Flat Log Mode)")
|
| 917 |
|
|
@@ -932,7 +949,6 @@ with tabs[-1]:
|
|
| 932 |
|
| 933 |
|
| 934 |
# ----- Logs tab
|
| 935 |
-
tabs.append("View Logs")
|
| 936 |
with tabs[-1]:
|
| 937 |
st.subheader(" Master Log (append-in-place)")
|
| 938 |
if os.path.exists(LOG_PATH):
|
|
|
|
| 45 |
def log(msg: str):
|
| 46 |
stamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
| 47 |
with open(LOG_PATH, "a", encoding="utf-8") as f:
|
| 48 |
+
f.write("\n\n===== New Session Started at {} =====\n".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
|
| 49 |
f.write(f"[{stamp}] {msg}\n")
|
| 50 |
print(msg)
|
| 51 |
|
|
|
|
| 354 |
# Build sidebar safely
|
| 355 |
feat_types = sorted(meta_df["source_type"].dropna().unique().tolist())
|
| 356 |
selected_types = st.sidebar.multiselect("Feature type", feat_types, default=feat_types)
|
| 357 |
+
if "source_type" not in meta_df.columns or meta_df["source_type"].dropna().empty:
|
| 358 |
+
filtered_meta = meta_df.copy()
|
| 359 |
+
else:
|
| 360 |
+
filtered_meta = meta_df[meta_df["source_type"].isin(selected_types)]
|
| 361 |
|
| 362 |
numeric_cols = df.select_dtypes(include=[np.number]).columns.tolist()
|
| 363 |
|
| 364 |
# -------------------------
|
| 365 |
# Features tab (robust)
|
| 366 |
# -------------------------
|
| 367 |
+
|
| 368 |
+
tabs = st.tabs([
|
| 369 |
+
"Features",
|
| 370 |
+
"Visualization",
|
| 371 |
+
"Correlations",
|
| 372 |
+
"Statistics",
|
| 373 |
+
"AutoML + SHAP",
|
| 374 |
+
"Business Impact",
|
| 375 |
+
"Bibliography",
|
| 376 |
+
"Download Saved Files",
|
| 377 |
+
"View Logs"
|
| 378 |
+
])
|
| 379 |
+
|
| 380 |
+
|
| 381 |
with tabs[0]:
|
| 382 |
st.subheader("Feature metadata")
|
| 383 |
st.dataframe(
|
|
|
|
| 929 |
|
| 930 |
|
| 931 |
# ----- Download tab
|
|
|
|
| 932 |
with tabs[-1]:
|
| 933 |
st.subheader(" Download Saved Files (Flat Log Mode)")
|
| 934 |
|
|
|
|
| 949 |
|
| 950 |
|
| 951 |
# ----- Logs tab
|
|
|
|
| 952 |
with tabs[-1]:
|
| 953 |
st.subheader(" Master Log (append-in-place)")
|
| 954 |
if os.path.exists(LOG_PATH):
|