|
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 |
|
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") |
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
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") |
|
|
|
|
|
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 |
|
|