RathodHarish commited on
Commit
741ce34
·
verified ·
1 Parent(s): 639c015

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +274 -0
app.py ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ from datetime import datetime
4
+ 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. "
31
+ f"There were {total_devices} devices. "
32
+ f"The most used device was {most_used}."
33
+ )
34
+ summary = summarizer(prompt, max_length=200, do_sample=False)[0]["generated_text"]
35
+ logging.info("Summary generated successfully")
36
+ return summary
37
+ except Exception as e:
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"]]
53
+ if anomalies.empty:
54
+ return "No anomalies detected."
55
+
56
+ anomaly_lines = ["**Detected Anomalies:**"]
57
+ for idx, row in anomalies.iterrows():
58
+ anomaly_lines.append(f"- Device ID: {row['device_id']}")
59
+ anomaly_lines.append(f" Usage Hours: {row['usage_hours']}")
60
+ anomaly_lines.append(f" Downtime: {row['downtime']}")
61
+ anomaly_lines.append(f" Timestamp: {row['timestamp']}")
62
+ anomaly_lines.append("---")
63
+ anomaly_lines.append("")
64
+ anomaly_list = "\n".join(anomaly_lines)
65
+ logging.info("Anomalies detected successfully")
66
+ return anomaly_list
67
+ except Exception as e:
68
+ logging.error(f"Anomaly detection failed: {str(e)}")
69
+ return f"Anomaly detection failed: {str(e)}"
70
+
71
+ # AMC Reminders based on device and AMC date
72
+ def check_amc_reminders(df, current_date):
73
+ try:
74
+ if "device_id" not in df.columns or "amc_date" not in df.columns:
75
+ logging.warning("Required columns for AMC reminders not found")
76
+ return "AMC reminders require 'device_id' and 'amc_date' columns."
77
+
78
+ df["amc_date"] = pd.to_datetime(df["amc_date"])
79
+ current_date = pd.to_datetime(current_date)
80
+
81
+ df["days_to_amc"] = (df["amc_date"] - current_date).dt.days
82
+ reminders = df[(df["days_to_amc"] >= 0) & (df["days_to_amc"] <= 30)][["device_id", "amc_date"]]
83
+
84
+ if reminders.empty:
85
+ return "No AMC reminders due within the next 30 days."
86
+
87
+ reminder_lines = ["**Upcoming AMC Reminders:**"]
88
+ for idx, row in reminders.iterrows():
89
+ reminder_lines.append(f"- Device ID: {row['device_id']}")
90
+ reminder_lines.append(f" AMC Date: {row['amc_date']}")
91
+ reminder_lines.append("---")
92
+ reminder_lines.append("")
93
+ reminder_list = "\n".join(reminder_lines)
94
+ logging.info("AMC reminders generated successfully")
95
+ return reminder_list
96
+ except Exception as e:
97
+ logging.error(f"AMC reminder generation failed: {str(e)}")
98
+ return f"AMC reminder generation failed: {str(e)}"
99
+
100
+ # Dashboard Insights (AI-generated executive-level insights)
101
+ def generate_dashboard_insights(df):
102
+ try:
103
+ total_devices = df["device_id"].nunique()
104
+ avg_usage = df["usage_hours"].mean() if "usage_hours" in df.columns else 0
105
+ prompt = (
106
+ f"Generate executive-level insights. "
107
+ f"There were {total_devices} devices with an average usage of {avg_usage:.2f} hours."
108
+ )
109
+ insights = summarizer(prompt, max_length=150, do_sample=False)[0]["generated_text"]
110
+ logging.info("Dashboard insights generated successfully")
111
+ return insights
112
+ except Exception as e:
113
+ logging.error(f"Dashboard insights generation failed: {str(e)}")
114
+ return f"Dashboard insights generation failed: {str(e)}"
115
+
116
+ # Create a bar chart for usage hours per device
117
+ def create_usage_chart(df):
118
+ try:
119
+ usage_data = df.groupby("device_id")["usage_hours"].sum().reset_index()
120
+ fig = px.bar(
121
+ usage_data,
122
+ x="device_id",
123
+ y="usage_hours",
124
+ title="Usage Hours per Device",
125
+ labels={"device_id": "Device ID", "usage_hours": "Usage Hours"},
126
+ color="usage_hours",
127
+ color_continuous_scale="Blues"
128
+ )
129
+ fig.update_layout(
130
+ title_font_size=16,
131
+ margin=dict(l=20, r=20, t=40, b=20),
132
+ plot_bgcolor="white",
133
+ paper_bgcolor="white",
134
+ font=dict(size=12)
135
+ )
136
+ return fig
137
+ except Exception as e:
138
+ logging.error(f"Failed to create usage chart: {str(e)}")
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."
147
+
148
+ file_name = file_obj.name if hasattr(file_obj, 'name') else file_obj
149
+ logging.info(f"Processing file: {file_name}")
150
+
151
+ if not file_name.endswith(".csv"):
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
163
+
164
+ if df.empty:
165
+ logging.warning("No data in the file")
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\n{summarize_logs(df)}\n\n---\n"
170
+
171
+ # Step 2: Log Preview
172
+ if not df.empty:
173
+ preview_lines = ["**Step 2: Log Preview (First 5 Rows)**\n"]
174
+ for idx, row in df.head().iterrows():
175
+ preview_lines.append(f"**Row {idx + 1}:**")
176
+ preview_lines.append(f"- Device ID: {row['device_id']}")
177
+ preview_lines.append(f"- Timestamp: {row['timestamp']}")
178
+ preview_lines.append(f"- Usage Hours: {row['usage_hours']}")
179
+ preview_lines.append(f"- Downtime: {row['downtime']}")
180
+ preview_lines.append(f"- AMC Date: {row['amc_date']}")
181
+ preview_lines.append("---")
182
+ preview_lines.append("")
183
+ preview = "\n".join(preview_lines) + "\n---\n"
184
+ else:
185
+ preview = "**Step 2: Log Preview**\n\nNo data available.\n\n---\n"
186
+
187
+ # Step 3: Usage Chart
188
+ chart = create_usage_chart(df)
189
+
190
+ # Step 4: Anomaly Detection
191
+ anomalies = f"**Step 3: Anomaly Detection**\n\n{detect_anomalies(df)}\n\n---\n"
192
+
193
+ # Step 5: AMC Reminders
194
+ amc_reminders = f"**Step 4: AMC Reminders**\n\n{check_amc_reminders(df, datetime.now())}\n\n---\n"
195
+
196
+ # Step 6: Dashboard Insights
197
+ insights = f"**Step 5: Dashboard Insights (AI)**\n\n{generate_dashboard_insights(df)}\n\n---\n"
198
+
199
+ return summary, preview, chart, anomalies, amc_reminders, insights
200
+ except Exception as e:
201
+ logging.error(f"Failed to process file: {str(e)}")
202
+ return f"Failed to process file: {str(e)}", None, None, None, None, None
203
+
204
+ # Gradio Interface with Step-by-Step Layout
205
+ try:
206
+ logging.info("Initializing Gradio Blocks interface...")
207
+ with gr.Blocks(css="""
208
+ .dashboard-container {border: 1px solid #e0e0e0; padding: 10px; border-radius: 5px; background-color: #f9f9f9;}
209
+ .dashboard-title {font-size: 24px; font-weight: bold; margin-bottom: 10px;}
210
+ .dashboard-section {margin-bottom: 15px;}
211
+ .dashboard-section h3 {font-size: 18px; margin-bottom: 5px;}
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.")
215
+
216
+ with gr.Row():
217
+ with gr.Column(scale=1):
218
+ file_input = gr.File(label="Upload Logs (CSV)", file_types=[".csv"])
219
+ submit_button = gr.Button("Submit", variant="primary")
220
+
221
+ with gr.Column(scale=2):
222
+ with gr.Group(elem_classes="dashboard-container"):
223
+ gr.Markdown("<div class='dashboard-title'>Analysis Results (Step-by-Step)</div>")
224
+
225
+ # Step 1: Summary Report
226
+ with gr.Group(elem_classes="dashboard-section"):
227
+ gr.Markdown("### Step 1: Summary Report")
228
+ summary_output = gr.Markdown()
229
+
230
+ # Step 2: Log Preview
231
+ with gr.Group(elem_classes="dashboard-section"):
232
+ gr.Markdown("### Step 2: Log Preview")
233
+ preview_output = gr.Markdown()
234
+
235
+ # Step 3: Usage Chart
236
+ with gr.Group(elem_classes="dashboard-section"):
237
+ gr.Markdown("### Step 3: Usage Chart")
238
+ chart_output = gr.Plot()
239
+
240
+ # Step 4: Anomaly Detection
241
+ with gr.Group(elem_classes="dashboard-section"):
242
+ gr.Markdown("### Step 4: Anomaly Detection")
243
+ anomaly_output = gr.Markdown()
244
+
245
+ # Step 5: AMC Reminders
246
+ with gr.Group(elem_classes="dashboard-section"):
247
+ gr.Markdown("### Step 5: AMC Reminders")
248
+ amc_output = gr.Markdown()
249
+
250
+ # Step 6: Dashboard Insights
251
+ with gr.Group(elem_classes="dashboard-section"):
252
+ gr.Markdown("### Step 6: Dashboard Insights (AI)")
253
+ insights_output = gr.Markdown()
254
+
255
+ submit_button.click(
256
+ fn=process_logs,
257
+ inputs=[file_input],
258
+ outputs=[summary_output, preview_output, chart_output, anomaly_output, amc_output, insights_output]
259
+ )
260
+
261
+ logging.info("Gradio interface initialized successfully")
262
+ except Exception as e:
263
+ logging.error(f"Failed to initialize Gradio interface: {str(e)}")
264
+ raise e
265
+
266
+ if __name__ == "__main__":
267
+ try:
268
+ logging.info("Launching Gradio interface...")
269
+ iface.launch(server_name="0.0.0.0", server_port=7860, debug=True, share=False)
270
+ logging.info("Gradio interface launched successfully")
271
+ except Exception as e:
272
+ logging.error(f"Failed to launch Gradio interface: {str(e)}")
273
+ print(f"Error launching app: {str(e)}")
274
+ raise e