RathodHarish commited on
Commit
d190ea7
·
verified ·
1 Parent(s): 571a10b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +179 -153
app.py CHANGED
@@ -78,8 +78,7 @@ def upload_csv(file):
78
  # Automatically trigger filter_and_visualize after upload with default filters
79
  debug_msg += "Triggering initial visualization with default filters...\n"
80
  try:
81
- result = filter_and_visualize("All", "All", "All")
82
- device_cards, plot_daily, plot_uptime, anomaly_text, filter_msg = result
83
  debug_msg += f"Initial Filter Result: {filter_msg}\n"
84
  except Exception as e:
85
  debug_msg += f"Initial Filter Error: {str(e)}\n"
@@ -91,182 +90,209 @@ def upload_csv(file):
91
 
92
  def filter_and_visualize(selected_lab, selected_type, selected_date_range):
93
  global df
94
- if df.empty:
95
- return None, None, None, None, "No data available."
96
-
97
- # Debug: Log the filter parameters
98
- error_msg = f"Applying filters: Lab={selected_lab}, Type={selected_type}, Date Range={selected_date_range}\n"
99
-
100
- # Filter the DataFrame
101
- filtered_df = df.copy()
102
- error_msg += f"Initial DataFrame: {len(filtered_df)} rows\n"
103
-
104
- if selected_lab != "All":
105
- filtered_df = filtered_df[filtered_df["Lab"] == selected_lab]
106
- error_msg += f"After Lab filter ({selected_lab}): {len(filtered_df)} rows\n"
107
- if selected_type != "All":
108
- filtered_df = filtered_df[filtered_df["Type"] == selected_type]
109
- error_msg += f"After Type filter ({selected_type}): {len(filtered_df)} rows\n"
110
- if selected_date_range != "All" and selected_date_range != "No data available." and not df['Timestamp'].isna().all():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  try:
112
- start_date, end_date = selected_date_range.split(" to ")
113
- start_date = pd.to_datetime(start_date)
114
- end_date = pd.to_datetime(end_date) + timedelta(days=1) # Include end date
115
- filtered_df = filtered_df[(filtered_df["Timestamp"] >= start_date) & (filtered_df["Timestamp"] < end_date)]
116
- error_msg += f"After Date Range filter ({start_date} to {end_date}): {len(filtered_df)} rows\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  except Exception as e:
118
- error_msg += f"Error parsing date range: {str(e)}\n"
119
-
120
- if filtered_df.empty:
121
- return None, None, None, None, f"{error_msg}No data matches the selected filters."
122
-
123
- # Debug: Log the filtered DataFrame
124
- error_msg += f"Filtered DataFrame:\n{filtered_df.to_string()}\n"
125
-
126
- # Device Cards (as a table)
127
- device_cards = filtered_df[['DeviceID', 'Lab', 'Type', 'UsageCount', 'Timestamp']].sort_values(by='Timestamp', ascending=False)
128
-
129
- # Daily Log Trends (Line Chart)
130
- try:
131
- if df['Timestamp'].isna().all():
132
- error_msg += "Warning: All timestamps are invalid. Skipping Daily Log Trends.\n"
133
  plt.figure(figsize=(8, 4))
134
- plt.title("Daily Log Trends - No Data (Invalid Timestamps)")
135
  plt.xlabel("Date")
136
  plt.ylabel("Number of Logs")
137
- buf1 = io.BytesIO()
138
- plt.savefig(buf1, format="png", bbox_inches="tight")
139
  plt.close()
140
- buf1.seek(0)
141
- else:
142
- daily_logs = filtered_df.groupby(filtered_df['Timestamp'].dt.date).size()
143
- if daily_logs.empty:
144
- error_msg += "Warning: No data for Daily Log Trends.\n"
 
145
  plt.figure(figsize=(8, 4))
146
- plt.title("Daily Log Trends - No Data")
147
  plt.xlabel("Date")
148
- plt.ylabel("Number of Logs")
149
- buf1 = io.BytesIO()
150
- plt.savefig(buf1, format="png", bbox_inches="tight")
151
  plt.close()
152
- buf1.seek(0)
153
  else:
154
- plt.figure(figsize=(8, 4))
155
- daily_logs.plot(kind='line', marker='o', color='blue')
156
- plt.title("Daily Log Trends")
157
- plt.xlabel("Date")
158
- plt.ylabel("Number of Logs")
159
- plt.xticks(rotation=45)
160
- buf1 = io.BytesIO()
161
- plt.savefig(buf1, format="png", bbox_inches="tight")
162
- plt.close()
163
- buf1.seek(0)
164
- except Exception as e:
165
- error_msg += f"Error generating Daily Log Trends: {str(e)}\n"
166
- plt.figure(figsize=(8, 4))
167
- plt.title("Daily Log Trends - Error")
168
- plt.xlabel("Date")
169
- plt.ylabel("Number of Logs")
170
- buf1 = io.BytesIO()
171
- plt.savefig(buf1, format="png", bbox_inches="tight")
172
- plt.close()
173
- buf1.seek(0)
174
-
175
- # Weekly Uptime % (Bar Chart)
176
- try:
177
- if df['Timestamp'].isna().all():
178
- error_msg += "Warning: All timestamps are invalid. Skipping Weekly Uptime.\n"
 
 
179
  plt.figure(figsize=(8, 4))
180
- plt.title("Weekly Uptime % - No Data (Invalid Timestamps)")
181
  plt.xlabel("Date")
182
  plt.ylabel("Uptime %")
183
- buf2 = io.BytesIO()
184
- plt.savefig(buf2, format="png", bbox_inches="tight")
185
  plt.close()
186
- buf2.seek(0)
187
- else:
188
- end_date = filtered_df['Timestamp'].max()
189
- start_date = end_date - timedelta(days=7)
190
- weekly_df = filtered_df[(filtered_df['Timestamp'] >= start_date) & (filtered_df['Timestamp'] <= end_date)]
191
- if weekly_df.empty:
192
- error_msg += "Warning: No data for Weekly Uptime % (date range too narrow).\n"
193
- plt.figure(figsize=(8, 4))
194
- plt.title("Weekly Uptime % - No Data")
195
- plt.xlabel("Date")
196
- plt.ylabel("Uptime %")
197
- buf2 = io.BytesIO()
198
- plt.savefig(buf2, format="png", bbox_inches="tight")
199
- plt.close()
200
- buf2.seek(0)
201
  else:
202
- uptime = weekly_df.groupby(weekly_df['Timestamp'].dt.date)['Status'].apply(lambda x: (x == 'Up').mean() * 100)
203
- plt.figure(figsize=(8, 4))
204
- uptime.plot(kind='bar', color='green')
205
- plt.title("Weekly Uptime %")
206
- plt.xlabel("Date")
207
- plt.ylabel("Uptime %")
208
- plt.xticks(rotation=45)
209
- buf2 = io.BytesIO()
210
- plt.savefig(buf2, format="png", bbox_inches="tight")
211
- plt.close()
212
- buf2.seek(0)
213
  except Exception as e:
214
- error_msg += f"Error generating Weekly Uptime %: {str(e)}\n"
 
 
 
 
 
 
 
 
 
215
  plt.figure(figsize=(8, 4))
216
  plt.title("Weekly Uptime % - Error")
217
  plt.xlabel("Date")
218
  plt.ylabel("Uptime %")
219
- buf2 = io.BytesIO()
220
- plt.savefig(buf2, format="png", bbox_inches="tight")
221
  plt.close()
222
- buf2.seek(0)
223
-
224
- # Anomaly Alerts (Text)
225
- try:
226
- anomalies = filtered_df[(filtered_df['UsageCount'] > 80) | (filtered_df['Status'] == 'Down')]
227
- if anomalies.empty:
228
- anomaly_text = "No anomalies detected."
229
- else:
230
- anomaly_text = "Anomalies Detected:\n" + anomalies[['DeviceID', 'Lab', 'Type', 'Status', 'UsageCount']].to_string(index=False)
231
- except Exception as e:
232
- error_msg += f"Error generating Anomaly Alerts: {str(e)}\n"
233
- anomaly_text = "Error generating anomaly alerts."
234
-
235
- return device_cards, buf1, buf2, anomaly_text, f"{error_msg}Filters applied successfully."
236
 
237
  def download_pdf(selected_lab, selected_type, selected_date_range):
238
  global df
