import sys import streamlit as st import pandas as pd from utils.load_data import load_logs from utils.visualize import plot_usage from utils.report import generate_pdf from models.anomaly import detect_anomalies from utils.amc import upcoming_amc_devices import logging # Configure logging logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") logger = logging.getLogger(__name__) # Streamlit app setup try: st.set_page_config(page_title="LabOps Dashboard", layout="wide") logger.info("Streamlit page configuration set successfully.") except Exception as e: logger.error(f"Failed to configure Streamlit: {e}") raise st.title("📊 Multi-Device LabOps Dashboard") # File uploader try: uploaded_files = st.file_uploader("Upload Device Logs (CSV)", accept_multiple_files=True, type=["csv"]) logger.info(f"Received {len(uploaded_files)} uploaded files.") except Exception as e: logger.error(f"File uploader error: {e}") st.error(f"Failed to initialize file uploader: {e}") if uploaded_files: try: df = load_logs(uploaded_files) logger.info(f"Loaded {len(df)} log records from uploaded files.") st.subheader("📋 Uploaded Logs") st.dataframe(df.head()) st.subheader("📈 Daily Usage Chart") fig = plot_usage(df) st.pyplot(fig) st.subheader("🚨 Detected Anomalies") anomalies = detect_anomalies(df) st.dataframe(anomalies) st.subheader("🛠 Upcoming AMC Devices") if "amc_expiry" in df.columns: amc_df = upcoming_amc_devices(df) st.dataframe(amc_df) else: st.info("Column `amc_expiry` not found in uploaded data.") logger.warning("Missing `amc_expiry` column in data.") if st.button("📄 Generate PDF Report"): pdf_path = generate_pdf(df) with open(pdf_path, "rb") as f: st.download_button("Download PDF", f, file_name="labops_report.pdf", mime="application/pdf") logger.info("PDF report generated and offered for download.") except Exception as e: logger.error(f"Error processing uploaded files: {e}") st.error(f"Failed to process data: {e}") if __name__ == "__main__": try: logger.info("Application starting...") except Exception as e: logger.error(f"Application failed to start: {e}") raise