RathodHarish commited on
Commit
db5a92d
·
verified ·
1 Parent(s): a38ff86

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +19 -90
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
37
- SMTP_SERVER = 'smtp.gmail.com'
38
- SMTP_PORT = 587
39
- SMTP_USERNAME = 'harishkumarr@sathkrutha.com'
40
- SMTP_PASSWORD = 'Harish@048' # Ensure this is an app-specific password
41
- EMAIL_FROM = "harishkumarr@sathkrutha.com"
42
- EMAIL_TO = "sanjaybhargavneela@sathkrutha.com"
43
-
44
  # Try to import reportlab
45
  try:
46
  from reportlab.lib.pagesizes import letter
@@ -129,56 +118,7 @@ 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. Dataframe is empty.")
136
- return "No AMC reminder emails sent (no reminders found)."
137
-
138
- try:
139
- # Log the reminders for debugging
140
- logging.info(f"Found {len(reminders_df)} AMC reminders to send: {reminders_df.to_dict()}")
141
-
142
- # Set up the SMTP server
143
- server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
144
- server.starttls()
145
- server.login(SMTP_USERNAME, SMTP_PASSWORD)
146
-
147
- email_results = []
148
- for _, row in reminders_df.iterrows():
149
- device_id = row['device_id']
150
- amc_date = row['amc_date'].strftime('%Y-%m-%d') if pd.notna(row['amc_date']) else "N/A"
151
-
152
- # Create the email
153
- msg = MIMEMultipart()
154
- msg['From'] = EMAIL_FROM
155
- msg['To'] = EMAIL_TO
156
- msg['Subject'] = f"AMC Reminder for Device {device_id}"
157
-
158
- body = f"""
159
- Dear Sanjay Bhargav Neela,
160
- This is a reminder that the Annual Maintenance Contract (AMC) for the following device is due:
161
- - Device ID: {device_id}
162
- - AMC Date: {amc_date}
163
- Please schedule the maintenance at your earliest convenience.
164
- Best regards,
165
- Harish Kumar
166
- LabOps Team
167
- """
168
- msg.attach(MIMEText(body, 'plain'))
169
-
170
- # Send the email
171
- server.sendmail(EMAIL_FROM, EMAIL_TO, msg.as_string())
172
- logging.info(f"AMC reminder email sent for Device ID {device_id} to {EMAIL_TO}")
173
- email_results.append(f"Sent AMC reminder for Device ID {device_id}")
174
-
175
- server.quit()
176
- return "\n".join(email_results) if email_results else "No emails sent."
177
- except Exception as e:
178
- logging.error(f"Failed to send AMC reminder emails: {str(e)}")
179
- return f"Failed to send AMC reminder emails: {str(e)}"
180
-
181
- # Updated Salesforce report creation with correct field API names
182
  def create_salesforce_reports(df):
183
  if sf is None:
184
  return "Salesforce connection not available."
@@ -186,19 +126,16 @@ def create_salesforce_reports(df):
186
  return "Cannot create reports: 'LabOps Reports' folder not found in Salesforce."
187
 
188
  try:
189
- # Usage Report (Summary Report)
190
  usage_report_metadata = {
191
  "reportMetadata": {
192
  "name": f"SmartLog_Usage_Report_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
193
  "developerName": f"SmartLog_Usage_Report_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
194
  "reportType": "CustomEntity$SmartLog__c",
195
- "reportFormat": "SUMMARY",
196
  "columns": [
197
  {"field": "SmartLog__c.Device_Id__c"},
198
- {"field": "SmartLog__c.Usage_Hours__c", "aggregateTypes": ["Sum"]}
199
- ],
200
- "groupingsDown": [
201
- {"field": "SmartLog__c.Device_Id__c", "sortOrder": "Asc", "dateGranularity": "None"}
202
  ],
203
  "folderId": LABOPS_REPORTS_FOLDER_ID
204
  }
@@ -329,7 +266,7 @@ def detect_anomalies(df):
329
  logging.error(f"Anomaly detection failed: {str(e)}")
330
  return f"Anomaly detection failed: {str(e)}"
331
 
332
- # AMC reminders
333
  def check_amc_reminders(df, current_date):
334
  try:
335
  if "device_id" not in df.columns or "amc_date" not in df.columns:
@@ -390,8 +327,8 @@ def create_usage_chart(df):
390
  logging.error(f"Failed to create usage chart: {str(e)}")
391
  return None
392
 
393
- # Generate PDF content
394
- def generate_pdf_content(summary, preview, anomalies, amc_reminders, insights, email_status):
395
  if not reportlab_available:
396
  return None
397
  try:
@@ -423,10 +360,6 @@ def generate_pdf_content(summary, preview, anomalies, amc_reminders, insights, e
423
  story.append(safe_paragraph(amc_reminders or "No AMC reminders.", styles['Normal']))
424
  story.append(Spacer(1, 12))
425
 
426
- story.append(Paragraph("Email Notification Status", styles['Heading2']))
427
- story.append(safe_paragraph(email_status or "No emails sent.", styles['Normal']))
428
- story.append(Spacer(1, 12))
429
-
430
  story.append(Paragraph("Dashboard Insights", styles['Heading2']))
431
  story.append(safe_paragraph(insights or "No insights generated.", styles['Normal']))
432
 
@@ -442,13 +375,13 @@ async def process_logs(file_obj):
442
  try:
443
  start_time = datetime.now()
444
  if not file_obj:
445
- 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."
446
 
447
  file_name = file_obj.name
448
  logging.info(f"Processing file: {file_name}")
449
 
450
  if not file_name.endswith(".csv"):
451
- return "Please upload a CSV file.", "", None, "", "", "", None, "", "", ""
452
 
453
  required_columns = ["device_id", "log_type", "status", "timestamp", "usage_hours", "downtime", "amc_date"]
454
  dtypes = {
@@ -462,11 +395,13 @@ async def process_logs(file_obj):
462
  df = pd.read_csv(file_obj, dtype=dtypes)
463
  missing_columns = [col for col in required_columns if col not in df.columns]
464
  if missing_columns:
465
- return f"Missing columns: {missing_columns}", None, None, None, None, None, None, None, None, None
466
  df["timestamp"] = pd.to_datetime(df["timestamp"], errors='coerce')
467
  df["amc_date"] = pd.to_datetime(df["amc_date"], errors='coerce')
468
  if df.empty:
469
- return "No data available.", None, None, None, None, None, None, None, None, None
 
 
470
 
471
  # Run tasks concurrently
472
  with ThreadPoolExecutor(max_workers=4) as executor:
@@ -496,15 +431,14 @@ async def process_logs(file_obj):
496
  preview = "\n".join(preview_lines)
497
 
498
  salesforce_result = save_to_salesforce(df, summary, anomalies, amc_reminders, insights)
499
- email_status = send_amc_reminder_emails(reminders_df)
500
- pdf_file = generate_pdf_content(summary, preview, anomalies, amc_reminders, insights, email_status)
501
 
502
  elapsed_time = (datetime.now() - start_time).total_seconds()
503
  logging.info(f"Processing completed in {elapsed_time:.2f} seconds")
504
- return summary, preview, chart, anomalies, amc_reminders, insights, pdf_file, salesforce_result, report_result, email_status
505
  except Exception as e:
506
  logging.error(f"Failed to process file: {str(e)}")
507
- return f"Error: {str(e)}", None, None, None, None, None, None, None, None, None
508
 
509
  # Gradio Interface
510
  try:
@@ -518,7 +452,7 @@ try:
518
  .dashboard-section ul {margin: 2px 0; padding-left: 20px;}
519
  """) as iface:
520
  gr.Markdown("<h1>LabOps Log Analyzer Dashboard (Hugging Face AI)</h1>")
521
- gr.Markdown("Upload a CSV file to analyze, generate Salesforce reports, and send AMC reminder emails.")
522
 
523
  with gr.Row():
524
  with gr.Column(scale=1):
@@ -553,10 +487,6 @@ try:
553
  gr.Markdown("### Step 6: Insights (AI)")
554
  insights_output = gr.Markdown()
555
 
556
- with gr.Group(elem_classes="dashboard-section"):
557
- gr.Markdown("### Step 7: Email Notification Status")
558
- email_output = gr.Markdown()
559
-
560
  with gr.Group(elem_classes="dashboard-section"):
561
  gr.Markdown("### Salesforce Integration")
562
  salesforce_output = gr.Markdown()
@@ -581,8 +511,7 @@ try:
581
  insights_output,
582
  pdf_output,
583
  salesforce_output,
584
- report_output,
585
- email_output
586
  ]
587
  )
588
 
 
1
  """
2
+ LabOps Log Analyzer Dashboard with CSV file upload, PDF generation, Salesforce integration, and AMC reminder via Salesforce trigger
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
+ # Updated Salesforce report creation with minimal metadata
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  def create_salesforce_reports(df):
123
  if sf is None:
124
  return "Salesforce connection not available."
 
126
  return "Cannot create reports: 'LabOps Reports' folder not found in Salesforce."
127
 
128
  try:
129
+ # Usage Report (Tabular Report for simplicity)
130
  usage_report_metadata = {
131
  "reportMetadata": {
132
  "name": f"SmartLog_Usage_Report_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
133
  "developerName": f"SmartLog_Usage_Report_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
134
  "reportType": "CustomEntity$SmartLog__c",
135
+ "reportFormat": "TABULAR",
136
  "columns": [
137
  {"field": "SmartLog__c.Device_Id__c"},
138
+ {"field": "SmartLog__c.Usage_Hours__c"}
 
 
 
139
  ],
140
  "folderId": LABOPS_REPORTS_FOLDER_ID
141
  }
 
266
  logging.error(f"Anomaly detection failed: {str(e)}")
267
  return f"Anomaly detection failed: {str(e)}"
268
 
269
+ # AMC reminders (for display purposes only, email handled by Salesforce trigger)
270
  def check_amc_reminders(df, current_date):
271
  try:
272
  if "device_id" not in df.columns or "amc_date" not in df.columns:
 
327
  logging.error(f"Failed to create usage chart: {str(e)}")
328
  return None
329
 
330
+ # Generate PDF content (removed email_status since email is handled by Salesforce)
331
+ def generate_pdf_content(summary, preview, anomalies, amc_reminders, insights):
332
  if not reportlab_available:
333
  return None
334
  try:
 
360
  story.append(safe_paragraph(amc_reminders or "No AMC reminders.", styles['Normal']))
361
  story.append(Spacer(1, 12))
362
 
 
 
 
 
363
  story.append(Paragraph("Dashboard Insights", styles['Heading2']))
364
  story.append(safe_paragraph(insights or "No insights generated.", styles['Normal']))
365
 
 
375
  try:
376
  start_time = datetime.now()
377
  if not file_obj:
378
+ 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."
379
 
380
  file_name = file_obj.name
381
  logging.info(f"Processing file: {file_name}")
382
 
383
  if not file_name.endswith(".csv"):
384
+ return "Please upload a CSV file.", "", None, "", "", "", None, "", ""
385
 
386
  required_columns = ["device_id", "log_type", "status", "timestamp", "usage_hours", "downtime", "amc_date"]
387
  dtypes = {
 
395
  df = pd.read_csv(file_obj, dtype=dtypes)
396
  missing_columns = [col for col in required_columns if col not in df.columns]
397
  if missing_columns:
398
+ return f"Missing columns: {missing_columns}", None, None, None, None, None, None, None, None
399
  df["timestamp"] = pd.to_datetime(df["timestamp"], errors='coerce')
400
  df["amc_date"] = pd.to_datetime(df["amc_date"], errors='coerce')
401
  if df.empty:
402
+ return "No data available.", None, No
403
+ ```python
404
+ ne, None, None, None, None, None, None
405
 
406
  # Run tasks concurrently
407
  with ThreadPoolExecutor(max_workers=4) as executor:
 
431
  preview = "\n".join(preview_lines)
432
 
433
  salesforce_result = save_to_salesforce(df, summary, anomalies, amc_reminders, insights)
434
+ pdf_file = generate_pdf_content(summary, preview, anomalies, amc_reminders, insights)
 
435
 
436
  elapsed_time = (datetime.now() - start_time).total_seconds()
437
  logging.info(f"Processing completed in {elapsed_time:.2f} seconds")
438
+ return summary, preview, chart, anomalies, amc_reminders, insights, pdf_file, salesforce_result, report_result
439
  except Exception as e:
440
  logging.error(f"Failed to process file: {str(e)}")
441
+ return f"Error: {str(e)}", None, None, None, None, None, None, None, None
442
 
443
  # Gradio Interface
444
  try:
 
452
  .dashboard-section ul {margin: 2px 0; padding-left: 20px;}
453
  """) as iface:
454
  gr.Markdown("<h1>LabOps Log Analyzer Dashboard (Hugging Face AI)</h1>")
455
+ gr.Markdown("Upload a CSV file to analyze, generate Salesforce reports, and trigger AMC reminder emails via Salesforce.")
456
 
457
  with gr.Row():
458
  with gr.Column(scale=1):
 
487
  gr.Markdown("### Step 6: Insights (AI)")
488
  insights_output = gr.Markdown()
489
 
 
 
 
 
490
  with gr.Group(elem_classes="dashboard-section"):
491
  gr.Markdown("### Salesforce Integration")
492
  salesforce_output = gr.Markdown()
 
511
  insights_output,
512
  pdf_output,
513
  salesforce_output,
514
+ report_output
 
515
  ]
516
  )
517