239
- if df.empty:
240
- return None
241
-
242
- filtered_df = df.copy()
243
- if selected_lab != "All":
244
- filtered_df = filtered_df[filtered_df["Lab"] == selected_lab]
245
- if selected_type != "All":
246
- filtered_df = filtered_df[filtered_df["Type"] == selected_type]
247
- if selected_date_range != "All" and selected_date_range != "No data available." and not df['Timestamp'].isna().all():
248
- start_date, end_date = selected_date_range.split(" to ")
249
- start_date = pd.to_datetime(start_date)
250
- end_date = pd.to_datetime(end_date) + timedelta(days=1)
251
- filtered_df = filtered_df[(filtered_df["Timestamp"] >= start_date) & (filtered_df["Timestamp"] < end_date)]
252
-
253
- if filtered_df.empty:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  return None
255
-
256
- pdf = FPDF()
257
- pdf.add_page()
258
- pdf.set_font("Arial", size=12)
259
- pdf.cell(200, 10, txt="LabOps Dashboard Report", ln=True, align='C')
260
- pdf.ln(10)
261
-
262
- for index, row in filtered_df.iterrows():
263
- line = f"{row['Timestamp']} | {row['DeviceID']} | {row['Lab']} | {row['Type']} | {row['Status']} | {row['UsageCount']}"
264
- pdf.multi_cell(0, 10, txt=line)
265
-
266
- output = io.BytesIO()
267
- pdf.output(output)
268
- output.seek(0)
269
- return output
270
 
271
  # Build the Gradio interface
272
  with gr.Blocks() as demo:
 
78
  # Automatically trigger filter_and_visualize after upload with default filters
79
  debug_msg += "Triggering initial visualization with default filters...\n"
80
  try:
81
+ device_cards, plot_daily, plot_uptime, anomaly_text, filter_msg = filter_and_visualize("All", "All", "All")
 
82
  debug_msg += f"Initial Filter Result: {filter_msg}\n"
83
  except Exception as e:
84
  debug_msg += f"Initial Filter Error: {str(e)}\n"
 
90
 
91
  def filter_and_visualize(selected_lab, selected_type, selected_date_range):
92
  global df
93
+ error_msg = "Starting filter and visualize process...\n"
94
+ try:
95
+ if df.empty:
96
+ return None, None, None, None, f"{error_msg}No data available."
97
+
98
+ # Debug: Log the filter parameters
99
+ error_msg += f"Applying filters: Lab={selected_lab}, Type={selected_type}, Date Range={selected_date_range}\n"
100
+
101
+ # Filter the DataFrame
102
+ filtered_df = df.copy()
103
+ error_msg += f"Initial DataFrame: {len(filtered_df)} rows\n"
104
+
105
+ if selected_lab != "All":
106
+ filtered_df = filtered_df[filtered_df["Lab"] == selected_lab]
107
+ error_msg += f"After Lab filter ({selected_lab}): {len(filtered_df)} rows\n"
108
+ if selected_type != "All":
109
+ filtered_df = filtered_df[filtered_df["Type"] == selected_type]
110
+ error_msg += f"After Type filter ({selected_type}): {len(filtered_df)} rows\n"
111
+ if selected_date_range != "All" and selected_date_range != "No data available." and not df['Timestamp'].isna().all():
112
+ try:
113
+ start_date, end_date = selected_date_range.split(" to ")
114
+ start_date = pd.to_datetime(start_date)
115
+ end_date = pd.to_datetime(end_date) + timedelta(days=1) # Include end date
116
+ filtered_df = filtered_df[(filtered_df["Timestamp"] >= start_date) & (filtered_df["Timestamp"] < end_date)]
117
+ error_msg += f"After Date Range filter ({start_date} to {end_date}): {len(filtered_df)} rows\n"
118
+ except Exception as e:
119
+ error_msg += f"Error parsing date range: {str(e)}\n"
120
+
121
+ if filtered_df.empty:
122
+ return None, None, None, None, f"{error_msg}No data matches the selected filters."
123
+
124
+ # Debug: Log the filtered DataFrame
125
+ error_msg += f"Filtered DataFrame:\n{filtered_df.to_string()}\n"
126
+
127
+ # Device Cards (as a table)
128
+ device_cards = filtered_df[['DeviceID', 'Lab', 'Type', 'UsageCount', 'Timestamp']].sort_values(by='Timestamp', ascending=False)
129
+
130
+ # Daily Log Trends (Line Chart)
131
  try:
