Update utils/__init__.py
Browse files- utils/__init__.py +0 -84
utils/__init__.py
CHANGED
|
@@ -1,84 +0,0 @@
|
|
| 1 |
-
from simple_salesforce import Salesforce
|
| 2 |
-
from reportlab.lib.pagesizes import letter
|
| 3 |
-
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph
|
| 4 |
-
from reportlab.lib import colors
|
| 5 |
-
from reportlab.lib.styles import getSampleStyleSheet
|
| 6 |
-
import pandas as pd
|
| 7 |
-
from datetime import datetime
|
| 8 |
-
import time
|
| 9 |
-
import logging
|
| 10 |
-
|
| 11 |
-
# Configure logging
|
| 12 |
-
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
| 13 |
-
logger = logging.getLogger(__name__)
|
| 14 |
-
|
| 15 |
-
def fetch_salesforce_data(sf: Salesforce, query: str, retries=3) -> list:
|
| 16 |
-
"""Fetch data from Salesforce using SOQL query with retry logic."""
|
| 17 |
-
logger.info(f"Executing SOQL query: {query}")
|
| 18 |
-
for attempt in range(retries):
|
| 19 |
-
try:
|
| 20 |
-
result = sf.query_all(query)
|
| 21 |
-
logger.info(f"Successfully fetched {len(result['records'])} records.")
|
| 22 |
-
return result["records"]
|
| 23 |
-
except Exception as e:
|
| 24 |
-
logger.error(f"Attempt {attempt + 1}/{retries} failed: {e}")
|
| 25 |
-
if attempt == retries - 1:
|
| 26 |
-
logger.error(f"Failed to fetch Salesforce data after {retries} attempts.")
|
| 27 |
-
return []
|
| 28 |
-
time.sleep(2)
|
| 29 |
-
return []
|
| 30 |
-
|
| 31 |
-
def detect_anomalies(log_text: str, anomaly_detector) -> str:
|
| 32 |
-
"""Detect anomalies in log text using Hugging Face model."""
|
| 33 |
-
logger.info(f"Detecting anomaly for text: {log_text}")
|
| 34 |
-
try:
|
| 35 |
-
result = anomaly_detector(log_text, clean_up_tokenization_spaces=True)
|
| 36 |
-
label = result[0]["label"]
|
| 37 |
-
logger.info(f"Anomaly detection result: {label}")
|
| 38 |
-
return label
|
| 39 |
-
except Exception as e:
|
| 40 |
-
logger.error(f"Error detecting anomaly: {e}")
|
| 41 |
-
return "NEGATIVE"
|
| 42 |
-
|
| 43 |
-
def generate_pdf_report(df: pd.DataFrame, lab_site: str, equipment_type: str, date_range: list) -> str:
|
| 44 |
-
"""Generate a PDF report from dashboard data."""
|
| 45 |
-
logger.info("Generating PDF report...")
|
| 46 |
-
try:
|
| 47 |
-
pdf_file = "/tmp/LabOps_Report.pdf"
|
| 48 |
-
doc = SimpleDocTemplate(pdf_file, pagesize=letter)
|
| 49 |
-
elements = []
|
| 50 |
-
styles = getSampleStyleSheet()
|
| 51 |
-
|
| 52 |
-
elements.append(Paragraph(f"LabOps Dashboard Report - {datetime.now().strftime('%Y-%m-%d')}", styles["Title"]))
|
| 53 |
-
elements.append(Paragraph(f"Lab: {lab_site} | Equipment: {equipment_type} | Date Range: {date_range[0]} to {date_range[1]}", styles["Normal"]))
|
| 54 |
-
|
| 55 |
-
data = [["Equipment", "Timestamp", "Status", "Usage Count", "Anomaly"]]
|
| 56 |
-
for _, row in df.iterrows():
|
| 57 |
-
timestamp = row["Log_Timestamp__c"].strftime('%Y-%m-%d %H:%M:%S') if pd.notnull(row["Log_Timestamp__c"]) else "N/A"
|
| 58 |
-
data.append([
|
| 59 |
-
row["Equipment__c"],
|
| 60 |
-
timestamp,
|
| 61 |
-
row["Status__c"],
|
| 62 |
-
str(row["Usage_Count__c"]),
|
| 63 |
-
row["Anomaly"]
|
| 64 |
-
])
|
| 65 |
-
|
| 66 |
-
table = Table(data)
|
| 67 |
-
table.setStyle(TableStyle([
|
| 68 |
-
("BACKGROUND", (0, 0), (-1, 0), colors.grey),
|
| 69 |
-
("TEXTCOLOR", (0, 0), (-1, 0), colors.whitesmoke),
|
| 70 |
-
("ALIGN", (0, 0), (-1, -1), "CENTER"),
|
| 71 |
-
("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
|
| 72 |
-
("FONTSIZE", (0, 0), (-1, 0), 14),
|
| 73 |
-
("BOTTOMPADDING", (0, 0), (-1, 0), 12),
|
| 74 |
-
("BACKGROUND", (0, 1), (-1, -1), colors.beige),
|
| 75 |
-
("GRID", (0, 0), (-1, -1), 1, colors.black)
|
| 76 |
-
]))
|
| 77 |
-
elements.append(table)
|
| 78 |
-
|
| 79 |
-
doc.build(elements)
|
| 80 |
-
logger.info(f"PDF report generated: {pdf_file}")
|
| 81 |
-
return pdf_file
|
| 82 |
-
except Exception as e:
|
| 83 |
-
logger.error(f"Failed to generate PDF report: {e}")
|
| 84 |
-
raise
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|