Hasitha16 commited on
Commit
7adc39b
Β·
verified Β·
1 Parent(s): d56816b

Update frontend.py

Browse files
Files changed (1) hide show
  1. frontend.py +105 -130
frontend.py CHANGED
@@ -9,51 +9,23 @@ import os
9
 
10
  st.set_page_config(page_title="NeuroPulse AI", page_icon="🧠", layout="wide")
11
 
 
12
  logo_path = os.path.join("app", "static", "logo.png")
13
  if os.path.exists(logo_path):
14
  st.image(logo_path, width=160)
15
 
16
  # Session state
17
- if "history" not in st.session_state:
18
- st.session_state.history = []
19
- if "dark_mode" not in st.session_state:
20
- st.session_state.dark_mode = False
21
 
22
- # Sidebar
23
  with st.sidebar:
24
- st.header("βš™οΈ Settings")
25
- st.session_state.dark_mode = st.toggle("πŸŒ™ Dark Mode", value=st.session_state.dark_mode)
26
-
27
- sentiment_model = st.selectbox("πŸ“Š Sentiment Model", [
28
- "distilbert-base-uncased-finetuned-sst-2-english",
29
- "nlptown/bert-base-multilingual-uncased-sentiment"
30
- ])
31
-
32
- industry = st.selectbox("🏭 Industry Context", [
33
- "Generic", "E-commerce", "Healthcare", "Education", "Travel", "Banking", "Insurance"
34
- ])
35
-
36
- product_category = st.selectbox("🧩 Product Category", [
37
- "General", "Mobile Devices", "Laptops", "Healthcare Devices", "Banking App",
38
- "Travel Service", "Educational Tool", "Insurance Portal"
39
- ])
40
-
41
- device_type = st.selectbox("πŸ’» Device Type", [
42
- "Web", "Android", "iOS", "Desktop", "Smartwatch", "Kiosk"
43
- ])
44
-
45
- use_aspects = st.checkbox("πŸ“Š Enable Aspect-Based Analysis")
46
- use_smart_summary = st.checkbox("🧠 Use Smart Summary (clustered key points)")
47
- use_smart_summary_bulk = st.checkbox("🧠 Smart Summary for Bulk CSV")
48
-
49
- follow_up = st.text_input("πŸ” Follow-up Question")
50
- voice_lang = st.selectbox("πŸ”ˆ Voice Language", ["en", "fr", "es", "de", "hi", "zh"])
51
- backend_url = st.text_input("πŸ–₯️ Backend URL", value="http://0.0.0.0:8000")
52
- api_token = st.text_input("πŸ” API Token", type="password")
53
-
54
- # Tabs
55
- tab1, tab2 = st.tabs(["🧠 Single Review", "πŸ“š Bulk CSV"])
56
 
 
57
  def speak(text, lang='en'):
58
  tts = gTTS(text, lang=lang)
59
  mp3 = BytesIO()
@@ -63,100 +35,103 @@ def speak(text, lang='en'):
63
  mp3.seek(0)
64
  return mp3
65
 
66
- # Tab: Single Review
67
- with tab1:
68
- st.title("🧠 NeuroPulse AI – Multimodal Review Analyzer")
69
-
70
- review = st.session_state.get("review", "")
71
- review = st.text_area("πŸ“ Enter a Review", value=review, height=160)
72
-
73
- col1, col2, col3 = st.columns(3)
74
- with col1:
75
- analyze = st.button("πŸ” Analyze")
76
- with col2:
77
- if st.button("🎲 Example"):
78
- st.session_state["review"] = "App was smooth, but the transaction failed twice on Android."
79
- st.rerun()
80
- with col3:
81
- if st.button("πŸ•ΉοΈ Clear"):
82
- st.session_state["review"] = ""
83
- st.rerun()
84
-
85
- if analyze and review:
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  with st.spinner("Analyzing..."):
87
- try:
88
- payload = {
89
- "text": review,
90
- "model": sentiment_model,
91
- "industry": industry,
92
- "aspects": use_aspects,
93
- "follow_up": follow_up,
94
- "product_category": product_category,
95
- "device": device_type
96
- }
97
- headers = {"X-API-Key": api_token} if api_token else {}
98
- params = {"smart": "1"} if use_smart_summary else {}
99
- res = requests.post(f"{backend_url}/analyze/", json=payload, headers=headers, params=params)
100
- if res.status_code == 200:
101
- data = res.json()
102
- st.success("βœ… Analysis Complete")
103
- st.subheader("πŸ“Œ Summary")
104
- st.info(data["summary"])
105
- st.caption(f"🧠 Summary Type: {'Smart Summary' if use_smart_summary else 'Standard Model'}")
106
- st.subheader("πŸ”Š Audio")
107
- audio = speak(data["summary"], lang=voice_lang)
108
- st.download_button("⬇️ Download Summary Audio", audio.read(), "summary.mp3", mime="audio/mp3")
109
- st.metric("πŸ“Š Sentiment", data["sentiment"]["label"], delta=f"{data['sentiment']['score']:.2%}")
110
- st.info(f"πŸ’’ Emotion: {data['emotion']}")
111
- if data.get("aspects"):
112
- st.subheader("πŸ” Aspects")
113
- for a in data["aspects"]:
114
- st.write(f"πŸ”Ή {a['aspect']}: {a['sentiment']} ({a['score']:.2%})")
115
- if data.get("follow_up"):
116
- st.subheader("🧠 Follow-Up Response")
117
- st.warning(data["follow_up"])
118
- else:
119
- st.error(f"❌ API Error: {res.status_code}")
120
- except Exception as e:
121
- st.error(f"🚫 {e}")
122
 
123
- # Tab: Bulk CSV
124
- with tab2:
125
- st.title("πŸ“š Bulk CSV Upload")
126
  uploaded_file = st.file_uploader("Upload CSV with `review` column", type="csv")
127
  if uploaded_file:
128
- try:
129
- df = pd.read_csv(uploaded_file)
130
- if "review" in df.columns:
131
- st.success(f"βœ… Loaded {len(df)} reviews")
132
-
133
- for col in ["industry", "product_category", "device"]:
134
- if col not in df.columns:
135
- df[col] = ["Generic" if col == "industry" else ""] * len(df)
136
- df[col] = df[col].fillna("").astype(str)
137
-
138
- if st.button("πŸ“Š Analyze Bulk Reviews"):
139
- with st.spinner("Processing..."):
140
- payload = {
141
- "reviews": df["review"].tolist(),
142
- "model": sentiment_model,
143
- "aspects": use_aspects,
144
- "industry": df["industry"].tolist(),
145
- "product_category": df["product_category"].tolist(),
146
- "device": df["device"].tolist()
147
- }
148
- headers = {"X-API-Key": api_token} if api_token else {}
149
- params = {"smart": "1"} if use_smart_summary_bulk else {}
150
-
151
- res = requests.post(f"{backend_url}/bulk/", json=payload, headers=headers, params=params)
152
- if res.status_code == 200:
153
- results = pd.DataFrame(res.json()["results"])
154
- results["summary_type"] = "Smart" if use_smart_summary_bulk else "Standard"
155
- st.dataframe(results)
156
- st.download_button("⬇️ Download Results CSV", results.to_csv(index=False), "bulk_results.csv", mime="text/csv")
157
- else:
158
- st.error(f"❌ Bulk Analysis Failed: {res.status_code}")
159
- else:
160
- st.error("CSV must contain a column named `review`.")
161
- except Exception as e:
162
- st.error(f"❌ File Error: {e}")
 
9
 
10
  st.set_page_config(page_title="NeuroPulse AI", page_icon="🧠", layout="wide")
11
 
12
+ # Optional logo
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
18
+ if "page" not in st.session_state:
19
+ st.session_state.page = "Home"
20
+ if "review" not in st.session_state:
21
+ st.session_state.review = ""
22
 
23
+ # Navigation
24
  with st.sidebar:
25
+ st.title("🧭 Navigation")
26
+ st.session_state.page = st.radio("Go to", ["Home", "Single Review", "Bulk CSV"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
+ # Text-to-speech
29
  def speak(text, lang='en'):
30
  tts = gTTS(text, lang=lang)
31
  mp3 = BytesIO()
 
35
  mp3.seek(0)
36
  return mp3
37
 
38
+ # Page: Home
39
+ if st.session_state.page == "Home":
40
+ st.markdown("""
41
+ <div style='text-align: center;'>
42
+ <h1 style='font-size: 48px;'>🧠 NeuroPulse AI</h1>
43
+ <p style='font-size: 20px;'>Smarter feedback analyzer using GenAI for Summarization, Sentiment, Emotion, Aspects, and GPT Q&A</p>
44
+ <a href='https://huggingface.co/spaces/your-space-name' target='_blank' style='text-decoration: none;'>
45
+ <button style='padding: 12px 30px; font-size: 18px; border-radius: 8px; background: linear-gradient(90deg, #6366f1, #4f46e5); color: white; border: none;'>πŸš€ Try App</button>
46
+ </a>
47
+ </div>
48
+ """, unsafe_allow_html=True)
49
+
50
+ # Page: Single Review
51
+ elif st.session_state.page == "Single Review":
52
+ st.title("🧠 Analyze Single Review")
53
+
54
+ with st.expander("βš™οΈ Settings"):
55
+ sentiment_model = st.selectbox("Sentiment Model", [
56
+ "distilbert-base-uncased-finetuned-sst-2-english",
57
+ "nlptown/bert-base-multilingual-uncased-sentiment"])
58
+ industry = st.selectbox("Industry", ["Generic", "E-commerce", "Healthcare"])
59
+ product_category = st.text_input("Product Category", "General")
60
+ device = st.text_input("Device", "Web")
61
+ use_aspects = st.checkbox("Enable Aspect Analysis")
62
+ use_smart = st.checkbox("Use Smart Summary")
63
+ follow_up = st.text_input("Follow-up Question")
64
+ voice_lang = st.selectbox("Voice Language", ["en", "fr", "es"])
65
+ backend_url = st.text_input("Backend URL", "http://0.0.0.0:8000")
66
+ api_token = st.text_input("API Token", type="password")
67
+
68
+ st.session_state.review = st.text_area("πŸ“ Enter your review", value=st.session_state.review, height=160)
69
+
70
+ if st.button("πŸ” Analyze") and st.session_state.review:
71
  with st.spinner("Analyzing..."):
72
+ payload = {
73
+ "text": st.session_state.review,
74
+ "model": sentiment_model,
75
+ "industry": industry,
76
+ "aspects": use_aspects,
77
+ "follow_up": follow_up,
78
+ "product_category": product_category,
79
+ "device": device
80
+ }
81
+ headers = {"X-API-Key": api_token}
82
+ params = {"smart": "1"} if use_smart else {}
83
+ res = requests.post(f"{backend_url}/analyze/", json=payload, headers=headers, params=params)
84
+ if res.status_code == 200:
85
+ out = res.json()
86
+ st.success("βœ… Done")
87
+ st.markdown(f"### πŸ“Œ Summary\n{out['summary']}")
88
+ st.caption(f"Smart Summary: {use_smart}")
89
+ audio = speak(out["summary"], lang=voice_lang)
90
+ st.download_button("⬇️ Download Audio", audio.read(), "summary.mp3")
91
+ st.metric("πŸ“Š Sentiment", out['sentiment']['label'], f"{out['sentiment']['score']:.2%}")
92
+ st.info(f"πŸ’’ Emotion: {out['emotion']}")
93
+ if out.get("aspects"):
94
+ st.markdown("### πŸ” Aspects")
95
+ for asp in out["aspects"]:
96
+ st.write(f"- {asp['aspect']}: {asp['sentiment']} ({asp['score']:.2%})")
97
+ if out.get("follow_up"):
98
+ st.warning(f"🧠 GPT: {out['follow_up']}")
99
+ else:
100
+ st.error(f"❌ Error: {res.status_code}")
 
 
 
 
 
 
101
 
102
+ # Page: Bulk CSV
103
+ elif st.session_state.page == "Bulk CSV":
104
+ st.title("πŸ“š Analyze CSV in Bulk")
105
  uploaded_file = st.file_uploader("Upload CSV with `review` column", type="csv")
106
  if uploaded_file:
107
+ df = pd.read_csv(uploaded_file)
108
+ if "review" not in df.columns:
109
+ st.error("CSV must have a 'review' column")
110
+ else:
111
+ st.success(f"βœ… {len(df)} reviews loaded")
112
+ df.fillna("", inplace=True)
113
+ if st.button("πŸ“Š Run Bulk Analysis"):
114
+ with st.spinner("Running..."):
115
+ payload = {
116
+ "reviews": df["review"].tolist(),
117
+ "model": sentiment_model,
118
+ "industry": df["industry"].tolist() if "industry" in df else ["Generic"]*len(df),
119
+ "product_category": df["product_category"].tolist() if "product_category" in df else [""]*len(df),
120
+ "device": df["device"].tolist() if "device" in df else [""]*len(df),
121
+ "aspects": use_aspects
122
+ }
123
+ headers = {"X-API-Key": api_token}
124
+ params = {"smart": "1"} if use_smart else {}
125
+ res = requests.post(f"{backend_url}/bulk/", json=payload, headers=headers, params=params)
126
+ if res.status_code == 200:
127
+ results = pd.DataFrame(res.json()["results"])
128
+ st.dataframe(results)
129
+ st.download_button("⬇️ Download CSV", results.to_csv(index=False), "results.csv")
130
+ else:
131
+ st.error(f"❌ Failed: {res.status_code}")
132
+ with st.expander("πŸ“„ Sample CSV"):
133
+ st.markdown("""
134
+ Download sample CSV [here](https://huggingface.co/datasets/hasi-labs/sample-neuropulse-csv/raw/main/sample.csv)
135
+
136
+ Required column: `review` (Optional: `industry`, `product_category`, `device`)
137
+ """)