132
+ if df['Timestamp'].isna().all():
133
+ error_msg += "Warning: All timestamps are invalid. Skipping Daily Log Trends.\n"
134
+ plt.figure(figsize=(8, 4))
135
+ plt.title("Daily Log Trends - No Data (Invalid Timestamps)")
136
+ plt.xlabel("Date")
137
+ plt.ylabel("Number of Logs")
138
+ plot_daily = io.BytesIO()
139
+ plt.savefig(plot_daily, format="png", bbox_inches="tight")
140
+ plt.close()
141
+ plot_daily.seek(0)
142
+ else:
143
+ daily_logs = filtered_df.groupby(filtered_df['Timestamp'].dt.date).size()
144
+ if daily_logs.empty:
145
+ error_msg += "Warning: No data for Daily Log Trends.\n"
146
+ plt.figure(figsize=(8, 4))
147
+ plt.title("Daily Log Trends - No Data")
148
+ plt.xlabel("Date")
149
+ plt.ylabel("Number of Logs")
150
+ plot_daily = io.BytesIO()
151
+ plt.savefig(plot_daily, format="png", bbox_inches="tight")
152
+ plt.close()
153
+ plot_daily.seek(0)
154
+ else:
155
+ plt.figure(figsize=(8, 4))
156
+ daily_logs.plot(kind='line', marker='o', color='blue')
157
+ plt.title("Daily Log Trends")
158
+ plt.xlabel("Date")
159
+ plt.ylabel("Number of Logs")
160
+ plt.xticks(rotation=45)
161
+ plot_daily = io.BytesIO()
162
+ plt.savefig(plot_daily, format="png", bbox_inches="tight")
163
+ plt.close()
164
+ plot_daily.seek(0)
165
  except Exception as e:
166
+ error_msg += f"Error generating Daily Log Trends: {str(e)}\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  plt.figure(figsize=(8, 4))
168
+ plt.title("Daily Log Trends - Error")
169
  plt.xlabel("Date")
170
  plt.ylabel("Number of Logs")
171
+ plot_daily = io.BytesIO()
172
+ plt.savefig(plot_daily, format="png", bbox_inches="tight")
173
  plt.close()
174
+ plot_daily.seek(0)
175
+
176
+ # Weekly Uptime % (Bar Chart)
177
+ try:
178
+ if df['Timestamp'].isna().all():
179
+ error_msg += "Warning: All timestamps are invalid. Skipping Weekly Uptime.\n"
180
  plt.figure(figsize=(8, 4))
181
+ plt.title("Weekly Uptime % - No Data (Invalid Timestamps)")
182
  plt.xlabel("Date")
183
+ plt.ylabel("Uptime %")
184
+ plot_uptime = io.BytesIO()
185
+ plt.savefig(plot_uptime, format="png", bbox_inches="tight")
186
  plt.close()
187
+ plot_uptime.seek(0)
188
  else:
189
+ end_date = filtered_df['Timestamp'].max()
190
+ start_date = end_date - timedelta(days=7)
191
+ weekly_df = filtered_df[(filtered_df['Timestamp'] >= start_date) & (filtered_df['Timestamp'] <= end_date)]
192
+ if weekly_df.empty:
193
+ error_msg += "Warning: No data for Weekly Uptime % (date range too narrow).\n"
194
+ plt.figure(figsize=(8, 4))
195
+ plt.title("Weekly Uptime % - No Data")
196
+ plt.xlabel("Date")
197
+ plt.ylabel("Uptime %")
198
+ plot_uptime = io.BytesIO()
199
+ plt.savefig(plot_uptime, format="png", bbox_inches="tight")
200
+ plt.close()
201
+ plot_uptime.seek(0)
202
+ else:
203
+ uptime = weekly_df.groupby(weekly_df['Timestamp'].dt.date)['Status'].apply(lambda x: (x == 'Up').mean() * 100)
204
+ plt.figure(figsize=(8, 4))
205
+ uptime.plot(kind='bar', color='green')
206
+ plt.title("Weekly Uptime %")
207
+ plt.xlabel("Date")
208
+ plt.ylabel("Uptime %")
209
+ plt.xticks(rotation=45)
210
+ plot_uptime = io.BytesIO()
211
+ plt.savefig(plot_uptime, format="png", bbox_inches="tight")
212
+ plt.close()
213
+ plot_uptime.seek(0)
214
+ except Exception as e:
215
+ error_msg += f"Error generating Weekly Uptime %: {str(e)}\n"
216
  plt.figure(figsize=(8, 4))
