Hasitha16 commited on
Commit
939ac52
·
verified ·
1 Parent(s): 494f3c9

Update frontend.py

Browse files
Files changed (1) hide show
  1. frontend.py +30 -181
frontend.py CHANGED
@@ -1,196 +1,45 @@
1
  import streamlit as st
2
  import requests
3
- 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_path = os.path.join("app", "static", "logo.png")
14
- if os.path.exists(logo_path):
15
- st.image(logo_path, width=160)
16
-
17
- # Session state defaults
18
  if "review" not in st.session_state:
19
  st.session_state.review = ""
20
  if "dark_mode" not in st.session_state:
21
  st.session_state.dark_mode = False
22
- if "intelligence_mode" not in st.session_state:
23
- st.session_state.intelligence_mode = True
24
 
25
- # Shared Sidebar Controls
 
 
26
  with st.sidebar:
27
- st.header("⚙️ Global Settings")
28
  st.session_state.dark_mode = st.toggle("🌙 Dark Mode", value=st.session_state.dark_mode)
29
- st.session_state.intelligence_mode = st.toggle("🧠 Intelligence Mode", value=st.session_state.intelligence_mode)
30
-
31
- api_token = st.text_input("🔐 API Token", type="password")
32
- backend_url = st.text_input("🖥️ Backend URL", value="http://0.0.0.0:8000")
33
-
34
- sentiment_model = st.selectbox("📊 Sentiment Model", [
35
- "distilbert-base-uncased-finetuned-sst-2-english",
36
- "nlptown/bert-base-multilingual-uncased-sentiment"
37
- ])
38
-
39
- industry = st.selectbox("🏭 Industry Context", [
40
- "Auto-detect", "Generic", "E-commerce", "Healthcare", "Education", "Travel", "Banking", "Insurance", "Gaming", "Food Delivery", "Real Estate", "Fitness", "Entertainment"
41
- ])
42
-
43
- product_category = st.selectbox("🧩 Product Category", [
44
- "Auto-detect", "General", "Mobile Devices", "Laptops", "Healthcare Devices", "Banking App", "Travel Service", "Educational Tool", "Insurance Portal", "Streaming App", "Wearables", "Home Appliances", "Food Apps"
45
- ])
46
-
47
- device_type = st.selectbox("💻 Device Type", [
48
- "Auto-detect", "Web", "Android", "iOS", "Desktop", "Smartwatch", "Kiosk"
49
- ])
50
-
51
- use_aspects = st.checkbox("🔬 Enable Aspect Analysis")
52
- use_smart_summary = st.checkbox("🧠 Use Smart Summary (Single)")
53
- use_smart_summary_bulk = st.checkbox("🧠 Smart Summary for Bulk")
54
- verbosity = st.radio("🗣️ Response Style", ["Brief", "Detailed"])
55
- follow_up = st.text_input("🔁 Follow-up Question")
56
- voice_lang = st.selectbox("🔈 Voice Language", ["en", "fr", "es", "de", "hi", "zh"])
57
-
58
- # Text-to-Speech Helper
59
- def speak(text, lang='en'):
60
- tts = gTTS(text, lang=lang)
61
- mp3 = BytesIO()
62
- tts.write_to_fp(mp3)
63
- b64 = base64.b64encode(mp3.getvalue()).decode()
64
- st.markdown(f'<audio controls><source src="data:audio/mp3;base64,{b64}" type="audio/mp3"></audio>', unsafe_allow_html=True)
65
- mp3.seek(0)
66
- return mp3
67
-
68
- # Tabs for modes
69
- tab1, tab2 = st.tabs(["🧠 Single Review", "📚 Bulk CSV"])
70
-
71
- # --- SINGLE REVIEW MODE ---
72
- with tab1:
73
- st.title("🧠 NeuroPulse AI – Multimodal Review Analyzer")
74
- st.markdown("""
75
- <div style='font-size:16px;color:#555;'>Minimum 50–100 words recommended for optimal insights.</div>
76
- """, unsafe_allow_html=True)
77
-
78
- review = st.text_area("📝 Enter a Review", value=st.session_state.review, height=180)
79
-
80
- col1, col2, col3 = st.columns(3)
81
- with col1:
82
- analyze = st.button("🔍 Analyze", use_container_width=True, disabled=not api_token)
83
- with col2:
84
- if st.button("🎲 Example", use_container_width=True):
85
- st.session_state.review = "App was smooth, but the transaction failed twice on Android during checkout."
86
- st.rerun()
87
- with col3:
88
- if st.button("🧹 Clear", use_container_width=True):
89
- st.session_state.review = ""
90
- st.rerun()
91
-
92
- if analyze and review:
93
- if len(review.split()) < 50:
94
- st.error("⚠️ Please enter at least 50 words for meaningful analysis.")
95
- else:
96
- with st.spinner("Analyzing..."):
97
- try:
98
- payload = {
99
- "text": review,
100
- "model": sentiment_model,
101
- "industry": industry,
102
- "aspects": use_aspects,
103
- "follow_up": follow_up,
104
- "product_category": product_category,
105
- "device": device_type,
106
- "verbosity": verbosity,
107
- "intelligence": st.session_state.intelligence_mode
108
- }
109
- headers = {"Authorization": f"Bearer {api_token}"}
110
- params = {"smart": "1"} if use_smart_summary else {}
111
- res = requests.post(f"{backend_url}/analyze/", json=payload, headers=headers, params=params)
112
- if res.status_code == 200:
113
- data = res.json()
114
- st.success("✅ Analysis Complete")
115
- st.subheader("📌 Summary")
116
- st.info(data["summary"])
117
- st.caption(f"🧠 Summary Type: {'Smart Summary' if use_smart_summary else 'Standard Model'}")
118
- st.markdown(f"**Context:** {industry} | {product_category} | {device_type}")
119
- st.subheader("🔊 Audio")
120
- audio = speak(data["summary"], lang=voice_lang)
121
- st.download_button("⬇️ Download Summary Audio", audio.read(), "summary.mp3", mime="audio/mp3")
122
- st.metric("📊 Sentiment", data["sentiment"]["label"], delta=f"{data['sentiment']['score']:.2%}")
123
- st.info(f"💢 Emotion: {data['emotion']}")
124
- if data.get("aspects"):
125
- st.subheader("🔍 Aspects")
126
- for a in data["aspects"]:
127
- st.write(f"🔹 {a['aspect']}: {a['sentiment']} ({a['score']:.2%})")
128
- if data.get("follow_up"):
129
- st.subheader("🧠 Follow-Up Response")
130
- st.warning(data["follow_up"])
131
- if data.get("explanation"):
132
- st.subheader("🧮 Explain This")
133
- st.markdown(data["explanation"])
134
- else:
135
- st.error(f"❌ API Error: {res.status_code}")
136
- except Exception as e:
137
- st.error(f"🚫 {e}")
138
-
139
- # --- BULK REVIEW MODE ---
140
- with tab2:
141
- st.title("📚 Bulk CSV Upload")
142
- st.markdown("""
143
- <div style='font-size:16px;'>Upload a CSV with the following columns:<br>
144
- <code>review</code> <span style='color:#aaa;'>(required)</span>,
145
- <code>industry</code>, <code>product_category</code>, <code>device</code> <span style='color:#aaa;'>(optional)</span></div>
146
- """, unsafe_allow_html=True)
147
-
148
- with st.expander("📄 Sample CSV"):
149
- with open("sample_reviews.csv", "rb") as f:
150
- st.download_button("⬇️ Download sample CSV", f, file_name="sample_reviews.csv")
151
-
152
- uploaded_file = st.file_uploader("📁 Upload your CSV", type="csv")
153
-
154
- if uploaded_file and api_token:
155
- try:
156
- df = pd.read_csv(uploaded_file)
157
- if "review" not in df.columns:
158
- st.error("CSV must contain a `review` column.")
159
- else:
160
- st.success(f"✅ Loaded {len(df)} reviews")
161
-
162
- for col in ["industry", "product_category", "device"]:
163
- if col not in df.columns:
164
- df[col] = [industry if industry != "Auto-detect" else "Generic"] * len(df)
165
- df[col] = df[col].fillna("").astype(str)
166
-
167
- if st.button("📊 Analyze Bulk Reviews", use_container_width=True):
168
- with st.spinner("Processing CSV..."):
169
- try:
170
- payload = {
171
- "reviews": df["review"].tolist(),
172
- "model": sentiment_model,
173
- "aspects": use_aspects,
174
- "industry": df["industry"].tolist(),
175
- "product_category": df["product_category"].tolist(),
176
- "device": df["device"].tolist(),
177
- "intelligence": st.session_state.intelligence_mode
178
- }
179
- headers = {"Authorization": f"Bearer {api_token}"}
180
- params = {"smart": "1"} if use_smart_summary_bulk else {}
181
-
182
- res = requests.post(f"{backend_url}/bulk/", json=payload, headers=headers, params=params)
183
- if res.status_code == 200:
184
- results = pd.DataFrame(res.json()["results"])
185
- results["summary_type"] = "Smart" if use_smart_summary_bulk else "Standard"
186
- st.dataframe(results)
187
- if "sentiment" in results:
188
- fig = px.pie(results, names="sentiment", title="Sentiment Distribution")
189
- st.plotly_chart(fig)
190
- st.download_button("⬇️ Download Results CSV", results.to_csv(index=False), "bulk_results.csv", mime="text/csv")
191
- else:
192
- st.error(f"❌ Bulk Analysis Failed: {res.status_code}")
193
- except Exception as e:
194
- st.error(f"💥 Error: {e}")
195
- except Exception as e:
196
- st.error(f"❌ File Error: {e}")
 
1
  import streamlit as st
2
  import requests
 
3
  from gtts import gTTS
4
  import base64
5
  from io import BytesIO
 
 
 
6
 
7
  st.set_page_config(page_title="NeuroPulse AI", page_icon="🧠", layout="wide")
8
 
 
 
 
 
 
9
  if "review" not in st.session_state:
10
  st.session_state.review = ""
11
  if "dark_mode" not in st.session_state:
12
  st.session_state.dark_mode = False
 
 
13
 
14
+ if st.session_state.dark_mode:
15
+ st.markdown("""<style>body { background-color: #111; color: white; }</style>""", unsafe_allow_html=True)
16
+
17
  with st.sidebar:
18
+ st.title("⚙️ Settings")
19
  st.session_state.dark_mode = st.toggle("🌙 Dark Mode", value=st.session_state.dark_mode)
20
+ api_key = st.text_input("🔐 API Key", type="password")
21
+ backend_url = st.text_input("🌐 Backend URL", value="http://localhost:8000")
22
+
23
+ st.title("🧠 NeuroPulse AI – Multimodal Review Analyzer")
24
+ review = st.text_area("📝 Enter Review", value=st.session_state.review, height=150)
25
+
26
+ if st.button("🔍 Analyze", use_container_width=True):
27
+ if not api_key:
28
+ st.error("⚠️ Please enter API key.")
29
+ elif len(review.split()) < 10:
30
+ st.warning("📝 Minimum 10 words required.")
31
+ else:
32
+ with st.spinner("Processing..."):
33
+ try:
34
+ payload = {"text": review}
35
+ headers = {"x-api-key": api_key}
36
+ res = requests.post(f"{backend_url}/analyze/", json=payload, headers=headers)
37
+ if res.status_code == 200:
38
+ data = res.json()
39
+ st.success(" Analysis Successful")
40
+ st.info(f"📌 Summary: {data['summary']}")
41
+ st.metric("📊 Sentiment", data["sentiment"]["label"])
42
+ else:
43
+ st.error(f" API Error: {res.status_code} - {res.text}")
44
+ except Exception as e:
45
+ st.error(f"🚫 Exception: {e}")