Ronio Jerico Roque commited on
Commit
daa41ad
·
1 Parent(s): aa8f542

Implement thread-safe handling for uploading client and SEM/PPC data with progress updates

Browse files
Files changed (3) hide show
  1. classes/client_summary.py +73 -33
  2. classes/sem_ppc.py +81 -136
  3. pages/home.py +0 -14
classes/client_summary.py CHANGED
@@ -1,10 +1,35 @@
1
  import streamlit as st
 
2
  from dotenv import load_dotenv
3
  from helper.telemetry import collect_telemetry
4
  from helper.upload_File import uploadFile
5
  from helper.button_behaviour import hide_button
6
- from helper.initialize_analyze_session import initialize_analyze_session
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  class CientSummary:
10
  def __init__(self):
@@ -23,43 +48,58 @@ class CientSummary:
23
  if 'target_market' not in st.session_state:
24
  st.session_state['target_market'] = ''
25
 
26
- def process (self):
27
- with st.spinner('Uploading Client Details...', show_time=True):
28
- st.write('')
29
- client_summary = ""
30
- client_name = ""
31
- client_website = ""
32
- #
33
- client_summary = f"Client Summary: {self.client_summary}\n"
34
- client_name = f"{self.name}\n"
35
- client_website = f"{self.website}\n"
36
 
37
- debug_client_summary = {'data_field' : 'Client Summary', 'result': client_summary}
38
- debug_client_name = {'data_field' : 'Client Name', 'result': client_name}
39
- debug_client_website = {'data_field' : 'Client Website', 'result': client_website}
40
 
41
- if self.client_summary:
42
- st.session_state['client_summary'] = 'uploaded'
43
- st.session_state['target_market'] = 'uploaded'
44
- collect_telemetry(debug_client_summary)
45
- if self.name:
46
- st.session_state['client_name'] = 'uploaded'
47
- collect_telemetry(debug_client_website)
48
- if self.website:
49
- st.session_state['client_website'] = 'uploaded'
50
- collect_telemetry(debug_client_name)
51
-
52
- def row1(self):
53
- self.client_summary = st.text_area("Client Summary:", help="Name of business, nature of business, location, products/services")
54
- session = st.session_state.analyze
55
- self.name = st.text_input("Client Name:")
56
- self.website = st.text_input("Client Website:")
57
 
58
- if (self.client_summary or self.name or self.website) and session == 'clicked':
59
- self.process()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
 
 
61
 
62
  if __name__ == "__main__":
63
  st.set_page_config(layout="wide")
64
 
65
- upload = uploadFile()
 
1
  import streamlit as st
2
+ import threading
3
  from dotenv import load_dotenv
4
  from helper.telemetry import collect_telemetry
5
  from helper.upload_File import uploadFile
6
  from helper.button_behaviour import hide_button
 
7
 
8
+ class ThreadSafeHandler:
9
+ def __init__(self, placeholder):
10
+ self.placeholder = placeholder
11
+ self.lock = threading.Lock()
12
+
13
+ def update_info(self, message):
14
+ with self.lock:
15
+ try:
16
+ self.placeholder.info(message)
17
+ except Exception:
18
+ pass
19
+
20
+ def update_success(self, message):
21
+ with self.lock:
22
+ try:
23
+ self.placeholder.success(message)
24
+ except Exception:
25
+ pass
26
+
27
+ def update_error(self, message):
28
+ with self.lock:
29
+ try:
30
+ self.placeholder.error(message)
31
+ except Exception:
32
+ pass
33
 
34
  class CientSummary:
35
  def __init__(self):
 
48
  if 'target_market' not in st.session_state:
49
  st.session_state['target_market'] = ''
50
 
51
+ def process(self):
52
+ session = st.session_state.analyze
53
+ if (self.client_summary or self.name or self.website) and session == 'clicked':
54
+ try:
55
+ # Prepare client data
56
+ client_data = {
57
+ 'client_summary': self.client_summary,
58
+ 'client_name': self.name,
59
+ 'client_website': self.website
60
+ }
61
 
62
+ # Placeholder to display feedback
63
+ handler = ThreadSafeHandler(st.empty())
 
64
 
65
+ def upload_client_data(field_key, field_value):
66
+ try:
67
+ handler.update_info(f"Uploading {field_key.replace('_', ' ').title()}...")
68
+ # Simulate the processing logic here
69
+ st.session_state[field_key] = 'uploaded' # Mock upload success
70
+ collect_telemetry({'data_field': field_key.replace('_', ' ').title(), 'result': field_value})
71
+ handler.update_success(f"{field_key.replace('_', ' ').title()} uploaded.")
72
+ except Exception as e:
73
+ handler.update_error(f"Error uploading {field_key.replace('_', ' ').title()}: {e}")
 
 
 
 
 
 
 
74
 
75
+ # Start threads for each client field
76
+ threads = []
77
+ for field_key, field_value in client_data.items():
78
+ thread = threading.Thread(target=upload_client_data, args=(field_key, field_value))
79
+ thread.start()
80
+ threads.append(thread)
81
+
82
+ # Wait for all threads to complete
83
+ for t in threads:
84
+ t.join()
85
+
86
+ # Update session after processing
87
+ st.session_state['analyzing'] = False
88
+ st.success("🎉 Client Details Uploaded Successfully!")
89
+ except AttributeError:
90
+ st.info("Please fill out all fields first.")
91
+ hide_button()
92
+
93
+ def row1(self):
94
+ self.client_summary = st.text_area("Client Summary:", help="Name of business, nature of business, location, products/services")
95
+ session = st.session_state.analyze
96
+ self.name = st.text_input("Client Name:")
97
+ self.website = st.text_input("Client Website:")
98
 
99
+ if (self.client_summary or self.name or self.website) and session == 'clicked':
100
+ self.process() # Call process method to initiate processing
101
 
102
  if __name__ == "__main__":
103
  st.set_page_config(layout="wide")
104
 
105
+ upload = uploadFile() # Assuming this is another helper class handling file uploads
classes/sem_ppc.py CHANGED
@@ -1,161 +1,106 @@
1
  import streamlit as st
 
2
  from dotenv import load_dotenv
3
  from helper.telemetry import collect_telemetry
4
  from helper.upload_File import uploadFile
5
  from helper.button_behaviour import hide_button
6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
  class Sem_PPC:
9
  def __init__(self, model_url):
10
  self.file_dict = {}
11
  self.model_url = model_url
12
- #self.analyst_name = analyst_name
13
- #self.data_src = data_src
14
- #self.analyst_description = analyst_description
15
  self.initialize()
16
  self.row1()
17
 
18
  def initialize(self):
19
- # FOR ENV
20
  load_dotenv()
21
- '''
22
- # AGENT NAME
23
- st.header(self.analyst_name)
24
-
25
- # EVALUATION FORM LINK
26
- url = os.getenv('Link')
27
- st.write('Evaluation Form: [Link](%s)' % url)
28
-
29
- # RETURN BUTTON
30
- try:
31
- if st.button("Return", type='primary'):
32
- st.switch_page("./pages/home.py")
33
- except Exception:
34
- pass
35
- '''
36
- if 'account_set_up' not in st.session_state:
37
- st.session_state['account_set_up'] = ''
38
- if 'search_ads' not in st.session_state:
39
- st.session_state['search_ads'] = ''
40
- if 'display_ads' not in st.session_state:
41
- st.session_state['display_ads'] = ''
42
- if 'mobile_ads' not in st.session_state:
43
- st.session_state['mobile_ads'] = ''
44
- if 'video_ads' not in st.session_state:
45
- st.session_state['video_ads'] = ''
46
- if 'shopping_ads' not in st.session_state:
47
- st.session_state['shopping_ads'] = ''
48
 
49
  def process(self):
50
  session = st.session_state.analyze
51
- if (self.account_set_up or self.search_ads or self.display_ads or self.mobile_ads or self.video_ads or self.shopping_ads) and session == 'clicked':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  try:
53
- account_set_up = ""
54
- search_ads = ""
55
- display_ads = ""
56
- mobile_ads = ""
57
- video_ads = ""
58
- shopping_ads = ""
59
- with st.spinner('Uploading SEM/PPC...', show_time=True):
60
- st.write('')
61
- # INITIALIZING SESSIONS
62
- #combined_text += f"Client Summary: {st.session_state.nature}\n"
63
- try:
64
- account_set_up += f"\nAccount Set Up: {self.account_set_up}"
65
- except KeyError:
66
- pass
67
- try:
68
- search_ads += f"\nSearch Ads: {self.search_ads}"
69
- except KeyError:
70
- pass
71
- try:
72
- display_ads += f"\nDisplay Ads: {self.display_ads}"
73
- except KeyError:
74
- pass
75
- try:
76
- mobile_ads += f"\nMobile Ads: {self.mobile_ads}"
77
- except KeyError:
78
- pass
79
- try:
80
- video_ads += f"\nVideo Ads: {self.video_ads}"
81
- except KeyError:
82
- pass
83
- try:
84
- shopping_ads += f"\nShopping Ads: {self.shopping_ads}"
85
- except KeyError:
86
- pass
87
-
88
- # OUTPUT FOR SEO ANALYST
89
- #payload_txt = {"question": combined_text}
90
- #result = self.request_model(payload_txt)
91
-
92
- #end_time = time.time()
93
- #time_lapsed = end_time - start_time
94
-
95
- debug_info_account_set_up = {'data_field' : 'Account Set Up - Google Ads', 'result': account_set_up}
96
- debug_info_search_ads = {'data_field' : 'Search Ads - Google Ads/SEMRush', 'result': search_ads}
97
- debug_info_display_ads = {'data_field' : 'Display Ads - Google Ads/SEMRush', 'result': display_ads}
98
- debug_info_mobile_ads = {'data_field' : 'Mobile Ads - Google Ads', 'result': mobile_ads}
99
- debug_info_video_ads = {'data_field' : 'Video Ads - Google Ads', 'result': video_ads}
100
- debug_info_shopping_ads = {'data_field' : 'Shopping Ads - Google Ads/SEMRush', 'result': shopping_ads}
101
-
102
- '''
103
- debug_info = {
104
- #'analyst': self.analyst_name,
105
- 'url_uuid': self.model_url.split("-")[-1],
106
- 'time_lapsed': time_lapsed,
107
- 'payload': payload_txt,
108
- 'result': result,
109
- }
110
- '''
111
- if self.account_set_up:
112
- st.session_state['account_set_up'] = 'uploaded'
113
- collect_telemetry(debug_info_account_set_up)
114
- if self.search_ads:
115
- st.session_state['search_ads'] = 'uploaded'
116
- collect_telemetry(debug_info_search_ads)
117
- if self.display_ads:
118
- st.session_state['display_ads'] = 'uploaded'
119
- collect_telemetry(debug_info_display_ads)
120
- if self.mobile_ads:
121
- st.session_state['mobile_ads'] = 'uploaded'
122
- collect_telemetry(debug_info_mobile_ads)
123
- if self.video_ads:
124
- st.session_state['video_ads'] = 'uploaded'
125
- collect_telemetry(debug_info_video_ads)
126
- if self.shopping_ads:
127
- st.session_state['shopping_ads'] = 'uploaded'
128
- collect_telemetry(debug_info_shopping_ads)
129
-
130
-
131
-
132
- #with st.expander("Debug information", icon="⚙"):
133
- # st.write(debug_info)
134
-
135
- st.session_state['analyzing'] = False
136
- except AttributeError:
137
- st.info("Please upload CSV or PDF files first.")
138
- hide_button()
139
 
140
  def row1(self):
141
- self.account_set_up = st.text_input("Account Set Up - Google Ads:", placeholder='Enter Account Set Up')
142
- self.search_ads = st.checkbox("Search Ads - Google Ads/SEMRush")
143
- self.display_ads = st.checkbox("Display Ads - Google Ads/SEMRush")
144
- self.mobile_ads = st.checkbox("Mobile Ads - Google Ads")
145
- self.video_ads = st.checkbox("Video Ads - Google Ads")
146
- self.shopping_ads = st.checkbox("Shopping Ads - Google Ads/SEMRush")
147
-
148
- '''
149
- st.write("") # FOR THE HIDE BUTTON
150
- st.write("") # FOR THE HIDE BUTTON
151
- st.write("AI Analyst Output: ")
152
- st.session_state['analyzing'] = False
153
- st.write("") # FOR THE HIDE BUTTON'
154
- '''
155
- #analyze_button = st.button("Analyze", disabled=initialize_analyze_session())
156
- self.process()
157
-
158
  if __name__ == "__main__":
159
  st.set_page_config(layout="wide")
160
 
161
- upload = uploadFile()
 
1
  import streamlit as st
2
+ import threading
3
  from dotenv import load_dotenv
4
  from helper.telemetry import collect_telemetry
5
  from helper.upload_File import uploadFile
6
  from helper.button_behaviour import hide_button
7
 
8
+ class ThreadSafeHandler:
9
+ def __init__(self, placeholder):
10
+ self.placeholder = placeholder
11
+ self.lock = threading.Lock()
12
+
13
+ def update_info(self, message):
14
+ with self.lock:
15
+ try:
16
+ self.placeholder.info(message)
17
+ except Exception:
18
+ pass
19
+
20
+ def update_success(self, message):
21
+ with self.lock:
22
+ try:
23
+ self.placeholder.success(message)
24
+ except Exception:
25
+ pass
26
+
27
+ def update_error(self, message):
28
+ with self.lock:
29
+ try:
30
+ self.placeholder.error(message)
31
+ except Exception:
32
+ pass
33
 
34
  class Sem_PPC:
35
  def __init__(self, model_url):
36
  self.file_dict = {}
37
  self.model_url = model_url
 
 
 
38
  self.initialize()
39
  self.row1()
40
 
41
  def initialize(self):
 
42
  load_dotenv()
43
+ # Initialize session state for various ads
44
+ for ad_type in ['account_set_up', 'search_ads', 'display_ads', 'mobile_ads', 'video_ads', 'shopping_ads']:
45
+ if ad_type not in st.session_state:
46
+ st.session_state[ad_type] = ''
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
  def process(self):
49
  session = st.session_state.analyze
50
+ if any([self.account_set_up, self.search_ads, self.display_ads, self.mobile_ads, self.video_ads, self.shopping_ads]) and session == 'clicked':
51
+ try:
52
+ # Prepare ad data
53
+ ad_data = {
54
+ 'account_set_up': self.account_set_up,
55
+ 'search_ads': self.search_ads,
56
+ 'display_ads': self.display_ads,
57
+ 'mobile_ads': self.mobile_ads,
58
+ 'video_ads': self.video_ads,
59
+ 'shopping_ads': self.shopping_ads
60
+ }
61
+
62
+ # Placeholder to display feedback
63
+ handler = ThreadSafeHandler(st.empty())
64
+
65
+ def upload_ads_data(ad_key, ad_value):
66
  try:
67
+ handler.update_info(f"Uploading {ad_key.replace('_', ' ').title()}...")
68
+ # Simulate the processing logic here
69
+ st.session_state[ad_key] = 'uploaded' # Mock upload success
70
+ collect_telemetry({'data_field': ad_key.replace('_', ' ').title(), 'result': ad_value})
71
+ handler.update_success(f"{ad_key.replace('_', ' ').title()} completed.")
72
+ except Exception as e:
73
+ handler.update_error(f"Error uploading {ad_key.replace('_', ' ').title()}: {e}")
74
+
75
+ # Start threads for each ad type
76
+ threads = []
77
+ for ad_key, ad_value in ad_data.items():
78
+ thread = threading.Thread(target=upload_ads_data, args=(ad_key, ad_value))
79
+ thread.start()
80
+ threads.append(thread)
81
+
82
+ # Wait for all threads to complete
83
+ for t in threads:
84
+ t.join()
85
+
86
+ # Update session after processing
87
+ st.session_state['analyzing'] = False
88
+ st.success("🎉 SEM/PPC Data Uploaded Successfully!")
89
+ except AttributeError:
90
+ st.info("Please upload CSV or PDF files first.")
91
+ hide_button()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  def row1(self):
94
+ self.account_set_up = st.text_input("Account Set Up - Google Ads:", placeholder='Enter Account Set Up')
95
+ self.search_ads = st.checkbox("Search Ads - Google Ads/SEMRush")
96
+ self.display_ads = st.checkbox("Display Ads - Google Ads/SEMRush")
97
+ self.mobile_ads = st.checkbox("Mobile Ads - Google Ads")
98
+ self.video_ads = st.checkbox("Video Ads - Google Ads")
99
+ self.shopping_ads = st.checkbox("Shopping Ads - Google Ads/SEMRush")
100
+
101
+ self.process() # Call process method to initiate processing
102
+
 
 
 
 
 
 
 
 
103
  if __name__ == "__main__":
104
  st.set_page_config(layout="wide")
105
 
106
+ upload = uploadFile() # Assuming this is another helper class handling file uploads
pages/home.py CHANGED
@@ -140,20 +140,6 @@ class DigitalFootprintDashboard:
140
  clear_collection("df_data")
141
  clear_collection("df_response")
142
 
143
- async def run_analysis(self):
144
- result = await asyncio.gather(
145
- self.gtmetrix.process(),
146
- self.backlinks.process(),
147
- self.keywords.process(),
148
- self.facebook.process(),
149
- self.instagram.process(),
150
- self.twitter.process(),
151
- self.youtube.process(),
152
- self.linkedin.process(),
153
- self.tiktok.process(),
154
- )
155
- st.session_state.analyze = False
156
-
157
  async def main(self):
158
  """Main method to run the dashboard"""
159
  await self.create_row1()
 
140
  clear_collection("df_data")
141
  clear_collection("df_response")
142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  async def main(self):
144
  """Main method to run the dashboard"""
145
  await self.create_row1()