RathodHarish commited on
Commit
7c09a59
·
verified ·
1 Parent(s): 10c0269

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +15 -94
app.py CHANGED
@@ -4,13 +4,11 @@ import plotly.express as px
4
  from sklearn.ensemble import IsolationForest
5
  from reportlab.lib.pagesizes import letter
6
  from reportlab.pdfgen import canvas
7
- from apscheduler.schedulers.background import BackgroundScheduler
8
  from transformers import pipeline
9
  import datetime
10
  import os
11
  import logging
12
  import re
13
- import atexit
14
  import numpy as np
15
  import torch
16
  import tempfile
@@ -50,9 +48,8 @@ except Exception as e:
50
  logger.error(f"Failed to initialize Hugging Face pipeline: {e}")
51
  summarizer = None
52
 
53
- # Global variables to store data
54
  logs = pd.DataFrame()
55
- amc_data = pd.DataFrame()
56
 
57
  # Load logs from uploaded CSV file
58
  def load_logs(logs_file):
@@ -84,41 +81,10 @@ def load_logs(logs_file):
84
  logger.error(f"Error loading logs: {e}")
85
  return pd.DataFrame()
86
 
87
- # Load AMC data from uploaded CSV file (optional)
88
- def load_amc_data(amc_file):
89
- global amc_data
90
- try:
91
- if amc_file is None:
92
- logger.info("No AMC data CSV file uploaded; proceeding without AMC data")
93
- return pd.DataFrame()
94
- # Read CSV from uploaded file
95
- with tempfile.NamedTemporaryFile(delete=False, suffix='.csv') as tmp:
96
- tmp.write(amc_file.read())
97
- tmp_path = tmp.name
98
- amc_data = pd.read_csv(tmp_path)
99
- os.unlink(tmp_path) # Clean up temporary file
100
-
101
- # Validate required columns
102
- required_columns = ['device_id', 'expiry_date']
103
- if not all(col in amc_data.columns for col in required_columns):
104
- logger.error(f"Missing required columns in AMC data: {required_columns}")
105
- return pd.DataFrame()
106
-
107
- amc_data['expiry_date'] = pd.to_datetime(amc_data['expiry_date'], errors='coerce')
108
- if amc_data['expiry_date'].isna().any():
109
- logger.error("Invalid expiry dates detected in AMC data")
110
- return pd.DataFrame()
111
- logger.info("AMC data loaded successfully from uploaded CSV")
112
- return amc_data
113
- except Exception as e:
114
- logger.error(f"Error loading AMC data: {e}")
115
- return pd.DataFrame()
116
-
117
  # Update dropdowns and validate uploads
118
- def update_dropdowns(logs_file, amc_file):
119
- global logs, amc_data
120
  logs = load_logs(logs_file)
121
- amc_data = load_amc_data(amc_file)
122
 
123
  if logs.empty:
124
  return (
@@ -128,13 +94,9 @@ def update_dropdowns(logs_file, amc_file):
128
  False # Disable Generate Dashboard button
129
  )
130
 
131
- lab_choices = logs['lab_id'].unique().tolist()
132
- equipment_choices = logs['type'].unique().tolist()
133
  upload_status = "<p style='color: green;'>Logs loaded successfully.</p>"
134
- if amc_data.empty:
135
- upload_status += "<p style='color: orange;'>No AMC data uploaded; AMC expiry alerts will be unavailable.</p>"
136
- else:
137
- upload_status += "<p style='color: green;'>AMC data loaded successfully.</p>"
138
 
