RathodHarish commited on
Commit
52b8c70
·
verified ·
1 Parent(s): a814e38

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +17 -92
app.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- LabOps Log Analyzer Dashboard with CSV file upload, PDF generation, Salesforce integration, and AMC reminder email alerts
3
  """
4
  import gradio as gr
5
  import pandas as pd
@@ -13,9 +13,6 @@ from concurrent.futures import ThreadPoolExecutor
13
  from simple_salesforce import Salesforce
14
  import os
15
  import json
16
- import smtplib
17
- from email.mime.text import MIMEText
18
- from email.mime.multipart import MIMEMultipart
19
 
20
  # Configure logging
21
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
@@ -33,14 +30,6 @@ except Exception as e:
33
  logging.error(f"Failed to connect to Salesforce: {str(e)}")
34
  sf = None
35
 
36
- # Email configuration (using environment variables)
37
- SMTP_SERVER = os.getenv('SMTP_SERVER', 'smtp.gmail.com')
38
- SMTP_PORT = int(os.getenv('SMTP_PORT', 587))
39
- SMTP_USERNAME = os.getenv('harishkumarr@sathkrutha.com') # e.g., your-email@gmail.com
40
- SMTP_PASSWORD = os.getenv('Harish@048') # App-specific password if using Gmail
41
- EMAIL_FROM = os.getenv('LabOpsDashboard', SMTP_USERNAME)
42
- EMAIL_TO = "harishkumarr@sathkrutha.com"
43
-
44
  # Try to import reportlab
45
  try:
46
  from reportlab.lib.pagesizes import letter
@@ -129,59 +118,6 @@ def get_folder_id(folder_name):
129
  # Cache the folder ID at startup
130
  LABOPS_REPORTS_FOLDER_ID = get_folder_id('LabOps Reports')
131
 
132
- # Send AMC reminder emails
133
- def send_amc_reminder_emails(reminders_df):
134
- if reminders_df.empty:
135
- logging.info("No AMC reminders to send via email.")
136
- return "No AMC reminder emails sent (no reminders found)."
137
-
138
- if not all([SMTP_USERNAME, SMTP_PASSWORD, EMAIL_FROM]):
139
- logging.error("SMTP credentials not configured. Please set SMTP_USERNAME, SMTP_PASSWORD, and EMAIL_FROM environment variables.")
140
- return "Failed to send emails: SMTP credentials not configured."
141
-
142
- try:
143
- # Set up the SMTP server
144
- server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
145
- server.starttls()
146
- server.login(SMTP_USERNAME, SMTP_PASSWORD)
147
-
148
- email_results = []
149
- for _, row in reminders_df.iterrows():
150
- device_id = row['device_id']
151
- amc_date = row['amc_date'].strftime('%Y-%m-%d')
152
-
153
- # Create the email
154
- msg = MIMEMultipart()
155
- msg['From'] = EMAIL_FROM
156
- msg['To'] = EMAIL_TO
157
- msg['Subject'] = f"AMC Reminder for Device {device_id}"
158
-
159
- body = f"""
160
- Dear Harish Kumar,
161
-
162
- This is a reminder that the Annual Maintenance Contract (AMC) for the following device is due:
163
-
164
- - Device ID: {device_id}
165
- - AMC Date: {amc_date}
166
-
167
- Please schedule the maintenance at your earliest convenience.
168
-
169
- Best regards,
170
- LabOps Team
171
- """
172
- msg.attach(MIMEText(body, 'plain'))
173
-
174
- # Send the email
175
- server.sendmail(EMAIL_FROM, EMAIL_TO, msg.as_string())
176
- logging.info(f"AMC reminder email sent for Device ID {device_id} to {EMAIL_TO}")
177
- email_results.append(f"Sent AMC reminder for Device ID {device_id}")
178
-
179
- server.quit()
180
- return "\n".join(email_results) if email_results else "No emails sent."
181
- except Exception as e:
182
- logging.error(f"Failed to send AMC reminder emails: {str(e)}")
183
- return f"Failed to send AMC reminder emails: {str(e)}"
184
-
185
  # Create Salesforce reports (Usage and AMC Reminders)
186
  def create_salesforce_reports(df):
187
  if sf is None:
@@ -343,25 +279,25 @@ def detect_anomalies(df, progress=gr.Progress()):
343
  logging.error(f"Anomaly detection failed: {str(e)}")
344
  return f"Anomaly detection failed: {str(e)}"
345
 
346
- # AMC reminders (identify records for email and display)
347
  def check_amc_reminders(df, current_date, progress=gr.Progress()):
348
  progress(0.6, "Checking AMC reminders...")
349
  try:
350
  if "device_id" not in df.columns or "amc_date" not in df.columns:
351
- return "AMC reminders require 'device_id' and 'amc_date' columns.", pd.DataFrame()
352
  df["amc_date"] = pd.to_datetime(df["amc_date"], errors='coerce')
353
  current_date = pd.to_datetime(current_date)
354
  df["days_to_amc"] = (df["amc_date"] - current_date).dt.days
355
  reminders = df[(df["days_to_amc"] >= 0) & (df["days_to_amc"] <= 30)][["device_id", "amc_date"]]
356
  if reminders.empty:
357
- return "No AMC reminders due within the next 30 days.", reminders
358
  reminder_lines = ["Upcoming AMC Reminders:"]
359
  for _, row in reminders.head(5).iterrows():
360
  reminder_lines.append(f"- Device ID: {row['device_id']}, AMC Date: {row['amc_date']}")
361
- return "\n".join(reminder_lines), reminders
362
  except Exception as e:
363
  logging.error(f"AMC reminder generation failed: {str(e)}")
364
- return f"AMC reminder generation failed: {str(e)}", pd.DataFrame()
365
 
366
  # Dashboard insights
367
  def generate_dashboard_insights(df, progress=gr.Progress()):
@@ -406,7 +342,7 @@ def create_usage_chart(df, progress=gr.Progress()):
406
  return None
407
 
408
  # Generate PDF content
409
- def generate_pdf_content(summary, preview, anomalies, amc_reminders, insights, email_status):
410
  if not reportlab_available:
411
  return None
412
  try:
@@ -438,10 +374,6 @@ def generate_pdf_content(summary, preview, anomalies, amc_reminders, insights, e
438
  story.append(safe_paragraph(amc_reminders or "No AMC reminders.", styles['Normal']))
439
  story.append(Spacer(1, 12))
440
 
441
- story.append(Paragraph("Email Notification Status", styles['Heading2']))
442
- story.append(safe_paragraph(email_status or "No emails sent.", styles['Normal']))
443
- story.append(Spacer(1, 12))
444
-
445
  story.append(Paragraph("Dashboard Insights", styles['Heading2']))
446
  story.append(safe_paragraph(insights or "No insights generated.", styles['Normal']))
447
 
@@ -457,13 +389,13 @@ async def process_logs(file_obj, progress=gr.Progress()):
457
  try:
458
  progress(0, "Starting file processing...")
459
  if not file_obj:
460
- return "No file uploaded.", "No data to preview.", None, "No anomalies detected.", "No AMC reminders.", "No insights generated.", None, "No Salesforce data saved.", "No report created.", "No emails sent."
461
 
462
  file_name = file_obj.name
463
  logging.info(f"Processing file: {file_name}")
464
 
465
  if not file_name.endswith(".csv"):
466
- return "Please upload a CSV file.", "", None, "", "", "", None, "", "", ""
467
 
468
  required_columns = ["device_id", "log_type", "status", "timestamp", "usage_hours", "downtime", "amc_date"]
469
  dtypes = {
@@ -477,11 +409,11 @@ async def process_logs(file_obj, progress=gr.Progress()):
477
  df = pd.read_csv(file_obj, dtype=dtypes)
478
  missing_columns = [col for col in required_columns if col not in df.columns]
479
  if missing_columns:
480
- return f"Missing columns: {missing_columns}", None, None, None, None, None, None, None, None, None
481
  df["timestamp"] = pd.to_datetime(df["timestamp"], errors='coerce')
482
  df["amc_date"] = pd.to_datetime(df["amc_date"], errors='coerce')
483
  if df.empty:
484
- return "No data available.", None, None, None, None, None, None, None, None, None
485
 
486
  with ThreadPoolExecutor() as executor:
487
  future_summary = executor.submit(summarize_logs, df)
@@ -493,8 +425,7 @@ async def process_logs(file_obj, progress=gr.Progress()):
493
 
494
  summary = f"Step 1: Summary Report\n{future_summary.result()}"
495
  anomalies = f"Anomaly Detection\n{future_anomalies.result()}"
496
- amc_reminders, reminders_df = future_amc.result() # Get both display text and DataFrame
497
- amc_reminders = f"AMC Reminders\n{amc_reminders}"
498
  insights = f"Dashboard Insights (AI)\n{future_insights.result()}"
499
  chart = future_chart.result()
500
  report_result = future_reports.result()
@@ -510,14 +441,13 @@ async def process_logs(file_obj, progress=gr.Progress()):
510
  preview = "\n".join(preview_lines)
511
 
512
  salesforce_result = save_to_salesforce(df, summary, anomalies, amc_reminders, insights)
513
- email_status = send_amc_reminder_emails(reminders_df)
514
- pdf_file = generate_pdf_content(summary, preview, anomalies, amc_reminders, insights, email_status)
515
 
516
  progress(1.0, "Done!")
517
- return summary, preview, chart, anomalies, amc_reminders, insights, pdf_file, salesforce_result, report_result, email_status
518
  except Exception as e:
519
  logging.error(f"Failed to process file: {str(e)}")
520
- return f"Error: {str(e)}", None, None, None, None, None, None, None, None, None
521
 
522
  # Gradio Interface
523
  try:
@@ -531,7 +461,7 @@ try:
531
  .dashboard-section ul {margin: 2px 0; padding-left: 20px;}
532
  """) as iface:
533
  gr.Markdown("<h1>LabOps Log Analyzer Dashboard (Hugging Face AI)</h1>")
534
- gr.Markdown("Upload a CSV file to analyze, generate Salesforce reports, and send AMC reminder emails.")
535
 
536
  with gr.Row():
537
  with gr.Column(scale=1):
@@ -566,10 +496,6 @@ try:
566
  gr.Markdown("### Step 6: Insights (AI)")
567
  insights_output = gr.Markdown()
568
 
569
- with gr.Group(elem_classes="dashboard-section"):
570
- gr.Markdown("### Step 7: Email Notification Status")
571
- email_output = gr.Markdown()
572
-
573
  with gr.Group(elem_classes="dashboard-section"):
574
  gr.Markdown("### Salesforce Integration")
575
  salesforce_output = gr.Markdown()
@@ -594,8 +520,7 @@ try:
594
  insights_output,
595
  pdf_output,
596
  salesforce_output,
597
- report_output,
598
- email_output
599
  ]
600
  )
601
 
 
1
  """
2
+ LabOps Log Analyzer Dashboard with CSV file upload, PDF generation, and Salesforce integration
3
  """
4
  import gradio as gr
5
  import pandas as pd
 
13
  from simple_salesforce import Salesforce
14
  import os
15
  import json
 
 
 
