Spaces:
Sleeping
Sleeping
File size: 7,008 Bytes
a83deda |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
import streamlit as st
import requests
import pandas as pd
from gtts import gTTS
import base64
from io import BytesIO
from PIL import Image
import os
st.set_page_config(page_title="NeuroPulse AI", page_icon="π§ ", layout="wide")
logo_path = os.path.join("app", "static", "logo.png")
if os.path.exists(logo_path):
st.image(logo_path, width=160)
# Session state
if "history" not in st.session_state:
st.session_state.history = []
if "dark_mode" not in st.session_state:
st.session_state.dark_mode = False
# Sidebar
with st.sidebar:
st.header("βοΈ Settings")
st.session_state.dark_mode = st.toggle("π Dark Mode", value=st.session_state.dark_mode)
sentiment_model = st.selectbox("π Sentiment Model", [
"distilbert-base-uncased-finetuned-sst-2-english",
"nlptown/bert-base-multilingual-uncased-sentiment"
])
industry = st.selectbox("π Industry Context", [
"Generic", "E-commerce", "Healthcare", "Education", "Travel", "Banking", "Insurance"
])
product_category = st.selectbox("π§© Product Category", [
"General", "Mobile Devices", "Laptops", "Healthcare Devices", "Banking App",
"Travel Service", "Educational Tool", "Insurance Portal"
])
device_type = st.selectbox("π» Device Type", [
"Web", "Android", "iOS", "Desktop", "Smartwatch", "Kiosk"
])
use_aspects = st.checkbox("π Enable Aspect-Based Analysis")
use_smart_summary = st.checkbox("π§ Use Smart Summary (clustered key points)")
use_smart_summary_bulk = st.checkbox("π§ Smart Summary for Bulk CSV")
follow_up = st.text_input("π Follow-up Question")
voice_lang = st.selectbox("π Voice Language", ["en", "fr", "es", "de", "hi", "zh"])
backend_url = st.text_input("π₯οΈ Backend URL", value="http://0.0.0.0:8000")
api_token = st.text_input("π API Token", type="password")
# Tabs
tab1, tab2 = st.tabs(["π§ Single Review", "π Bulk CSV"])
def speak(text, lang='en'):
tts = gTTS(text, lang=lang)
mp3 = BytesIO()
tts.write_to_fp(mp3)
b64 = base64.b64encode(mp3.getvalue()).decode()
st.markdown(f'<audio controls><source src="data:audio/mp3;base64,{b64}" type="audio/mp3"></audio>', unsafe_allow_html=True)
mp3.seek(0)
return mp3
# Tab: Single Review
with tab1:
st.title("π§ NeuroPulse AI β Multimodal Review Analyzer")
review = st.session_state.get("review", "")
review = st.text_area("π Enter a Review", value=review, height=160)
col1, col2, col3 = st.columns(3)
with col1:
analyze = st.button("π Analyze")
with col2:
if st.button("π² Example"):
st.session_state["review"] = "App was smooth, but the transaction failed twice on Android."
st.rerun()
with col3:
if st.button("π§Ή Clear"):
st.session_state["review"] = ""
st.rerun()
if analyze and review:
with st.spinner("Analyzing..."):
try:
payload = {
"text": review,
"model": sentiment_model,
"industry": industry,
"aspects": use_aspects,
"follow_up": follow_up,
"product_category": product_category,
"device": device_type
}
headers = {"X-API-Key": api_token} if api_token else {}
params = {"smart": "1"} if use_smart_summary else {}
res = requests.post(f"{backend_url}/analyze/", json=payload, headers=headers, params=params)
if res.status_code == 200:
data = res.json()
st.success("β
Analysis Complete")
st.subheader("π Summary")
st.info(data["summary"])
st.caption(f"π§ Summary Type: {'Smart Summary' if use_smart_summary else 'Standard Model'}")
st.subheader("π Audio")
audio = speak(data["summary"], lang=voice_lang)
st.download_button("β¬οΈ Download Summary Audio", audio.read(), "summary.mp3", mime="audio/mp3")
st.metric("π Sentiment", data["sentiment"]["label"], delta=f"{data['sentiment']['score']:.2%}")
st.info(f"π’ Emotion: {data['emotion']}")
if data.get("aspects"):
st.subheader("π¬ Aspects")
for a in data["aspects"]:
st.write(f"πΉ {a['aspect']}: {a['sentiment']} ({a['score']:.2%})")
if data.get("follow_up"):
st.subheader("π€ Follow-Up Response")
st.warning(data["follow_up"])
else:
st.error(f"β API Error: {res.status_code}")
except Exception as e:
st.error(f"π« {e}")
# Tab: Bulk CSV
with tab2:
st.title("π Bulk CSV Upload")
uploaded_file = st.file_uploader("Upload CSV with `review` column", type="csv")
if uploaded_file:
try:
df = pd.read_csv(uploaded_file)
if "review" in df.columns:
st.success(f"β
Loaded {len(df)} reviews")
for col in ["industry", "product_category", "device"]:
if col not in df.columns:
df[col] = [""] * len(df)
df[col] = df[col].fillna("").astype(str)
if st.button("π Analyze Bulk Reviews"):
with st.spinner("Processing..."):
payload = {
"reviews": df["review"].tolist(),
"model": sentiment_model,
"aspects": use_aspects,
"industry": df["industry"].tolist(),
"product_category": df["product_category"].tolist(),
"device": df["device"].tolist()
}
headers = {"X-API-Key": api_token} if api_token else {}
params = {"smart": "1"} if use_smart_summary_bulk else {}
res = requests.post(f"{backend_url}/bulk/", json=payload, headers=headers, params=params)
if res.status_code == 200:
results = pd.DataFrame(res.json()["results"])
results["summary_type"] = "Smart" if use_smart_summary_bulk else "Standard"
st.dataframe(results)
st.download_button("β¬οΈ Download Results CSV", results.to_csv(index=False), "bulk_results.csv", mime="text/csv")
else:
st.error(f"β Bulk Analysis Failed: {res.status_code}")
else:
st.error("CSV must contain a column named `review`.")
except Exception as e:
st.error(f"β File Error: {e}")
|