139
  return (
140
  gr.Dropdown(choices=lab_choices, value=lab_choices[0] if lab_choices else None, label="Select Lab"),
@@ -158,26 +120,6 @@ def detect_anomalies(logs):
158
  logger.error(f"Error in anomaly detection: {e}")
159
  return logs
160
 
161
- # AMC expiry checker
162
- def check_amc_expiry():
163
- try:
164
- if amc_data.empty:
165
- logger.info("No AMC data available; skipping expiry check")
166
- return None
167
- today = pd.to_datetime("today").normalize()
168
- expiries = amc_data[amc_data['expiry_date'] <= (today + pd.Timedelta(days=14))]
169
- logger.info("AMC expiry check completed")
170
- return expiries if not expiries.empty else None
171
- except Exception as e:
172
- logger.error(f"Error in AMC expiry check: {e}")
173
- return None
174
-
175
- # Scheduler
176
- scheduler = BackgroundScheduler()
177
- scheduler.add_job(check_amc_expiry, 'interval', days=1)
178
- scheduler.start()
179
- atexit.register(lambda: scheduler.shutdown())
180
-
181
  # Generate text summary using Hugging Face
182
  def generate_text_summary(logs):
183
  if summarizer is None or logs.empty:
@@ -196,7 +138,7 @@ def generate_text_summary(logs):
196
  return f"Error generating summary: {str(e)}"
197
 
198
  # Generate executive insights
199
- def generate_executive_insights(logs, anomalies, amc_expiries):
200
  if summarizer is None or logs.empty:
201
  return "No executive insights available due to missing data or model initialization."
202
  try:
@@ -209,17 +151,12 @@ def generate_executive_insights(logs, anomalies, amc_expiries):
209
  f"Device {row['device_id']} showed anomalous usage count {row['usage_count']} on {row['timestamp'].strftime('%Y-%m-%d %H:%M:%S')}."
210
  for _, row in anomalies.iterrows()
211
  ) if not anomalies.empty else "No anomalies detected."
212
- amc_text = "\n".join(
213
- f"Device {row['device_id']} has AMC expiring on {row['expiry_date'].strftime('%Y-%m-%d')}."
214
- for _, row in amc_expiries.iterrows()
215
- ) if amc_expiries is not None else "No AMC expiries within 2 weeks."
216
 
217
  prompt = (
218
  f"Summarize the following lab operations data into concise executive insights:\n\n"
219
  f"Logs:\n{log_text}\n\n"
220
  f"Anomalies:\n{anomaly_text}\n\n"
221
- f"AMC Expiries:\n{amc_text}\n\n"
222
- f"Provide high-level insights for lab managers, focusing on operational status, issues, and upcoming maintenance needs."
223
  )
224
 
225
  insights = summarizer(prompt, max_length=200, min_length=50, do_sample=False)[0]['summary_text']
@@ -306,8 +243,7 @@ def render_dashboard(lab, equipment_type, start_date, end_date):
306
  return (
307
  "<p style='color: red;'>Please select both Lab and Equipment Type.</p>",
308
  None, None, "<p style='color: red;'>Invalid input</p>",
309
- "<p style='color: red;'>Invalid input</p>", None,
310
- "No summary available.", "No insights available.",
311
  "\n".join(log_messages[-10:]) or "No logs available."
312
  )
313
 
@@ -338,8 +274,7 @@ def render_dashboard(lab, equipment_type, start_date, end_date):
338
  return (
339
  "<p style='color: orange;'>No devices found for the selected filters.</p>",
340
  None, None, "<p>No anomalies detected.</p>",
341
- "<p>No AMC expiries within 2 weeks.</p>", None,
342
- "No summary available.", "No insights available.",
343
  "\n".join(log_messages[-10:]) or "No logs available."
344
  )
345
 
@@ -396,17 +331,9 @@ def render_dashboard(lab, equipment_type, start_date, end_date):
396
  border=0
397
  ) if not anomalies.empty else "<p>No anomalies detected.</p>"
398
 
399
- # AMC Expiry Alerts
400
- amc_expiries = check_amc_expiry()
401
- amc_alerts = amc_expiries[['device_id', 'expiry_date']].to_html(
402
- index=False,
403
- classes="table table-striped",
404
- border=0
405
- ) if amc_expiries is not None else "<p>No AMC expiries within 2 weeks.</p>"
406
-
407
  # Generate summary and insights
408
  summary = generate_text_summary(filtered_logs)
409
- insights = generate_executive_insights(filtered_logs, anomalies, amc_expiries)
410
 
411
  # PDF Download
412
  pdf_data = generate_pdf(lab, equipment_type, filtered_logs, summary, insights)
@@ -420,7 +347,6 @@ def render_dashboard(lab, equipment_type, start_date, end_date):
420
  fig_usage,
421
  fig_uptime,
422
  anomaly_table,
423
- amc_alerts,
424
  pdf_data,
425
  summary,
426
  insights,
@@ -434,7 +360,6 @@ def render_dashboard(lab, equipment_type, start_date, end_date):
434
  None,
435
  None,
436
  "<p style='color: red;'>Error</p>",
437
- "<p style='color: red;'>Error</p>",
438
  None,
439
  "Error generating summary.",
440
  "Error generating insights.",
@@ -456,11 +381,9 @@ with gr.Blocks(
456
 
457
  # File Upload
458
  with gr.Group():
459
- gr.Markdown("### Upload Data Files")
460
- gr.Markdown("**Note**: Uploading logs.csv is required. Uploading amc_data.csv is optional for AMC expiry alerts.")
461
- with gr.Row():
462
- logs_file = gr.File(label="Upload Logs CSV (Required)", file_types=[".csv"])
463
- amc_file = gr.File(label="Upload AMC Data CSV (Optional)", file_types=[".csv"])
464
  upload_btn = gr.Button("Load Data", variant="primary", elem_classes="submit-btn")
465
  upload_status = gr.HTML(label="Upload Status")
466
 
@@ -507,8 +430,6 @@ with gr.Blocks(
507
  uptime_chart = gr.Plot(label="Weekly Uptime %")
508
  with gr.Tab("Anomaly Alerts"):
509
  anomaly_table = gr.HTML(label="Anomaly Alerts")
510
- with gr.Tab("AMC Expiry Alerts"):
511
- amc_alerts = gr.HTML(label="AMC Expiry Alerts")
512
  with gr.Tab("Summary"):
513
  summary_output = gr.Textbox(label="Log Summary", lines=5, interactive=False)
514
  with gr.Tab("Executive Insights"):
@@ -519,13 +440,13 @@ with gr.Blocks(
519
  # Update dropdowns on file upload
520
  upload_btn.click(
521
  fn=update_dropdowns,
522
- inputs=[logs_file, amc_file],
523
  outputs=[lab, equipment_type, upload_status, submit_btn]
524
  )
525
 
526
  # Update dashboard on submit
527
  inputs = [lab, equipment_type, start_date, end_date]
528
- outputs = [device_cards, usage_chart, uptime_chart, anomaly_table, amc_alerts, pdf_download, summary_output, insights_output, log_display]
529
  submit_btn.click(render_dashboard, inputs=inputs, outputs=outputs)
530
 
531
  # Launch Gradio app
 
4
  from sklearn.ensemble import IsolationForest
5
  from reportlab.lib.pagesizes import letter
6
  from reportlab.pdfgen import canvas
 
7
  from transformers import pipeline
8
  import datetime
9
  import os
10
  import logging
11
  import re
 
12
  import numpy as np
13
  import torch
14
  import tempfile
 
48
  logger.error(f"Failed to initialize Hugging Face pipeline: {e}")
49
  summarizer = None
50
 
51
+ # Global variable to store logs data
52
  logs = pd.DataFrame()
 
53
 
54
  # Load logs from uploaded CSV file
55
  def load_logs(logs_file):
 
81
  logger.error(f"Error loading logs: {e}")
82
  return pd.DataFrame()
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  # Update dropdowns and validate uploads
85
+ def update_dropdowns(logs_file):
86
+ global logs
87
  logs = load_logs(logs_file)
 
88
 
89
  if logs.empty:
90
  return (
 
94
  False # Disable Generate Dashboard button
95
  )
96
 
97
+ lab_choices = sorted(logs['lab_id'].unique().tolist()) # Sort for better UX
98
+ equipment_choices = sorted(logs['type'].unique().tolist()) # Sort for better UX
99
  upload_status = "<p style='color: green;'>Logs loaded successfully.</p>"
 
 
 
 
100
 
101
  return (
102
  gr.Dropdown(choices=lab_choices, value=lab_choices[0] if lab_choices else None, label="Select Lab"),
 
120
  logger.error(f"Error in anomaly detection: {e}")
121
  return logs
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  # Generate text summary using Hugging Face
124
  def generate_text_summary(logs):
125
  if summarizer is None or logs.empty:
 
138
  return f"Error generating summary: {str(e)}"
139
 
140
  # Generate executive insights
141
+ def generate_executive_insights(logs, anomalies):
142
  if summarizer is None or logs.empty:
143
  return "No executive insights available due to missing data or model initialization."
144
  try:
 
151
  f"Device {row['device_id']} showed anomalous usage count {row['usage_count']} on {row['timestamp'].strftime('%Y-%m-%d %H:%M:%S')}."
152
  for _, row in anomalies.iterrows()
153
  ) if not anomalies.empty else "No anomalies detected."
 
 
 
 
154
 
155
  prompt = (
156
  f"Summarize the following lab operations data into concise executive insights:\n\n"
157
  f"Logs:\n{log_text}\n\n"
158
  f"Anomalies:\n{anomaly_text}\n\n"
159
+ f"Provide high-level insights for lab managers, focusing on operational status and issues."
 
160
  )
161
 
162
  insights = summarizer(prompt, max_length=200, min_length=50, do_sample=False)[0]['summary_text']
 
243
  return (
244
  "<p style='color: red;'>Please select both Lab and Equipment Type.</p>",
245
  None, None, "<p style='color: red;'>Invalid input</p>",
246
+ None, "No summary available.", "No insights available.",
 
247
  "\n".join(log_messages[-10:]) or "No logs available."
248
  )
249
 
 
274
  return (
275
  "<p style='color: orange;'>No devices found for the selected filters.</p>",
276
  None, None, "<p>No anomalies detected.</p>",
277
+ None, "No summary available.", "No insights available.",
 
278
  "\n".join(log_messages[-10:]) or "No logs available."
279
  )
280
 
 
331
  border=0
332
  ) if not anomalies.empty else "<p>No anomalies detected.</p>"
333
 
 
 
 
 
 
 
 
 
334
  # Generate summary and insights
335
  summary = generate_text_summary(filtered_logs)
336
+ insights = generate_executive_insights(filtered_logs, anomalies)
337
 
338
  # PDF Download
339
  pdf_data = generate_pdf(lab, equipment_type, filtered_logs, summary, insights)
 
347
  fig_usage,
348
  fig_uptime,
349
  anomaly_table,
 
350
  pdf_data,
351
  summary,
352
  insights,
 
360
  None,
361
  None,
362
  "<p style='color: red;'>Error</p>",
 
363
  None,
364
  "Error generating summary.",
365
  "Error generating insights.",
 
381
 
382
  # File Upload
383
  with gr.Group():
384
+ gr.Markdown("### Upload Data File")
385
+ gr.Markdown("**Note**: Please upload a logs.csv file to proceed.")
386
+ logs_file = gr.File(label="Upload Logs CSV (Required)", file_types=[".csv"])
 
 
387
  upload_btn = gr.Button("Load Data", variant="primary", elem_classes="submit-btn")
388
  upload_status = gr.HTML(label="Upload Status")
389
 
 
430
  uptime_chart = gr.Plot(label="Weekly Uptime %")
431
  with gr.Tab("Anomaly Alerts"):
432
  anomaly_table = gr.HTML(label="Anomaly Alerts")
 
 
433
  with gr.Tab("Summary"):
434
  summary_output = gr.Textbox(label="Log Summary", lines=5, interactive=False)
435
  with gr.Tab("Executive Insights"):
 
440
  # Update dropdowns on file upload
441
  upload_btn.click(
442
  fn=update_dropdowns,
443
+ inputs=[logs_file],
444
  outputs=[lab, equipment_type, upload_status, submit_btn]
445
  )
446
 
447
  # Update dashboard on submit
448
  inputs = [lab, equipment_type, start_date, end_date]
449
+ outputs = [device_cards, usage_chart, uptime_chart, anomaly_table, pdf_download, summary_output, insights_output, log_display]
450
  submit_btn.click(render_dashboard, inputs=inputs, outputs=outputs)
451
 
452
  # Launch Gradio app