16
 
17
  # Configure logging
18
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
 
30
  logging.error(f"Failed to connect to Salesforce: {str(e)}")
31
  sf = None
32
 
 
 
 
 
 
 
 
 
33
  # Try to import reportlab
34
  try:
35
  from reportlab.lib.pagesizes import letter
 
118
  # Cache the folder ID at startup
119
  LABOPS_REPORTS_FOLDER_ID = get_folder_id('LabOps Reports')
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  # Create Salesforce reports (Usage and AMC Reminders)
122
  def create_salesforce_reports(df):
123
  if sf is None:
 
279
  logging.error(f"Anomaly detection failed: {str(e)}")
280
  return f"Anomaly detection failed: {str(e)}"
281
 
282
+ # AMC reminders (identify records for display)
283
  def check_amc_reminders(df, current_date, progress=gr.Progress()):
284
  progress(0.6, "Checking AMC reminders...")
285
  try:
286
  if "device_id" not in df.columns or "amc_date" not in df.columns:
287
+ return "AMC reminders require 'device_id' and 'amc_date' columns."
288
  df["amc_date"] = pd.to_datetime(df["amc_date"], errors='coerce')
289
  current_date = pd.to_datetime(current_date)
290
  df["days_to_amc"] = (df["amc_date"] - current_date).dt.days
291
  reminders = df[(df["days_to_amc"] >= 0) & (df["days_to_amc"] <= 30)][["device_id", "amc_date"]]
292
  if reminders.empty:
293
+ return "No AMC reminders due within the next 30 days."
294
  reminder_lines = ["Upcoming AMC Reminders:"]
