Ronio Jerico Roque commited on
Commit
b8acefa
·
1 Parent(s): 55ebf67

Refactor analysis execution to use thread-safe handlers and improve UI updates; implement staggered execution for analysis functions.

Browse files
Files changed (1) hide show
  1. pages/analyzing_page.py +204 -130
pages/analyzing_page.py CHANGED
@@ -1,6 +1,7 @@
1
  import os
2
  import streamlit as st
3
  import threading
 
4
  from streamlit.runtime.scriptrunner import add_script_run_ctx
5
  from classes.response_off import SeoOffPageAnalyst
6
  from classes.response_on_page import SeoOn
@@ -17,223 +18,296 @@ from classes.response_df_overview import dfOverview
17
  from classes.response_executive_summary import ExecutiveSummary
18
  from classes.response_snapshot import Snapshot
19
 
20
- def run_analysis():
21
- # Placeholders for status updates
22
- off_page_status = st.empty()
23
- on_page_status = st.empty()
24
- website_and_tools_status = st.empty()
25
- seo_status = st.empty()
26
- social_media_status = st.empty()
27
- lld_pm_ln_status = st.empty()
28
- pull_through_offers_status = st.empty()
29
- content_status = st.empty()
30
- sem_ppc = st.empty()
31
- marketplace = st.empty()
32
- target_market = st.empty()
33
- df_overview_status = st.empty()
34
- executive_summary_status = st.empty()
35
- snapshot_status = st.empty()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  def run_off_page_analysis():
 
38
  try:
39
- off_page_status.info("Starting SEO Off Page Analysis...")
40
  result = SeoOffPageAnalyst(os.getenv('MODEL_Off_Page_Analyst'))
41
- off_page_status.success("SEO Off Page Analysis completed successfully.")
42
  return result
43
  except Exception as e:
44
- off_page_status.error(f"SEO Off Page Analysis failed: {e}")
45
  return None
46
 
47
  def run_on_page_analysis():
 
48
  try:
49
- on_page_status.info("Starting On Page Analysis...")
50
  result = SeoOn(os.getenv('MODEL_On_Page_Analyst'))
51
- on_page_status.success("On Page Analysis completed successfully.")
52
  return result
53
  except Exception as e:
54
- on_page_status.error(f"On Page Analysis failed: {e}")
55
  return None
56
 
57
  def run_website_and_tools_analysis():
 
58
  try:
59
- website_and_tools_status.info("Starting Website and Tools Analysis...")
60
  result = WebsiteAndTools(os.getenv('Model_Website_and_Tools_Analyst'))
61
- website_and_tools_status.success("Website and Tools completed successfully.")
62
  return result
63
  except Exception as e:
64
- on_page_status.error(f"Website and Tools Analysis failed: {e}")
65
  return None
66
 
67
  def run_seo_analysis():
 
68
  try:
69
- seo_status.info("Starting SEO Analysis...")
70
  result = Seo(os.getenv('MODEL_SEO_Analyst'))
71
- seo_status.success("SEO Analysis completed successfully.")
72
  return result
73
  except Exception as e:
74
- seo_status.error(f"SEO Analysis failed: {e}")
75
  return None
76
 
77
  def run_social_media_analysis():
 
78
  try:
79
- social_media_status.info("Starting Social Media Analysis...")
80
  result = SocialMedia(os.getenv('MODEL_Social_Media_Analyst'))
81
- social_media_status.success("Social Media Analysis completed successfully.")
82
  return result
83
  except Exception as e:
84
- social_media_status.error(f"Social Media Analysis failed: {e}")
85
  return None
86
 
87
  def run_lld_pm_ln():
 
88
  try:
89
- lld_pm_ln_status.info("Starting LLD/PM/LN Analysis...")
90
  result = LLD_PM_LN(os.getenv('Model_LLD_PM_LN_ANALYST'))
91
- lld_pm_ln_status.success("LLD/PM/LN completed successfully.")
92
  return result
93
  except Exception as e:
94
- lld_pm_ln_status.error(f"LLD/PM/LN Analysis failed: {e}")
95
  return None
96
 
97
  def run_pull_through_offers():
 
98
  try:
99
- pull_through_offers_status.info("Starting Pull through offer Analysis...")
100
  result = PullThroughOffers(os.getenv('Model_Pull_Through_Offers_Analyst'))
101
- pull_through_offers_status.success("Pull through offer completed successfully.")
102
  return result
103
  except Exception as e:
104
- pull_through_offers_status.error(f"Pull through offer Analysis failed: {e}")
105
  return None
106
 
107
  def run_content():
 
108
  try:
