RathodHarish commited on
Commit
4f94010
·
verified ·
1 Parent(s): c00e92c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -29
app.py CHANGED
@@ -5,26 +5,27 @@ import logging
5
  import plotly.express as px
6
  from sklearn.ensemble import IsolationForest # For anomaly detection
7
  from transformers import pipeline
 
8
 
9
  # Configure logging for debugging
10
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
11
 
12
- # Load Hugging Face summarization model
 
13
  try:
14
- logging.info("Attempting to load Hugging Face model...")
15
- summarizer = pipeline("text2text-generation", model="google/flan-t5-base")
16
- logging.info("Hugging Face model loaded successfully")
17
  except Exception as e:
18
- logging.error(f"Failed to load model: {str(e)}")
19
  raise e
20
 
21
  # Format summary prompt and generate report
22
- def summarize_logs(df):
 
23
  try:
24
  total_devices = df["device_id"].nunique()
25
  avg_uptime = "97%" # Placeholder
26
  most_used = df.groupby("device_id")["usage_hours"].sum().idxmax() if not df.empty else "N/A"
27
- downtime_events = 3 # Placeholder
28
 
29
  prompt = (
30
  f"Summarize maintenance and usage logs. "
@@ -38,15 +39,21 @@ def summarize_logs(df):
38
  logging.error(f"Summary generation failed: {str(e)}")
39
  return "Failed to generate summary."
40
 
41
- # Anomaly Detection using Isolation Forest
42
- def detect_anomalies(df):
 
43
  try:
44
  if "usage_hours" not in df.columns or "downtime" not in df.columns:
45
  logging.warning("Required columns for anomaly detection not found")
46
  return "Anomaly detection requires 'usage_hours' and 'downtime' columns."
47
 
 
 
 
 
 
48
  features = df[["usage_hours", "downtime"]].fillna(0)
49
- iso_forest = IsolationForest(contamination=0.1, random_state=42)
50
  df["anomaly"] = iso_forest.fit_predict(features)
51
 
52
  anomalies = df[df["anomaly"] == -1][["device_id", "usage_hours", "downtime", "timestamp"]]
@@ -68,13 +75,14 @@ def detect_anomalies(df):
68
  return f"Anomaly detection failed: {str(e)}"
69
 
70
  # AMC Reminders based on device and AMC date
71
- def check_amc_reminders(df, current_date):
 
72
  try:
73
  if "device_id" not in df.columns or "amc_date" not in df.columns:
74
  logging.warning("Required columns for AMC reminders not found")
75
  return "AMC reminders require 'device_id' and 'amc_date' columns."
76
 
77
- df["amc_date"] = pd.to_datetime(df["amc_date"])
78
  current_date = pd.to_datetime(current_date)
79
 
80
  df["days_to_amc"] = (df["amc_date"] - current_date).dt.days
@@ -96,7 +104,8 @@ def check_amc_reminders(df, current_date):
96
  return f"AMC reminder generation failed: {str(e)}"
97
 
98
  # Dashboard Insights (AI-generated executive-level insights)
99
- def generate_dashboard_insights(df):
 
100
  try:
101
  total_devices = df["device_id"].nunique()
102
  avg_usage = df["usage_hours"].mean() if "usage_hours" in df.columns else 0
@@ -112,10 +121,15 @@ def generate_dashboard_insights(df):
112
  return f"Dashboard insights generation failed: {str(e)}"
113
 
114
  # Create a bar chart for usage hours per device
115
- def create_usage_chart(df):
 
116
  try:
 
117
  usage_data = df.groupby("device_id")["usage_hours"].sum().reset_index()
118
- # Define a custom color palette for multiple colors
 
 
 
119
  custom_colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4']
120
  fig = px.bar(
121
  usage_data,
@@ -123,8 +137,8 @@ def create_usage_chart(df):
123
  y="usage_hours",
124
  title="Usage Hours per Device",
125
  labels={"device_id": "Device ID", "usage_hours": "Usage Hours"},
126
- color="device_id", # Color by device_id to assign different colors
127
- color_discrete_sequence=custom_colors # Use custom color palette
128
  )
129
  fig.update_layout(
130
  title_font_size=16,
@@ -139,8 +153,9 @@ def create_usage_chart(df):
139
  return None
140
 
141
  # Main Gradio function
142
- def process_logs(file_obj):
143
  try:
 
144
  if file_obj is None:
145
  logging.warning("No file uploaded, returning empty results")
146
  return "No file uploaded.", "No data to preview.", None, "No anomalies detected.", "No AMC reminders.", "No insights generated."
@@ -152,11 +167,19 @@ def process_logs(file_obj):
152
  logging.error("Unsupported file format")
153
  return "Unsupported file format. Please upload a CSV file.", None, None, None, None, None
154
 
155
- df = pd.read_csv(file_name)
156
- logging.info(f"File loaded successfully with {len(df)} rows")
 
 
 
 
 
 
 
157
 
 
158
  try:
159
- df["timestamp"] = pd.to_datetime(df["timestamp"])
160
  except Exception as e:
161
  logging.error(f"Date conversion failed: {str(e)}")
162
  return f"Failed to convert timestamp to datetime: {str(e)}", None, None, None, None, None
@@ -166,9 +189,11 @@ def process_logs(file_obj):
166
  return "No data available in the file.", "No data to preview.", None, "No anomalies detected.", "No AMC reminders.", "No insights generated."
167
 
168
  # Step 1: Summary Report
169
- summary = f"**Step 1: Summary Report**\n{summarize_logs(df)}\n---\n"
 
170
 
171
  # Step 2: Log Preview
 
172
  if not df.empty:
173
  preview_lines = ["**Step 2: Log Preview (First 5 Rows)**"]
174
  for idx, row in df.head().iterrows():
@@ -184,23 +209,24 @@ def process_logs(file_obj):
184
  preview = "**Step 2: Log Preview**\nNo data available.\n---\n"
185
 
186
  # Step 3: Usage Chart
187
- chart = create_usage_chart(df)
188
 
189
  # Step 4: Anomaly Detection
190
- anomalies = f"**Step 3: Anomaly Detection**\n{detect_anomalies(df)}\n---\n"
191
 
192
  # Step 5: AMC Reminders
193
- amc_reminders = f"**Step 4: AMC Reminders**\n{check_amc_reminders(df, datetime.now())}\n---\n"
194
 
195
- # Step 6: Dashboard Insights
196
- insights = f"**Step 5: Dashboard Insights (AI)**\n{generate_dashboard_insights(df)}\n---\n"
197
 
 
198
  return summary, preview, chart, anomalies, amc_reminders, insights
199
  except Exception as e:
200
  logging.error(f"Failed to process file: {str(e)}")
201
  return f"Failed to process file: {str(e)}", None, None, None, None, None
202
 
203
- # Gradio Interface with Step-by-Step Layout
204
  try:
205
  logging.info("Initializing Gradio Blocks interface...")
206
  with gr.Blocks(css="""
@@ -208,7 +234,7 @@ try:
208
  .dashboard-title {font-size: 24px; font-weight: bold; margin-bottom: 10px;}
209
  .dashboard-section {margin-bottom: 15px;}
210
  .dashboard-section h3 {font-size: 18px; margin-bottom: 5px;}
211
- .dashboard-section p {margin: 2px 0;} /* Reduce spacing between lines */
212
  """) as iface:
213
  gr.Markdown("<h1>LabOps Log Analyzer Dashboard (Hugging Face AI)</h1>")
214
  gr.Markdown("Upload a CSV file containing lab equipment logs to analyze usage.")
 
5
  import plotly.express as px
6
  from sklearn.ensemble import IsolationForest # For anomaly detection
7
  from transformers import pipeline
8
+ import dask.dataframe as dd # For handling large datasets
9
 
10
  # Configure logging for debugging
11
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
12
 
13
+ # Preload Hugging Face summarization model at startup
14
+ logging.info("Preloading Hugging Face model...")
15
  try:
16
+ summarizer = pipeline("text2text-generation", model="google/flan-t5-base", device=0 if gr.cuda.is_available() else -1) # Use GPU if available
17
+ logging.info("Hugging Face model preloaded successfully")
 
18
  except Exception as e:
19
+ logging.error(f"Failed to preload model: {str(e)}")
20
  raise e
21
 
22
  # Format summary prompt and generate report
23
+ def summarize_logs(df, progress=gr.Progress()):
24
+ progress(0.1, "Generating summary report...")
25
  try:
26
  total_devices = df["device_id"].nunique()
27
  avg_uptime = "97%" # Placeholder
28
  most_used = df.groupby("device_id")["usage_hours"].sum().idxmax() if not df.empty else "N/A"
 
29
 
30
  prompt = (
31
  f"Summarize maintenance and usage logs. "
 
39
  logging.error(f"Summary generation failed: {str(e)}")
40
  return "Failed to generate summary."
41
 
42
+ # Anomaly Detection using Isolation Forest with sampling for large datasets
43
+ def detect_anomalies(df, progress=gr.Progress()):
44
+ progress(0.4, "Detecting anomalies...")
45
  try:
46
  if "usage_hours" not in df.columns or "downtime" not in df.columns:
47
  logging.warning("Required columns for anomaly detection not found")
48
  return "Anomaly detection requires 'usage_hours' and 'downtime' columns."
49
 
50
+ # Sample data if too large
51
+ if len(df) > 10000: # Adjust threshold as needed
52
+ df = df.sample(n=10000, random_state=42)
53
+ logging.info("Sampled data for anomaly detection to 10,000 rows")
54
+
55
  features = df[["usage_hours", "downtime"]].fillna(0)
56
+ iso_forest = IsolationForest(contamination=0.1, random_state=42, n_jobs=-1) # Use all CPU cores
57
  df["anomaly"] = iso_forest.fit_predict(features)
58
 
59
  anomalies = df[df["anomaly"] == -1][["device_id", "usage_hours", "downtime", "timestamp"]]
 
75
  return f"Anomaly detection failed: {str(e)}"
76
 
77
  # AMC Reminders based on device and AMC date
78
+ def check_amc_reminders(df, current_date, progress=gr.Progress()):
79
+ progress(0.6, "Checking AMC reminders...")
80
  try:
81
  if "device_id" not in df.columns or "amc_date" not in df.columns:
82
  logging.warning("Required columns for AMC reminders not found")
83
  return "AMC reminders require 'device_id' and 'amc_date' columns."
84
 
85
+ df["amc_date"] = pd.to_datetime(df["amc_date"], errors='coerce')
86
  current_date = pd.to_datetime(current_date)
87
 
88
  df["days_to_amc"] = (df["amc_date"] - current_date).dt.days
 
104
  return f"AMC reminder generation failed: {str(e)}"
105
 
106
  # Dashboard Insights (AI-generated executive-level insights)
107
+ def generate_dashboard_insights(df, progress=gr.Progress()):
108
+ progress(0.8, "Generating dashboard insights...")
109
  try:
110
  total_devices = df["device_id"].nunique()
111
  avg_usage = df["usage_hours"].mean() if "usage_hours" in df.columns else 0
 
121
  return f"Dashboard insights generation failed: {str(e)}"
122
 
123
  # Create a bar chart for usage hours per device
124
+ def create_usage_chart(df, progress=gr.Progress()):
125
+ progress(0.9, "Creating usage chart...")
126
  try:
127
+ # Limit the data for chart to top 10 devices to reduce load
128
  usage_data = df.groupby("device_id")["usage_hours"].sum().reset_index()
129
+ if len(usage_data) > 10:
130
+ usage_data = usage_data.nlargest(10, "usage_hours")
131
+ logging.info("Limited chart data to top 10 devices")
132
+
133
  custom_colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4']
134
  fig = px.bar(
135
  usage_data,
 
137
  y="usage_hours",
138
  title="Usage Hours per Device",
139
  labels={"device_id": "Device ID", "usage_hours": "Usage Hours"},
140
+ color="device_id",
141
+ color_discrete_sequence=custom_colors
142
  )
143
  fig.update_layout(
144
  title_font_size=16,
 
153
  return None
154
 
155
  # Main Gradio function
156
+ def process_logs(file_obj, progress=gr.Progress()):
157
  try:
158
+ progress(0, "Starting file processing...")
159
  if file_obj is None:
160
  logging.warning("No file uploaded, returning empty results")
161
  return "No file uploaded.", "No data to preview.", None, "No anomalies detected.", "No AMC reminders.", "No insights generated."
 
167
  logging.error("Unsupported file format")
168
  return "Unsupported file format. Please upload a CSV file.", None, None, None, None, None
169
 
170
+ # Use Dask for large CSV files to read in chunks
171
+ progress(0.05, "Loading CSV file...")
172
+ try:
173
+ ddf = dd.from_pandas(pd.read_csv(file_name), npartitions=4) # Split into 4 partitions
174
+ df = ddf.compute() # Convert back to pandas after processing
175
+ logging.info(f"File loaded successfully with {len(df)} rows")
176
+ except Exception as e:
177
+ logging.error(f"Failed to load CSV: {str(e)}")
178
+ return f"Failed to load CSV: {str(e)}", None, None, None, None, None
179
 
180
+ progress(0.1, "Converting timestamps...")
181
  try:
182
+ df["timestamp"] = pd.to_datetime(df["timestamp"], errors='coerce')
183
  except Exception as e:
184
  logging.error(f"Date conversion failed: {str(e)}")
185
  return f"Failed to convert timestamp to datetime: {str(e)}", None, None, None, None, None
 
189
  return "No data available in the file.", "No data to preview.", None, "No anomalies detected.", "No AMC reminders.", "No insights generated."
190
 
191
  # Step 1: Summary Report
192
+ progress(0.2, "Generating summary...")
193
+ summary = f"**Step 1: Summary Report**\n{summarize_logs(df, progress)}\n---\n"
194
 
195
  # Step 2: Log Preview
196
+ progress(0.3, "Previewing logs...")
197
  if not df.empty:
198
  preview_lines = ["**Step 2: Log Preview (First 5 Rows)**"]
199
  for idx, row in df.head().iterrows():
 
209
  preview = "**Step 2: Log Preview**\nNo data available.\n---\n"
210
 
211
  # Step 3: Usage Chart
212
+ chart = create_usage_chart(df, progress)
213
 
214
  # Step 4: Anomaly Detection
215
+ anomalies = f"**Step 3: Anomaly Detection**\n{detect_anomalies(df, progress)}\n---\n"
216
 
217
  # Step 5: AMC Reminders
218
+ amc_reminders = f"**Step 4: AMC Reminders**\n{check_amc_reminders(df, datetime.now(), progress)}\n---\n"
219
 
220
+ # Stepabba 6: Dashboard Insights
221
+ insights = f"**Step 5: Dashboard Insights (AI)**\n{generate_dashboard_insights(df, progress)}\n---\n"
222
 
223
+ progress(1.0, "Processing complete!")
224
  return summary, preview, chart, anomalies, amc_reminders, insights
225
  except Exception as e:
226
  logging.error(f"Failed to process file: {str(e)}")
227
  return f"Failed to process file: {str(e)}", None, None, None, None, None
228
 
229
+ # Gr{dimadio Interface with Step-by-Step Layout
230
  try:
231
  logging.info("Initializing Gradio Blocks interface...")
232
  with gr.Blocks(css="""
 
234
  .dashboard-title {font-size: 24px; font-weight: bold; margin-bottom: 10px;}
235
  .dashboard-section {margin-bottom: 15px;}
236
  .dashboard-section h3 {font-size: 18px; margin-bottom: 5px;}
237
+ .dashboard-section p {margin: 2px 0;}
238
  """) as iface:
239
  gr.Markdown("<h1>LabOps Log Analyzer Dashboard (Hugging Face AI)</h1>")
240
  gr.Markdown("Upload a CSV file containing lab equipment logs to analyze usage.")