295
  for _, row in reminders.head(5).iterrows():
296
  reminder_lines.append(f"- Device ID: {row['device_id']}, AMC Date: {row['amc_date']}")
297
+ return "\n".join(reminder_lines)
298
  except Exception as e:
299
  logging.error(f"AMC reminder generation failed: {str(e)}")
300
+ return f"AMC reminder generation failed: {str(e)}"
301
 
302
  # Dashboard insights
303
  def generate_dashboard_insights(df, progress=gr.Progress()):
 
342
  return None
343
 
344
  # Generate PDF content
345
+ def generate_pdf_content(summary, preview, anomalies, amc_reminders, insights):
346
  if not reportlab_available:
347
  return None
348
  try:
 
374
  story.append(safe_paragraph(amc_reminders or "No AMC reminders.", styles['Normal']))
375
  story.append(Spacer(1, 12))
376
 
 
 
 
 
377
  story.append(Paragraph("Dashboard Insights", styles['Heading2']))
378
  story.append(safe_paragraph(insights or "No insights generated.", styles['Normal']))
379
 
 
389
  try:
390
  progress(0, "Starting file processing...")
391
  if not file_obj:
392
+ return "No file uploaded.", "No data to preview.", None, "No anomalies detected.", "No AMC reminders.", "No insights generated.", None, "No Salesforce data saved.", "No report created."
393
 
394
  file_name = file_obj.name
395
  logging.info(f"Processing file: {file_name}")
396
 
397
  if not file_name.endswith(".csv"):
398
+ return "Please upload a CSV file.", "", None, "", "", "", None, "", ""
399
 
400
  required_columns = ["device_id", "log_type", "status", "timestamp", "usage_hours", "downtime", "amc_date"]
401
  dtypes = {
 
409
  df = pd.read_csv(file_obj, dtype=dtypes)
410
  missing_columns = [col for col in required_columns if col not in df.columns]
411
  if missing_columns:
412
+ return f"Missing columns: {missing_columns}", None, None, None, None, None, None, None, None
413
  df["timestamp"] = pd.to_datetime(df["timestamp"], errors='coerce')
414
  df["amc_date"] = pd.to_datetime(df["amc_date"], errors='coerce')
415
  if df.empty:
416
+ return "No data available.", None, None, None, None, None, None, None, None
417
 
418
  with ThreadPoolExecutor() as executor:
419
  future_summary = executor.submit(summarize_logs, df)
 
425
 
426
  summary = f"Step 1: Summary Report\n{future_summary.result()}"
427
  anomalies = f"Anomaly Detection\n{future_anomalies.result()}"
428
+ amc_reminders = f"AMC Reminders\n{future_amc.result()}"
 
429
  insights = f"Dashboard Insights (AI)\n{future_insights.result()}"
430
  chart = future_chart.result()
431
  report_result = future_reports.result()
 
441
  preview = "\n".join(preview_lines)
442
 
443
  salesforce_result = save_to_salesforce(df, summary, anomalies, amc_reminders, insights)
444
+ pdf_file = generate_pdf_content(summary, preview, anomalies, amc_reminders, insights)
 
445
 
446
  progress(1.0, "Done!")
447
+ return summary, preview, chart, anomalies, amc_reminders, insights, pdf_file, salesforce_result, report_result
448
  except Exception as e:
449
  logging.error(f"Failed to process file: {str(e)}")
450
+ return f"Error: {str(e)}", None, None, None, None, None, None, None, None
451
 
452
  # Gradio Interface
453
  try:
 
461
  .dashboard-section ul {margin: 2px 0; padding-left: 20px;}
462
  """) as iface:
463
  gr.Markdown("<h1>LabOps Log Analyzer Dashboard (Hugging Face AI)</h1>")
464
+ gr.Markdown("Upload a CSV file to analyze and generate Salesforce reports.")
465
 
466
  with gr.Row():
467
  with gr.Column(scale=1):
 
496
  gr.Markdown("### Step 6: Insights (AI)")
497
  insights_output = gr.Markdown()
498
 
 
 
 
 
499
  with gr.Group(elem_classes="dashboard-section"):
500
  gr.Markdown("### Salesforce Integration")
501
  salesforce_output = gr.Markdown()
 
520
  insights_output,
521
  pdf_output,
522
  salesforce_output,
523
+ report_output
 
524
  ]
525
  )
526