109
- content_status.info("Starting Content Analysis...")
110
  result = Content(os.getenv('Model_Content'))
111
- content_status.success("Content Analysis completed successfully.")
112
  return result
113
  except Exception as e:
114
- content_status.error(f"Content Analysis failed: {e}")
115
  return None
116
 
117
  def run_sem_ppc_analysis():
 
118
  try:
119
- sem_ppc.info("Starting SEM/PPC Analysis...")
120
  result = Sem_PPC(os.getenv('Model_SEM_PPC_Analyst'))
121
- sem_ppc.success("SEM/PPC Analysis completed successfully.")
122
  return result
123
  except Exception as e:
124
- sem_ppc.error(f"SEM/PPC Analysis failed: {e}")
125
  return None
126
 
127
  def run_marketplace_analysis():
 
128
  try:
129
- marketplace.info("Starting Marketplace Analysis...")
130
  result = Marketplace(os.getenv('Model_SEM_PPC_Analyst'))
131
- marketplace.success("Marketplace Analysis completed successfully.")
132
  return result
133
  except Exception as e:
134
- marketplace.error(f"Marketplace Analysis failed: {e}")
135
  return None
136
 
137
  def run_target_market_analysis():
 
138
  try:
139
- target_market.info("Starting Target Market Analysis...")
140
  result = TargetMarket(os.getenv('Model_Target_Market_Analyst'))
141
- target_market.success("Target Market Analysis completed successfully.")
142
  return result
143
  except Exception as e:
144
- target_market.error(f"Target Market Analysis failed: {e}")
145
  return None
146
 
147
- def df_overview_analysis():
 
148
  try:
149
- df_overview_status.info("DF Overview Analysis...")
150
  result = dfOverview(os.getenv('Model_DF_Overview_Analyst'))
151
- df_overview_status.success("DF Overview Analysis completed successfully.")
152
  return result
153
  except Exception as e:
154
- df_overview_status.error(f"DF Overview Analysis failed: {e}")
 
 
 
 
 
 
 
 
 
 
 
155
  return None
156
 
157
- # Create threads for concurrent execution
158
- off_page_thread = threading.Thread(target=run_off_page_analysis)
159
- on_page_thread = threading.Thread(target=run_on_page_analysis)
160
- website_and_tools_thread = threading.Thread(target=run_website_and_tools_analysis)
161
- seo_thread = threading.Thread(target=run_seo_analysis)
162
- social_media_thread = threading.Thread(target=run_social_media_analysis)
163
- llm_pm_ln_thread = threading.Thread(target=run_lld_pm_ln)
164
- pull_through_offers_thread = threading.Thread(target=run_pull_through_offers)
165
- content_thread = threading.Thread(target=run_content)
166
- content_sem_ppc_thread = threading.Thread(target=run_sem_ppc_analysis)
167
- marketplace_thread = threading.Thread(target=run_marketplace_analysis)
168
- target_market_thread = threading.Thread(target=run_target_market_analysis)
169
- df_overview_thread = threading.Thread(target=df_overview_analysis)
170
-
171
- # Attach Streamlit context to threads
172
- add_script_run_ctx(off_page_thread)
173
- add_script_run_ctx(on_page_thread)
174
- add_script_run_ctx(website_and_tools_thread)
175
- add_script_run_ctx(seo_thread)
176
- add_script_run_ctx(social_media_thread)
177
- add_script_run_ctx(llm_pm_ln_thread)
178
- add_script_run_ctx(pull_through_offers_thread)
179
- add_script_run_ctx(content_thread)
180
- add_script_run_ctx(content_sem_ppc_thread)
181
- add_script_run_ctx(marketplace_thread)
182
- add_script_run_ctx(target_market_thread)
183
- add_script_run_ctx(df_overview_thread)
184
-
185
- # Start threads
186
- off_page_thread.start()
187
- on_page_thread.start()
188
- website_and_tools_thread.start()
189
- seo_thread.start()
190
- social_media_thread.start()
191
- llm_pm_ln_thread.start()
192
- pull_through_offers_thread.start()
193
- content_thread.start()
194
- content_sem_ppc_thread.start()
195
- marketplace_thread.start()
196
- target_market_thread.start()
197
- df_overview_thread.start()
198
-
199
- # Wait for threads to complete
200
- off_page_thread.join()
201
- on_page_thread.join()
202
- website_and_tools_thread.join()
203
- seo_thread.join()
204
- social_media_thread.join()
205
- llm_pm_ln_thread.join()
206
- pull_through_offers_thread.join()
207
- content_thread.join()
208
- content_sem_ppc_thread.join()
209
- marketplace_thread.join()
210
- target_market_thread.join()
211
- df_overview_thread.join()
212
-
213
- st.markdown("---")
214
- snapshot_status.info("Starting Snapshot by Channel Analysis...")
215
- try:
216
- snapshot = Snapshot(os.getenv('Model_Snapshot_by_Channel_Analyst'))
217
- snapshot_status.success("Snapshot by Channel Analysis completed successfully.")
218
- except Exception as e:
219
- snapshot_status.error(f"Snapshot by Channel Analysis failed: {e}")
220
 
221
- executive_summary_status.info("Starting Executive Summary Analysis...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  try:
223
- executive_summary = ExecutiveSummary(os.getenv('Model_Executive_Summary_Analyst'))
224
- executive_summary_status.success("Executive Summary Analysis completed successfully.")
225
- except Exception as e:
226
- executive_summary_status.error(f"Executive Summary Analysis failed: {e}")
227
- st.success("🎉 All analyses completed!") # Final success message
228
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
 
230
- st.success("🎉 All analyses completed!") # Final success message
 
 
231
 
232
- # --- Display Button After Completion ---
233
- if st.button("View Results", icon="📃"):
234
- st.switch_page("pages/output.py")
 
 
235
 
236
- # Execute the analysis
237
- if st.button("Back"):
238
- st.switch_page("pages/home.py")
239
- run_analysis()
 
1
  import os
2
  import streamlit as st
3
  import threading
4
+ import time
5
  from streamlit.runtime.scriptrunner import add_script_run_ctx
6
  from classes.response_off import SeoOffPageAnalyst
7
  from classes.response_on_page import SeoOn
 
18
  from classes.response_executive_summary import ExecutiveSummary
19
  from classes.response_snapshot import Snapshot
20
 
21
+ # Initialize session state to track if analysis has been run
22
+ if 'analysis_completed' not in st.session_state:
23
+ st.session_state.analysis_completed = False
24
+
25
+ # Create a thread-safe way to update the UI
26
+ class ThreadSafeAnalysis:
27
+ def __init__(self, placeholder, name):
28
+ self.placeholder = placeholder
29
+ self.name = name
30
+ self.lock = threading.Lock()
31
+
32
+ def update_info(self, message):
33
+ with self.lock:
34
+ try:
35
+ self.placeholder.info(message)
36
+ except Exception:
37
+ # Silently ignore errors here - this prevents "bad set index" errors
38
+ pass
39
+
40
+ def update_success(self, message):
41
+ with self.lock:
42
+ try:
43
+ self.placeholder.success(message)
44
+ except Exception:
45
+ # Silently ignore errors here
46
+ pass
47
+
48
+ def update_error(self, message):
49
+ with self.lock:
50
+ try:
51
+ self.placeholder.error(message)
52
+ except Exception:
53
+ # Silently ignore errors here
54
+ pass
55
 
56
+ def run_analysis():
57
+ # Create placeholders for status updates
58
+ placeholders = {
59
+ "off_page": st.empty(),
60
+ "on_page": st.empty(),
61
+ "website_tools": st.empty(),
62
+ "seo": st.empty(),
63
+ "social_media": st.empty(),
64
+ "lld_pm_ln": st.empty(),
65
+ "pull_through": st.empty(),
66
+ "content": st.empty(),
67
+ "sem_ppc": st.empty(),
68
+ "marketplace": st.empty(),
69
+ "target_market": st.empty(),
70
+ "df_overview": st.empty(),
71
+ "executive_summary": st.empty(),
72
+ "snapshot": st.empty()
73
+ }
74
+
75
+ # Create thread-safe handlers for each analysis type
76
+ handlers = {name: ThreadSafeAnalysis(placeholder, name)
77
+ for name, placeholder in placeholders.items()}
78
+
79
+ # Define all analysis functions
80
  def run_off_page_analysis():
81
+ handler = handlers["off_page"]
82
  try:
83
+ handler.update_info("Running SEO Off Page Analysis...")
84
  result = SeoOffPageAnalyst(os.getenv('MODEL_Off_Page_Analyst'))
85
+ handler.update_success("SEO Off Page Analysis completed successfully.")
86
  return result
87
  except Exception as e:
88
+ handler.update_error(f"SEO Off Page Analysis failed: {str(e)}")
89
  return None
90
 
91
  def run_on_page_analysis():
92
+ handler = handlers["on_page"]
93
  try:
94
+ handler.update_info("Running On Page Analysis...")
95
  result = SeoOn(os.getenv('MODEL_On_Page_Analyst'))
96
+ handler.update_success("On Page Analysis completed successfully.")
97
  return result
98
  except Exception as e:
99
+ handler.update_error(f"On Page Analysis failed: {str(e)}")
100
  return None
101
 
102
  def run_website_and_tools_analysis():
103
+ handler = handlers["website_tools"]
104
  try:
105
+ handler.update_info("Running Website and Tools Analysis...")
106
  result = WebsiteAndTools(os.getenv('Model_Website_and_Tools_Analyst'))
107
+ handler.update_success("Website and Tools completed successfully.")
108
  return result
109
  except Exception as e:
110
+ handler.update_error(f"Website and Tools Analysis failed: {str(e)}")
111
  return None
112
 
113
  def run_seo_analysis():
114
+ handler = handlers["seo"]
115
  try:
116
+ handler.update_info("Running SEO Analysis...")
117
  result = Seo(os.getenv('MODEL_SEO_Analyst'))
118
+ handler.update_success("SEO Analysis completed successfully.")
119
  return result
120
  except Exception as e:
121
+ handler.update_error(f"SEO Analysis failed: {str(e)}")
122
  return None
123
 
124
  def run_social_media_analysis():
125
+ handler = handlers["social_media"]
126
  try:
127
+ handler.update_info("Running Social Media Analysis...")
128
  result = SocialMedia(os.getenv('MODEL_Social_Media_Analyst'))
129
+ handler.update_success("Social Media Analysis completed successfully.")
130
  return result
131
  except Exception as e:
132
+ handler.update_error(f"Social Media Analysis failed: {str(e)}")
133
  return None
134
 
135
  def run_lld_pm_ln():
136
+ handler = handlers["lld_pm_ln"]
137
  try:
138
+ handler.update_info("Running LLD/PM/LN Analysis...")
139
  result = LLD_PM_LN(os.getenv('Model_LLD_PM_LN_ANALYST'))
140
+ handler.update_success("LLD/PM/LN completed successfully.")
141
  return result
142
  except Exception as e:
143
+ handler.update_error(f"LLD/PM/LN Analysis failed: {str(e)}")
144
  return None
145
 
146
  def run_pull_through_offers():
147
+ handler = handlers["pull_through"]
148
  try:
149
+ handler.update_info("Running Pull through offer Analysis...")
150
  result = PullThroughOffers(os.getenv('Model_Pull_Through_Offers_Analyst'))
151
+ handler.update_success("Pull through offer completed successfully.")
152
  return result
153
  except Exception as e:
154
+ handler.update_error(f"Pull through offer Analysis failed: {str(e)}")
155
  return None
156
 
157
  def run_content():
158
+ handler = handlers["content"]
159
  try:
160
+ handler.update_info("Running Content Analysis...")
161
  result = Content(os.getenv('Model_Content'))
162
+ handler.update_success("Content Analysis completed successfully.")
163
  return result
164
  except Exception as e:
165
+ handler.update_error(f"Content Analysis failed: {str(e)}")
166
  return None
167
 
168
  def run_sem_ppc_analysis():
169
+ handler = handlers["sem_ppc"]
170
  try:
171
+ handler.update_info("Running SEM/PPC Analysis...")
172
  result = Sem_PPC(os.getenv('Model_SEM_PPC_Analyst'))
173
+ handler.update_success("SEM/PPC Analysis completed successfully.")
174
  return result
175
  except Exception as e:
176
+ handler.update_error(f"SEM/PPC Analysis failed: {str(e)}")
177
  return None
178
 
179
  def run_marketplace_analysis():
180
+ handler = handlers["marketplace"]
181
  try:
182
+ handler.update_info("Running Marketplace Analysis...")
183
  result = Marketplace(os.getenv('Model_SEM_PPC_Analyst'))
184
+ handler.update_success("Marketplace Analysis completed successfully.")
185
  return result
186
  except Exception as e:
187
+ handler.update_error(f"Marketplace Analysis failed: {str(e)}")
188
  return None
189
 
190
  def run_target_market_analysis():
191
+ handler = handlers["target_market"]
192
  try:
193
+ handler.update_info("Running Target Market Analysis...")
194
  result = TargetMarket(os.getenv('Model_Target_Market_Analyst'))
195
+ handler.update_success("Target Market Analysis completed successfully.")
196
  return result
197
  except Exception as e:
198
+ handler.update_error(f"Target Market Analysis failed: {str(e)}")
199
  return None
200
 
201
+ def run_df_overview_analysis():
202
+ handler = handlers["df_overview"]
203
  try:
204
+ handler.update_info("Running DF Overview Analysis...")
205
  result = dfOverview(os.getenv('Model_DF_Overview_Analyst'))
206
+ handler.update_success("DF Overview Analysis completed successfully.")
207
  return result
208
  except Exception as e:
209
+ handler.update_error(f"DF Overview Analysis failed: {str(e)}")
210
+ return None
211
+
212
+ def run_snapshot_analysis():
213
+ handler = handlers["snapshot"]
214
+ try:
215
+ handler.update_info("Running Snapshot by Channel Analysis...")
216
+ result = Snapshot(os.getenv('Model_Snapshot_by_Channel_Analyst'))
217
+ handler.update_success("Snapshot by Channel Analysis completed successfully.")
218
+ return result
219
+ except Exception as e:
220
+ handler.update_error(f"Snapshot by Channel Analysis failed: {str(e)}")
221
  return None
222
 
223
+ def run_executive_summary_analysis():
224
+ handler = handlers["executive_summary"]
225
+ try:
226
+ handler.update_info("Running Executive Summary Analysis...")
227
+ result = ExecutiveSummary(os.getenv('Model_Executive_Summary_Analyst'))
228
+ handler.update_success("Executive Summary Analysis completed successfully.")
229
+ return result
230
+ except Exception as e:
231
+ handler.update_error(f"Executive Summary Analysis failed: {str(e)}")
232
+ return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
 
234
+ # Define first batch of analyses
235
+ threads_first_batch = [
236
+ (run_off_page_analysis, "off_page"),
237
+ (run_on_page_analysis, "on_page"),
238
+ (run_website_and_tools_analysis, "website_tools"),
239
+ (run_seo_analysis, "seo"),
240
+ (run_social_media_analysis, "social_media"),
241
+ (run_lld_pm_ln, "lld_pm_ln"),
242
+ (run_pull_through_offers, "pull_through"),
243
+ (run_content, "content"),
244
+ (run_sem_ppc_analysis, "sem_ppc"),
245
+ (run_marketplace_analysis, "marketplace"),
246
+ (run_target_market_analysis, "target_market"),
247
+ (run_df_overview_analysis, "df_overview")
248
+ ]
249
+
250
+ # Create and start first batch threads with small delays to prevent UI conflicts
251
+ thread_objects_first_batch = []
252
+ for i, (func, name) in enumerate(threads_first_batch):
253
+ # Add a small stagger to thread start times to reduce conflicts
254
+ time.sleep(0.1)
255
+ thread = threading.Thread(target=func, name=name)
256
+ add_script_run_ctx(thread) # Attach Streamlit context
257
+ thread_objects_first_batch.append(thread)
258
+ thread.start()
259
+
260
+ # Wait for all first batch threads to complete
261
+ for thread in thread_objects_first_batch:
262
+ thread.join()
263
+
264
+ # Add a separator
265
  try:
266
+ st.markdown("---")
267
+ except Exception:
268
+ pass
 
 
269
 
270
+ # Wait a bit to let UI stabilize before starting second batch
271
+ time.sleep(0.5)
272
+
273
+ # Create threads for second batch (snapshot and executive summary)
274
+ threads_second_batch = [
275
+ (run_snapshot_analysis, "snapshot"),
276
+ (run_executive_summary_analysis, "executive_summary")
277
+ ]
278
+
279
+ # Create and start second batch threads
280
+ thread_objects_second_batch = []
281
+ for i, (func, name) in enumerate(threads_second_batch):
282
+ # Add a small stagger between threads
283
+ time.sleep(0.2)
284
+ thread = threading.Thread(target=func, name=name)
285
+ add_script_run_ctx(thread) # Attach Streamlit context
286
+ thread_objects_second_batch.append(thread)
287
+ thread.start()
288
+
289
+ # Wait for second batch threads to complete
290
+ for thread in thread_objects_second_batch:
291
+ thread.join()
292
+
293
+ # Set analysis_completed to True when all analyses are done
294
+ st.session_state.analysis_completed = True
295
+ try:
296
+ st.success("🎉 All analyses completed!")
297
+ except Exception:
298
+ pass
299
 
300
+ # Navigation button
301
+ if st.button("Back"):
302
+ st.switch_page("pages/home.py")
303
 
304
+ # Main logic
305
+ if not st.session_state.analysis_completed:
306
+ run_analysis()
307
+ else:
308
+ st.info("Analysis has already been completed.")
309
 
310
+ # View Results button (only displayed after analysis is completed)
311
+ if st.session_state.analysis_completed and st.button("View Results", icon="📃"):
312
+ st.switch_page("pages/output.py")
313
+ st.session_state.analysis_completed = False