MaheshP98's picture
Update app.py
0d752e6 verified
raw
history blame
5.3 kB
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 uploaded files: {uploaded_files}")
# Handle Gradio's File component output: may be a tuple/list of lists
if not uploaded_files:
logger.warning("No files uploaded.")
return "Please upload at least one valid CSV file.", None, None, None, None
# Flatten the structure: uploaded_files might be (['path'],) or ['path']
if isinstance(uploaded_files, (tuple, list)) and len(uploaded_files) > 0:
if isinstance(uploaded_files[0], list):
valid_files = uploaded_files[0] # Extract the inner list
else:
valid_files = uploaded_files
else:
valid_files = []
# Filter out None values and ensure we have valid files
valid_files = [f for f in valid_files if f is not None]
if not valid_files:
logger.warning("No valid files after filtering.")
return "Please upload at least one valid CSV file.", None, None, None, None
logger.info(f"Processing {len(valid_files)} valid files: {valid_files}")
try:
# Load data
df = load_logs(valid_files)
logger.info(f"Loaded {len(df)} log records from uploaded files.")
# Log table
log_table = df.head().to_dict(orient="records")
# Usage chart
logger.info("Generating usage plot...")
fig = plot_usage(df)
logger.info("Usage plot generated successfully.")
# Anomalies
anomaly_table = "Anomaly detection failed."
try:
anomalies = detect_anomalies(df)
anomaly_table = anomalies.to_dict(orient="records") if not anomalies.empty else "No anomalies detected."
except Exception as e:
logger.error(f"Anomaly detection failed: {e}")
# AMC expiries
amc_table = None
try:
if "amc_expiry" in df.columns:
logger.info("Processing AMC expiries...")
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.")
except Exception as e:
logger.error(f"AMC processing failed: {e}")
amc_table = f"Error processing AMC expiries: {e}"
return log_table, fig, anomaly_table, amc_table, df
except Exception as e:
logger.error(f"Error processing files: {e}")
return f"Error: {e}", None, None, None, None
def generate_pdf_report(df):
"""Generate and return path to PDF report, with error message if applicable."""
if df is None:
logger.warning("No data available for PDF generation.")
return None, "Please upload CSV files first."
logger.info("Generating PDF report...")
try:
pdf_path = generate_pdf(df)
return pdf_path, "PDF generated successfully."
except Exception as e:
logger.error(f"Failed to generate PDF: {e}")
return None, 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")
pdf_message = gr.Textbox(label="PDF Generation Status")
# 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, pdf_message]
)
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