217
+ plt.title("Weekly Uptime % - Error")
218
  plt.xlabel("Date")
219
  plt.ylabel("Uptime %")
220
+ plot_uptime = io.BytesIO()
221
+ plt.savefig(plot_uptime, format="png", bbox_inches="tight")
222
  plt.close()
223
+ plot_uptime.seek(0)
224
+
225
+ # Anomaly Alerts (Text)
226
+ try:
227
+ anomalies = filtered_df[(filtered_df['UsageCount'] > 80) | (filtered_df['Status'] == 'Down')]
228
+ if anomalies.empty:
229
+ anomaly_text = "No anomalies detected."
 
 
 
 
 
 
 
 
230
  else:
231
+ anomaly_text = "Anomalies Detected:\n" + anomalies[['DeviceID', 'Lab', 'Type', 'Status', 'UsageCount']].to_string(index=False)
232
+ except Exception as e:
233
+ error_msg += f"Error generating Anomaly Alerts: {str(e)}\n"
234
+ anomaly_text = "Error generating anomaly alerts."
235
+
236
+ return device_cards, plot_daily, plot_uptime, anomaly_text, f"{error_msg}Filters applied successfully."
 
 
 
 
 
237
  except Exception as e:
238
+ error_msg += f"Unexpected error in filter_and_visualize: {str(e)}\n"
239
+ plt.figure(figsize=(8, 4))
240
+ plt.title("Daily Log Trends - Error")
241
+ plt.xlabel("Date")
242
+ plt.ylabel("Number of Logs")
243
+ plot_daily = io.BytesIO()
244
+ plt.savefig(plot_daily, format="png", bbox_inches="tight")
245
+ plt.close()
246
+ plot_daily.seek(0)
247
+
248
  plt.figure(figsize=(8, 4))
249
  plt.title("Weekly Uptime % - Error")
250
  plt.xlabel("Date")
251
  plt.ylabel("Uptime %")
252
+ plot_uptime = io.BytesIO()
253
+ plt.savefig(plot_uptime, format="png", bbox_inches="tight")
254
  plt.close()
255
+ plot_uptime.seek(0)
256
+
257
+ return None, plot_daily, plot_uptime, "Error generating anomaly alerts.", error_msg
 
 
 
 
 
 
 
 
 
 
 
258
 
259
  def download_pdf(selected_lab, selected_type, selected_date_range):
260
  global df
261
+ try:
262
+ if df.empty:
263
+ return None
264
+
265
+ filtered_df = df.copy()
266
+ if selected_lab != "All":
267
+ filtered_df = filtered_df[filtered_df["Lab"] == selected_lab]
268
+ if selected_type != "All":
269
+ filtered_df = filtered_df[filtered_df["Type"] == selected_type]
270
+ if selected_date_range != "All" and selected_date_range != "No data available." and not df['Timestamp'].isna().all():
271
+ start_date, end_date = selected_date_range.split(" to ")
272
+ start_date = pd.to_datetime(start_date)
273
+ end_date = pd.to_datetime(end_date) + timedelta(days=1)
274
+ filtered_df = filtered_df[(filtered_df["Timestamp"] >= start_date) & (filtered_df["Timestamp"] < end_date)]
275
+
276
+ if filtered_df.empty:
277
+ return None
278
+
279
+ pdf = FPDF()
280
+ pdf.add_page()
281
+ pdf.set_font("Arial", size=12)
282
+ pdf.cell(200, 10, txt="LabOps Dashboard Report", ln=True, align='C')
283
+ pdf.ln(10)
284
+
285
+ for index, row in filtered_df.iterrows():
286
+ line = f"{row['Timestamp']} | {row['DeviceID']} | {row['Lab']} | {row['Type']} | {row['Status']} | {row['UsageCount']}"
287
+ pdf.multi_cell(0, 10, txt=line)
288
+
289
+ output = io.BytesIO()
290
+ pdf.output(output)
291
+ output.seek(0)
292
+ return output
293
+ except Exception as e:
294
+ print(f"Error in download_pdf: {str(e)}")
295
  return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
 
297
  # Build the Gradio interface
298
  with gr.Blocks() as demo: