Hasitha16 commited on
Commit
1c216da
Β·
verified Β·
1 Parent(s): 6271269

Update frontend.py

Browse files
Files changed (1) hide show
  1. frontend.py +96 -149
frontend.py CHANGED
@@ -4,92 +4,60 @@ import pandas as pd
4
  from gtts import gTTS
5
  import base64
6
  from io import BytesIO
7
- from PIL import Image
8
  import os
9
  import plotly.express as px
10
 
11
  st.set_page_config(page_title="NeuroPulse AI", page_icon="🧠", layout="wide")
12
 
13
- # Logo
14
- logo_path = "logo.png"
15
- if os.path.exists(logo_path):
16
- st.image(logo_path, width=180)
17
-
18
- # Session State
19
- if "review" not in st.session_state:
20
- st.session_state.review = ""
21
- if "dark_mode" not in st.session_state:
22
- st.session_state.dark_mode = False
23
- if "intelligence_mode" not in st.session_state:
24
- st.session_state.intelligence_mode = True
25
- if "trigger_example_analysis" not in st.session_state:
26
- st.session_state.trigger_example_analysis = False
27
-
28
- # Dark Mode Style
29
  if st.session_state.dark_mode:
30
  st.markdown("""
31
- <style>
32
- html, body, [class*="st-"] {
33
- background-color: #121212;
34
- color: #f5f5f5;
35
- }
36
- .stTextInput > div > div > input,
37
- .stTextArea > div > textarea,
38
- .stSelectbox div div,
39
- .stDownloadButton > button,
40
- .stButton > button {
41
- background-color: #1e1e1e;
42
- color: white;
43
- }
44
- </style>
45
  """, unsafe_allow_html=True)
46
 
47
- # Sidebar Controls
48
  with st.sidebar:
49
  st.header("βš™οΈ Global Settings")
 
 
50
 
51
- # Dark Mode Toggle with refresh
52
- if st.toggle("πŸŒ™ Dark Mode", value=st.session_state.dark_mode):
53
- if not st.session_state.dark_mode:
54
- st.session_state.dark_mode = True
55
- st.rerun()
56
- else:
57
- if st.session_state.dark_mode:
58
- st.session_state.dark_mode = False
59
- st.rerun()
60
-
61
- if st.toggle("🧠 Intelligence Mode", value=st.session_state.intelligence_mode):
62
- st.session_state.intelligence_mode = True
63
- else:
64
- st.session_state.intelligence_mode = False
65
-
66
- DEFAULT_DEMO_TOKEN = "my-secret-key"
67
- api_token = st.text_input("πŸ” API Token", value=DEFAULT_DEMO_TOKEN, type="password")
68
- if not api_token or api_token.strip() == "my-secret-key":
69
- st.warning("πŸ§ͺ Running in demo mode β€” for full access, enter a valid API key.")
70
-
71
  backend_url = st.text_input("🌐 Backend URL", value="http://localhost:8000")
72
 
73
  sentiment_model = st.selectbox("πŸ“Š Sentiment Model", [
74
  "distilbert-base-uncased-finetuned-sst-2-english",
75
  "nlptown/bert-base-multilingual-uncased-sentiment"
76
  ])
77
-
78
- industry = st.selectbox("🏭 Industry", [
79
- "Auto-detect", "Generic", "E-commerce", "Healthcare", "Education", "Travel", "Banking", "Insurance",
80
- "Gaming", "Food Delivery", "Real Estate", "Fitness", "Entertainment"
81
- ])
82
-
83
- product_category = st.selectbox("🧩 Product Category", [
84
- "Auto-detect", "General", "Mobile Devices", "Laptops", "Healthcare Devices", "Banking App",
85
- "Travel Service", "Educational Tool", "Insurance Portal", "Streaming App", "Wearables",
86
- "Home Appliances", "Food Apps"
87
- ])
88
-
89
- use_aspects = st.checkbox("πŸ”¬ Enable Aspect Analysis")
90
- use_smart_summary = st.checkbox("🧠 Smart Summary (Single)")
91
- use_smart_summary_bulk = st.checkbox("🧠 Smart Summary for Bulk")
92
- use_explain_bulk = st.checkbox("🧠 Generate Explanations (Bulk)")
93
  verbosity = st.radio("πŸ—£οΈ Response Style", ["Brief", "Detailed"])
94
  voice_lang = st.selectbox("πŸ”ˆ Voice Language", ["en", "fr", "es", "de", "hi", "zh"])
95
 
@@ -103,20 +71,22 @@ def speak(text, lang='en'):
103
  mp3.seek(0)
104
  return mp3
105
 
 
106
  tab1, tab2 = st.tabs(["🧠 Single Review", "πŸ“š Bulk CSV"])
107
 
108
- # --- SINGLE REVIEW TAB ---
109
  with tab1:
110
  st.title("🧠 NeuroPulse AI – Multimodal Review Analyzer")
111
  st.markdown("<div style='font-size:16px;color:#888;'>Minimum 20–50 words recommended.</div>", unsafe_allow_html=True)
112
 
113
  review = st.text_area("πŸ“ Enter Review", value=st.session_state.review, height=180)
 
114
 
115
  col1, col2, col3 = st.columns(3)
116
  with col1:
117
- analyze = st.button("πŸ” Analyze", use_container_width=True, disabled=not api_token)
118
  with col2:
119
- if st.button("🎲 Example", use_container_width=True):
120
  st.session_state.review = (
121
  "I love this phone! Super fast performance, great battery, and smooth UI. "
122
  "Camera is awesome too, though the price is a bit high. Overall, very happy."
@@ -124,90 +94,69 @@ with tab1:
124
  st.session_state.trigger_example_analysis = True
125
  st.rerun()
126
  with col3:
127
- if st.button("🧹 Clear", use_container_width=True):
128
- st.session_state.review = ""
 
129
  st.rerun()
130
 
131
- if st.session_state.trigger_example_analysis and st.session_state.review:
132
- analyze = True
133
  st.session_state.trigger_example_analysis = False
134
-
135
- if analyze and review:
136
- if len(review.split()) < 20:
137
- st.warning("⚠️ Please enter at least 20 words.")
138
- else:
139
- with st.spinner("Analyzing..."):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  try:
141
- payload = {
142
- "text": review,
143
- "model": sentiment_model,
144
- "industry": industry,
145
- "aspects": use_aspects,
146
- "follow_up": None,
147
- "product_category": product_category,
148
- "verbosity": verbosity,
149
- "intelligence": st.session_state.intelligence_mode
150
  }
151
- headers = {"x-api-key": st.session_state.get("api_token", api_token)}
152
- params = {"smart": "1"} if use_smart_summary else {}
153
- res = requests.post(f"{backend_url}/analyze/", json=payload, headers=headers, params=params)
154
-
155
  if res.status_code == 200:
156
- data = res.json()
157
- st.success("βœ… Analysis Complete")
158
- st.subheader("πŸ“Œ Summary")
159
- st.info(data["summary"])
160
- st.caption(f"🧠 Summary Type: {'Smart' if use_smart_summary else 'Standard'} | {verbosity} Response")
161
- st.markdown(f"**Context:** `{data['industry']}` | `{data['product_category']}` | `Web`")
162
-
163
- st.subheader("πŸ”Š Audio")
164
- audio = speak(data["summary"], lang=voice_lang)
165
- st.download_button("⬇️ Download Summary Audio", audio.read(), "summary.mp3", mime="audio/mp3")
166
-
167
- st.metric("πŸ“Š Sentiment", data["sentiment"]["label"], delta=f"{data['sentiment']['score']:.2%}")
168
- st.info(f"πŸ’’ Emotion: {data['emotion']}")
169
-
170
- # Follow-up Section
171
- st.markdown("### πŸ” Got questions?")
172
- st.info("πŸ’¬ Ask a follow-up question about this review.")
173
- sample_questions = [
174
- "What did the user like most?",
175
- "Any complaints mentioned?",
176
- "Is it positive overall?",
177
- "What are the improvement areas?"
178
- ]
179
- selected_q = st.selectbox("πŸ’‘ Sample Questions", ["Type your own..."] + sample_questions)
180
-
181
- if selected_q != "Type your own...":
182
- custom_q = selected_q
183
- else:
184
- custom_q = st.text_input("πŸ” Ask a follow-up")
185
-
186
- if custom_q:
187
- with st.spinner("Thinking..."):
188
- try:
189
- follow_payload = {
190
- "text": review,
191
- "question": custom_q,
192
- "verbosity": verbosity
193
- }
194
- res = requests.post(f"{backend_url}/followup/", json=follow_payload, headers=headers)
195
- if res.status_code == 200:
196
- follow = res.json().get("answer")
197
- st.subheader("πŸ” Follow-Up Answer")
198
- st.warning(follow)
199
- else:
200
- st.error(f"❌ Follow-up failed: {res.json().get('detail', 'Unknown error')}")
201
- except Exception as e:
202
- st.error(f"⚠️ Follow-up error: {e}")
203
  else:
204
- st.error(f"❌ API Error {res.status_code}: {res.json().get('detail', 'Unknown error')}")
205
  except Exception as e:
206
- st.error(f"🚫 Exception occurred: {e}")
 
 
 
 
207
 
208
- # -------------------
209
- # BULK CSV TAB
210
- # -------------------
211
  with tab2:
212
  st.title("πŸ“š Bulk CSV Upload")
213
  st.markdown("""
@@ -246,16 +195,14 @@ with tab2:
246
  payload = {
247
  "reviews": df["review"].tolist(),
248
  "model": sentiment_model,
249
- "aspects": use_aspects,
250
  "industry": df["industry"].tolist(),
251
  "product_category": df["product_category"].tolist(),
252
  "device": df["device"].tolist(),
253
  "follow_up": df["follow_up"].tolist(),
254
- "explain": use_explain_bulk,
255
  "intelligence": st.session_state.intelligence_mode,
256
  }
257
  res = requests.post(
258
- f"{backend_url}/bulk/?token={st.session_state.get('api_token', api_token)}",
259
  json=payload
260
  )
261
  if res.status_code == 200:
 
4
  from gtts import gTTS
5
  import base64
6
  from io import BytesIO
 
7
  import os
8
  import plotly.express as px
9
 
10
  st.set_page_config(page_title="NeuroPulse AI", page_icon="🧠", layout="wide")
11
 
12
+ if os.path.exists("logo.png"):
13
+ st.image("logo.png", width=180)
14
+
15
+ # Session variables
16
+ for key, default in {
17
+ "review": "",
18
+ "dark_mode": False,
19
+ "intelligence_mode": True,
20
+ "trigger_example_analysis": False,
21
+ "last_response": None,
22
+ "followup_answer": None,
23
+ }.items():
24
+ if key not in st.session_state:
25
+ st.session_state[key] = default
26
+
27
+ # Dark mode CSS
28
  if st.session_state.dark_mode:
29
  st.markdown("""
30
+ <style>
31
+ html, body, [class*="st-"] {
32
+ background-color: #121212;
33
+ color: #f5f5f5;
34
+ }
35
+ .stTextInput > div > div > input,
36
+ .stTextArea > div > textarea,
37
+ .stSelectbox div div,
38
+ .stDownloadButton > button,
39
+ .stButton > button {
40
+ background-color: #1e1e1e;
41
+ color: white;
42
+ }
43
+ </style>
44
  """, unsafe_allow_html=True)
45
 
46
+ # Sidebar controls
47
  with st.sidebar:
48
  st.header("βš™οΈ Global Settings")
49
+ st.session_state.dark_mode = st.toggle("πŸŒ™ Dark Mode", value=st.session_state.dark_mode)
50
+ st.session_state.intelligence_mode = st.toggle("🧠 Intelligence Mode", value=st.session_state.intelligence_mode)
51
 
52
+ api_token = st.text_input("πŸ” API Token", value="my-secret-key", type="password")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  backend_url = st.text_input("🌐 Backend URL", value="http://localhost:8000")
54
 
55
  sentiment_model = st.selectbox("πŸ“Š Sentiment Model", [
56
  "distilbert-base-uncased-finetuned-sst-2-english",
57
  "nlptown/bert-base-multilingual-uncased-sentiment"
58
  ])
59
+ industry = st.selectbox("🏭 Industry", ["Auto-detect", "Generic", "E-commerce", "Healthcare", "Education"])
60
+ product_category = st.selectbox("🧩 Product Category", ["Auto-detect", "General", "Mobile Devices", "Laptops"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  verbosity = st.radio("πŸ—£οΈ Response Style", ["Brief", "Detailed"])
62
  voice_lang = st.selectbox("πŸ”ˆ Voice Language", ["en", "fr", "es", "de", "hi", "zh"])
63
 
 
71
  mp3.seek(0)
72
  return mp3
73
 
74
+ # Tabs
75
  tab1, tab2 = st.tabs(["🧠 Single Review", "πŸ“š Bulk CSV"])
76
 
77
+ # ---- SINGLE REVIEW ----
78
  with tab1:
79
  st.title("🧠 NeuroPulse AI – Multimodal Review Analyzer")
80
  st.markdown("<div style='font-size:16px;color:#888;'>Minimum 20–50 words recommended.</div>", unsafe_allow_html=True)
81
 
82
  review = st.text_area("πŸ“ Enter Review", value=st.session_state.review, height=180)
83
+ st.session_state.review = review
84
 
85
  col1, col2, col3 = st.columns(3)
86
  with col1:
87
+ analyze = st.button("πŸ” Analyze")
88
  with col2:
89
+ if st.button("🎲 Example"):
90
  st.session_state.review = (
91
  "I love this phone! Super fast performance, great battery, and smooth UI. "
92
  "Camera is awesome too, though the price is a bit high. Overall, very happy."
 
94
  st.session_state.trigger_example_analysis = True
95
  st.rerun()
96
  with col3:
97
+ if st.button("🧹 Clear"):
98
+ for key in ["review", "last_response", "followup_answer"]:
99
+ st.session_state[key] = ""
100
  st.rerun()
101
 
102
+ if (analyze or st.session_state.trigger_example_analysis) and st.session_state.review:
 
103
  st.session_state.trigger_example_analysis = False
104
+ st.session_state.followup_answer = None
105
+ with st.spinner("Analyzing..."):
106
+ try:
107
+ payload = {
108
+ "text": st.session_state.review,
109
+ "model": sentiment_model,
110
+ "industry": industry,
111
+ "product_category": product_category,
112
+ "verbosity": verbosity,
113
+ "intelligence": st.session_state.intelligence_mode
114
+ }
115
+ headers = {"x-api-key": api_token}
116
+ res = requests.post(f"{backend_url}/analyze/", json=payload, headers=headers)
117
+ if res.status_code == 200:
118
+ st.session_state.last_response = res.json()
119
+ else:
120
+ st.error(f"API error: {res.status_code} - {res.json().get('detail')}")
121
+ except Exception as e:
122
+ st.error(f"🚫 Exception: {e}")
123
+
124
+ data = st.session_state.last_response
125
+ if data:
126
+ st.subheader("πŸ“Œ Summary")
127
+ st.info(data["summary"])
128
+ st.metric("πŸ“Š Sentiment", data["sentiment"]["label"], delta=f"{data['sentiment']['score']:.2%}")
129
+ st.info(f"πŸ’’ Emotion: {data['emotion']}")
130
+ st.subheader("πŸ”Š Audio")
131
+ audio = speak(data["summary"], lang=voice_lang)
132
+ st.download_button("⬇️ Download Summary Audio", audio.read(), "summary.mp3")
133
+
134
+ st.markdown("### πŸ” Got questions?")
135
+ sample_questions = ["What did the user like most?", "Any complaints mentioned?", "Is it positive overall?"]
136
+ selected_q = st.selectbox("πŸ’‘ Sample Questions", ["Type your own..."] + sample_questions)
137
+ custom_q = selected_q if selected_q != "Type your own..." else st.text_input("πŸ” Ask a follow-up")
138
+
139
+ if custom_q:
140
+ with st.spinner("Thinking..."):
141
  try:
142
+ follow_payload = {
143
+ "text": st.session_state.review,
144
+ "question": custom_q,
145
+ "verbosity": verbosity
 
 
 
 
 
146
  }
147
+ res = requests.post(f"{backend_url}/followup/", json=follow_payload, headers=headers)
 
 
 
148
  if res.status_code == 200:
149
+ st.session_state.followup_answer = res.json().get("answer")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  else:
151
+ st.error(f"❌ Follow-up failed: {res.json().get('detail')}")
152
  except Exception as e:
153
+ st.error(f"⚠️ Follow-up error: {e}")
154
+
155
+ if st.session_state.followup_answer:
156
+ st.subheader("πŸ” Follow-Up Answer")
157
+ st.success(st.session_state.followup_answer)
158
 
159
+ # ---- BULK CSV ----
 
 
160
  with tab2:
161
  st.title("πŸ“š Bulk CSV Upload")
162
  st.markdown("""
 
195
  payload = {
196
  "reviews": df["review"].tolist(),
197
  "model": sentiment_model,
 
198
  "industry": df["industry"].tolist(),
199
  "product_category": df["product_category"].tolist(),
200
  "device": df["device"].tolist(),
201
  "follow_up": df["follow_up"].tolist(),
 
202
  "intelligence": st.session_state.intelligence_mode,
203
  }
204
  res = requests.post(
205
+ f"{backend_url}/bulk/?token={api_token}",
206
  json=payload
207
  )
208
  if res.status_code == 200: