import gradio as gr 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 import os # Configure logging logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") logger = logging.getLogger(__name__) def process_files(*uploaded_files): """Process uploaded CSV files and generate dashboard outputs.""" logger.info(f"Received {len(uploaded_files)} uploaded files.") try: if not uploaded_files: return "Please upload at least one CSV file.", None, None, None, None # Load data df = load_logs(uploaded_files) logger.info(f"Loaded {len(df)} log records from uploaded files.") # Log table log_table = df.head().to_dict(orient="records") # Usage chart fig = plot_usage(df) # Anomalies anomalies = detect_anomalies(df) anomaly_table = anomalies.to_dict(orient="records") if not anomalies.empty else "No anomalies detected." # AMC expiries amc_table = None if "amc_expiry" in df.columns: amc_df = upcoming_amc_devices(df) amc_table = amc_df.to_dict(orient="records") if not amc_df.empty else "No upcoming AMC expiries." else: amc_table = "Column `amc_expiry` not found in uploaded data." logger.warning("Missing `amc_expiry` column in data.") return log_table, fig, anomaly_table, amc_table, df def generate_pdf_report(df): """Generate and return path to PDF report.""" if df is None: return "Please upload CSV files first." logger.info("Generating PDF report...") try: pdf_path = generate_pdf(df) return pdf_path except Exception as e: logger.error(f"Failed to generate PDF: {e}") return f"Error generating PDF: {e}" with gr.Blocks(title="Multi-Device LabOps Dashboard") as demo: gr.Markdown("# 📊 Multi-Device LabOps Dashboard") with gr.Row(): file_input = gr.File(file_count="multiple", file_types=[".csv"], label="Upload Device Logs (CSV)") with gr.Row(): submit_btn = gr.Button("Process Files") with gr.Row(): with gr.Column(): gr.Markdown("## 📋 Uploaded Logs") log_output = gr.Dataframe() with gr.Column(): gr.Markdown("## 📈 Daily Usage Chart") chart_output = gr.Plot() with gr.Row(): with gr.Column(): gr.Markdown("## 🚨 Detected Anomalies") anomaly_output = gr.Dataframe() with gr.Column(): gr.Markdown("## 🛠 Upcoming AMC Devices") amc_output = gr.Dataframe() with gr.Row(): pdf_btn = gr.Button("📄 Generate PDF Report") pdf_output = gr.File(label="Download PDF Report") # State to store dataframe df_state = gr.State() # Connect inputs to outputs submit_btn.click( fn=process_files, inputs=[file_input], outputs=[log_output, chart_output, anomaly_output, amc_output, df_state] ) pdf_btn.click( fn=generate_pdf_report, inputs=[df_state], outputs=[pdf_output] ) if __name__ == "__main__": try: logger.info("Application starting...") demo.launch(server_name="0.0.0.0", server_port=7860) except Exception as e: logger.error(f"Application failed to start: {e}") raise