MaheshP98 commited on
Commit
8846627
Β·
verified Β·
1 Parent(s): c19f32d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -188
app.py CHANGED
@@ -1,199 +1,45 @@
1
  import streamlit as st
2
  import pandas as pd
3
- import plotly.express as px
4
- from datetime import datetime, timedelta
5
- from simple_salesforce import Salesforce
6
- from transformers import pipeline
7
- from utils import fetch_salesforce_data, detect_anomalies, generate_pdf_report
8
- import os
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
- # Streamlit app configuration
16
- try:
17
- st.set_page_config(page_title="LabOps Dashboard", layout="wide")
18
- logger.info("Streamlit page configuration set successfully.")
19
- except Exception as e:
20
- logger.error(f"Failed to set Streamlit page configuration: {e}")
21
- raise
22
 
23
- # Cache Salesforce connection
24
- @st.cache_resource
25
- def init_salesforce():
26
- logger.info("Initializing Salesforce connection...")
27
- try:
28
- sf = Salesforce(
29
- username=os.getenv("SF_USERNAME", st.secrets.get("sf_username")),
30
- password=os.getenv("SF_PASSWORD", st.secrets.get("sf_password")),
31
- security_token=os.getenv("SF_SECURITY_TOKEN", st.secrets.get("sf_security_token"))
32
- )
33
- logger.info("Salesforce connection initialized successfully.")
34
- return sf
35
- except Exception as e:
36
- logger.error(f"Failed to initialize Salesforce: {e}")
37
- st.error(f"Cannot connect to Salesforce: {e}")
38
- return None
39
 
40
- # Cache Hugging Face model
41
- @st.cache_resource
42
- def init_anomaly_detector():
43
- logger.info("Initializing anomaly detector...")
44
- try:
45
- # Use lighter model for Hugging Face Spaces
46
- detector = pipeline(
47
- "text-classification",
48
- model="prajjwal1/bert-tiny",
49
- tokenizer="prajjwal1/bert-tiny",
50
- clean_up_tokenization_spaces=True
51
- )
52
- logger.info("Anomaly detector initialized successfully.")
53
- return detector
54
- except Exception as e:
55
- logger.error(f"Failed to initialize anomaly detector: {e}")
56
- st.error(f"Cannot initialize anomaly detector: {e}")
57
- return None
58
 
59
- # Initialize connections
60
- sf = init_salesforce()
61
- anomaly_detector = init_anomaly_detector()
62
 
63
- # Cache data fetching
64
- @st.cache_data(ttl=10)
65
- def get_filtered_data(lab_site, equipment_type, date_start, date_end):
66
- logger.info(f"Fetching data for lab: {lab_site}, equipment: {equipment_type}, date range: {date_start} to {date_end}")
67
  try:
68
- query = f"""
69
- SELECT Equipment__c, Log_Timestamp__c, Status__c, Usage_Count__c, Lab__c, Equipment_Type__c
70
- FROM SmartLog__c
71
- WHERE Log_Timestamp__c >= {date_start.strftime('%Y-%m-%d')}
72
- AND Log_Timestamp__c <= {date_end.strftime('%Y-%m-%d')}
73
- """
74
- if lab_site != "All":
75
- query += f" AND Lab__c = '{lab_site}'"
76
- if equipment_type != "All":
77
- query += f" AND Equipment_Type__c = '{equipment_type}'"
78
- query += " LIMIT 100"
79
- data = fetch_salesforce_data(sf, query)
80
- logger.info(f"Fetched {len(data)} records from Salesforce.")
81
- return data
82
  except Exception as e:
83
- logger.error(f"Failed to fetch data: {e}")
84
- return []
85
-
86
- def main():
87
- logger.info("Starting main application...")
88
- if sf is None or anomaly_detector is None:
89
- st.error("Application cannot start due to initialization failures. Check logs for details.")
90
- logger.error("Application initialization failed: Salesforce or anomaly detector not available.")
91
- return
92
-
93
- st.title("Multi-Device LabOps Dashboard")
94
-
95
- # Filters
96
- col1, col2 = st.columns(2)
97
- with col1:
98
- lab_site = st.selectbox("Select Lab Site", ["All", "Lab1", "Lab2", "Lab3"])
99
- with col2:
100
- equipment_type = st.selectbox("Equipment Type", ["All", "Cell Analyzer", "Weight Log", "UV Verification"])
101
-
102
- date_range = st.date_input("Date Range", [datetime.now() - timedelta(days=7), datetime.now()])
103
-
104
- if len(date_range) != 2:
105
- st.warning("Please select a valid date range.")
106
- logger.warning("Invalid date range selected.")
107
- return
108
- date_start, date_end = date_range
109
-
110
- # Fetch and process data
111
- with st.spinner("Fetching data..."):
112
- data = get_filtered_data(lab_site, equipment_type, date_start, date_end)
113
- if not data:
114
- st.warning("No data available for the selected filters.")
115
- logger.warning("No data returned for the selected filters.")
116
- return
117
-
118
- df = pd.DataFrame(data)
119
- df["Log_Timestamp__c"] = pd.to_datetime(df["Log_Timestamp__c"])
120
- df["Anomaly"] = df.apply(
121
- lambda row: detect_anomalies(f"{row['Status__c']} Usage:{row['Usage_Count__c']}", anomaly_detector),
122
- axis=1
123
- )
124
-
125
- # Pagination
126
- page_size = 10
127
- total_pages = max(1, len(df) // page_size + (1 if len(df) % page_size else 0))
128
- page = st.number_input("Page", min_value=1, max_value=total_pages, value=1, step=1)
129
- start_idx = (page - 1) * page_size
130
- end_idx = start_idx + page_size
131
- paginated_df = df[start_idx:end_idx]
132
-
133
- # Device Cards
134
- st.subheader("Device Status")
135
- for _, row in paginated_df.iterrows():
136
- anomaly = "⚠️ Anomaly" if row["Anomaly"] == "POSITIVE" else "βœ… Normal"
137
- st.markdown(f"""
138
- **{row['Equipment__c']}** | Lab: {row['Lab__c']} | Health: {row['Status__c']} |
139
- Usage: {row['Usage_Count__c']} | Last Log: {row['Log_Timestamp__c'].strftime('%Y-%m-%d %H:%M:%S')} | {anomaly}
140
- """)
141
-
142
- # Usage Chart
143
- st.subheader("Usage Trends")
144
- fig = px.line(
145
- df,
146
- x="Log_Timestamp__c",
147
- y="Usage_Count__c",
148
- color="Equipment__c",
149
- title="Daily Usage Trends",
150
- labels={"Log_Timestamp__c": "Timestamp", "Usage_Count__c": "Usage Count"}
151
- )
152
- fig.update_layout(xaxis_title="Timestamp", yaxis_title="Usage Count")
153
- st.plotly_chart(fig, use_container_width=True)
154
-
155
- # Downtime Chart
156
- st.subheader("Downtime Patterns")
157
- downtime_df = df[df["Status__c"] == "Down"]
158
- if not downtime_df.empty:
159
- fig_downtime = px.histogram(
160
- downtime_df,
161
- x="Log_Timestamp__c",
162
- color="Equipment__c",
163
- title="Downtime Patterns",
164
- labels={"Log_Timestamp__c": "Timestamp"}
165
- )
166
- fig_downtime.update_layout(xaxis_title="Timestamp", yaxis_title="Downtime Count")
167
- st.plotly_chart(fig_downtime, use_container_width=True)
168
- else:
169
- st.info("No downtime events found for the selected filters.")
170
-
171
- # AMC Reminders
172
- st.subheader("AMC Reminders")
173
- amc_query = "SELECT Equipment__c, AMC_Expiry_Date__c FROM Equipment__c WHERE AMC_Expiry_Date__c <= NEXT_N_DAYS:14"
174
- amc_data = fetch_salesforce_data(sf, amc_query, retries=3)
175
- if amc_data:
176
- for record in amc_data:
177
- st.write(f"Equipment {record['Equipment__c']} - AMC Expiry: {record['AMC_Expiry_Date__c']}")
178
  else:
179
- st.info("No AMC expiries within the next 14 days.")
180
-
181
- # Export PDF
182
- if st.button("Export PDF Report"):
183
- with st.spinner("Generating PDF..."):
184
- try:
185
- pdf_file = generate_pdf_report(df, lab_site, equipment_type, [date_start, date_end])
186
- with open(pdf_file, "rb") as f:
187
- st.download_button("Download PDF", f, file_name="LabOps_Report.pdf", mime="application/pdf")
188
- logger.info("PDF report generated successfully.")
189
- except Exception as e:
190
- st.error(f"Failed to generate PDF: {e}")
191
- logger.error(f"Failed to generate PDF: {e}")
192
-
193
- if __name__ == "__main__":
194
- try:
195
- logger.info("Application starting...")
196
- main()
197
- except Exception as e:
198
- logger.error(f"Application failed to start: {e}")
199
- raise
 
1
  import streamlit as st
2
  import pandas as pd
3
+ from utils.load_data import load_logs
4
+ from utils.visualize import plot_usage
5
+ from utils.report import generate_pdf
6
+ from models.anomaly import detect_anomalies
7
+ from utils.amc import upcoming_amc_devices
 
 
8
 
9
+ st.set_page_config(page_title="LabOps Dashboard", layout="wide")
10
+ st.title("πŸ“Š Multi-Device LabOps Dashboard")
 
11
 
12
+ uploaded_files = st.file_uploader("Upload Device Logs (CSV)", accept_multiple_files=True)
 
 
 
 
 
 
13
 
14
+ if uploaded_files:
15
+ df = load_logs(uploaded_files)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+ st.subheader("πŸ“‹ Uploaded Logs")
18
+ st.dataframe(df.head())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ st.subheader("πŸ“ˆ Daily Usage Chart")
21
+ st.pyplot(plot_usage(df))
 
22
 
23
+ st.subheader("🚨 Detected Anomalies")
 
 
 
24
  try:
25
+ anomalies = detect_anomalies(df)
26
+ st.dataframe(anomalies)
 
 
 
 
 
 
 
 
 
 
 
 
27
  except Exception as e:
28
+ st.error(f"Failed to compute anomalies: {e}")
29
+
30
+ st.subheader("πŸ›  Upcoming AMC Devices")
31
+ if "amc_expiry" in df.columns:
32
+ try:
33
+ amc_df = upcoming_amc_devices(df)
34
+ st.dataframe(amc_df)
35
+ except Exception as e:
36
+ st.error(f"Failed to process AMC dates: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  else:
38
+ st.info("Column `amc_expiry` not found in uploaded data.")
39
+
40
+ if st.button("πŸ“„ Generate PDF Report"):
41
+ try:
42
+ generate_pdf(df)
43
+ st.success("βœ… PDF report generated and saved to /tmp/labops_report.pdf")
44
+ except Exception as e:
45
+ st.error(f"Failed to generate PDF: {e}")