Sumedhzz commited on
Commit
442f5c5
Β·
1 Parent(s): 75d538d

UI Update: Glassmorphic design and Cloud logging

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +130 -51
src/streamlit_app.py CHANGED
@@ -2,113 +2,192 @@ import streamlit as st
2
  from transformers import pipeline
3
  import pandas as pd
4
  from datetime import datetime
 
5
  import plotly.graph_objects as go
 
6
  from streamlit_gsheets import GSheetsConnection
7
 
8
  # --- PAGE CONFIG ---
9
  st.set_page_config(page_title="Sentiment Analyzer AI | Bilingual Engine", page_icon="🌐", layout="wide")
10
 
11
- # --- CUSTOM CSS FOR GLASS-CARD LOOK ---
12
  st.markdown("""
13
  <style>
14
- .stApp { background: linear-gradient(135deg, #12141d 0%, #1a1c2c 100%); color: #ffffff; }
 
 
 
 
 
 
 
 
 
 
 
 
15
  .glass-card {
16
  background: rgba(255, 255, 255, 0.05);
17
  backdrop-filter: blur(10px);
18
  border-radius: 20px;
19
  border: 1px solid rgba(255, 255, 255, 0.1);
20
- padding: 25px;
21
- margin-bottom: 20px;
 
 
22
  }
 
23
  .stButton>button {
24
  background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
25
- color: white; border-radius: 12px; font-weight: 600; width: 100%;
 
 
 
 
 
 
 
 
 
 
26
  }
 
 
27
  </style>
28
  """, unsafe_allow_html=True)
29
 
30
  # --- CLOUD DATA LOGGING (GOOGLE SHEETS) ---
31
- # This connects to the sheet you shared with the service account
32
- conn = st.connection("gsheets", type=GSheetsConnection)
 
 
 
33
 
34
  def save_to_cloud(text, ai_label, ai_score, corrected_label=None):
35
  try:
36
- # Read existing data to append
37
- existing_data = conn.read(worksheet="Sheet1", ttl=0)
 
38
  except:
39
  existing_data = pd.DataFrame()
40
 
 
41
  new_entry = pd.DataFrame([{
42
  "Timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
43
  "Text": text,
44
  "AI_Label": ai_label,
45
  "Confidence": f"{ai_score:.2%}",
 
46
  "Correction": corrected_label if corrected_label else "N/A"
47
  }])
48
 
49
  updated_df = pd.concat([existing_data, new_entry], ignore_index=True)
50
- conn.update(worksheet="Sheet1", data=updated_df)
51
 
52
  # --- MODEL ENGINE ---
53
- MODEL_REPO = "SumedhGajbhiye/Sentiment-Analyzer"
54
 
55
  @st.cache_resource
56
- def load_analysis_engine():
 
 
 
 
 
 
 
 
 
 
 
 
57
  try:
58
- # Pulls directly from your HF Model Repo
59
- return pipeline("sentiment-analysis", model=MODEL_REPO, tokenizer=MODEL_REPO)
60
- except Exception as e:
61
- st.error(f"System Core Connection Failed: {e}")
62
- return None
63
-
64
- # --- UI HEADER ---
65
- st.title("🌐 Sentiment Analyzer")
66
- st.caption("Bilingual Engine: English | Hindi | Hinglish")
67
 
68
- classifier = load_analysis_engine()
 
69
 
70
  if classifier:
71
- user_input = st.text_input("QUERY INPUT:", placeholder="Type a sentence...", key="main_input")
 
 
 
 
 
72
 
73
  if user_input:
74
- with st.spinner("Neural Scan..."):
 
75
  result = classifier(user_input)[0]
76
- label, score = result['label'], result['score']
77
- color = "#00ff88" if "POS" in label.upper() else "#ff4b4b" if "NEG" in label.upper() else "#ffaa00"
78
-
79
- # --- SIDE-BY-SIDE LAYOUT ---
80
- # 1.5 ratio for left makes the gauge much bigger
81
- col_left, col_right = st.columns([1.5, 1], gap="large")
82
-
83
- with col_left:
84
- st.markdown(f'<div class="glass-card"><h4>RESULT: <span style="color:{color}">{label}</span></h4></div>', unsafe_allow_html=True)
85
-
86
- # Big Professional Gauge
 
 
 
 
 
 
 
 
 
 
87
  fig = go.Figure(go.Indicator(
88
  mode = "gauge+number",
89
  value = score * 100,
90
- number = {'suffix': "%", 'font': {'color': '#fff'}},
91
  gauge = {
92
- 'axis': {'range': [0, 100], 'tickcolor': "#888"},
93
  'bar': {'color': color},
94
  'bgcolor': "rgba(0,0,0,0)",
95
  'borderwidth': 2,
96
- 'bordercolor': "rgba(255,255,255,0.1)"
97
  }
98
  ))
99
- fig.update_layout(height=450, margin=dict(t=50, b=0), paper_bgcolor='rgba(0,0,0,0)', font={'color': "#fff"})
 
 
 
 
 
 
100
  st.plotly_chart(fig, use_container_width=True)
101
 
102
- with col_right:
103
- st.markdown("### πŸ› οΈ Neural Feedback")
104
- st.info("Human verification helps the engine learn mixed-language nuances.")
 
 
 
 
 
 
105
 
106
- if st.button("βœ… CONFIRM ACCURACY"):
107
- save_to_cloud(user_input, label, score)
108
- st.toast("Success! Verified data sent to Google Sheets.")
109
-
110
- st.markdown("---")
111
- correction = st.selectbox("UNCERTAIN? CORRECT LABEL:", ["Positive", "Neutral", "Negative"])
112
- if st.button("πŸ’Ύ SAVE CORRECTION"):
113
- save_to_cloud(user_input, label, score, corrected_label=correction)
114
- st.warning("Correction logged for retraining.")
 
 
 
 
 
 
2
  from transformers import pipeline
3
  import pandas as pd
4
  from datetime import datetime
5
+ import time
6
  import plotly.graph_objects as go
7
+ import json
8
  from streamlit_gsheets import GSheetsConnection
9
 
10
  # --- PAGE CONFIG ---
11
  st.set_page_config(page_title="Sentiment Analyzer AI | Bilingual Engine", page_icon="🌐", layout="wide")
12
 
13
+ # --- PROFESSIONAL NEUMORPHIC / GLASS CSS ---
14
  st.markdown("""
15
  <style>
16
+ .stApp {
17
+ background: linear-gradient(135deg, #12141d 0%, #1a1c2c 100%);
18
+ color: #ffffff;
19
+ }
20
+
21
+ div[data-baseweb="input"] {
22
+ background: rgba(255, 255, 255, 0.05) !important;
23
+ backdrop-filter: blur(10px) !important;
24
+ border-radius: 15px !important;
25
+ border: 1px solid rgba(255, 255, 255, 0.1) !important;
26
+ padding: 5px !important;
27
+ }
28
+
29
  .glass-card {
30
  background: rgba(255, 255, 255, 0.05);
31
  backdrop-filter: blur(10px);
32
  border-radius: 20px;
33
  border: 1px solid rgba(255, 255, 255, 0.1);
34
+ padding: 30px;
35
+ margin-top: 20px;
36
+ margin-bottom: 25px;
37
+ transition: 0.4s ease;
38
  }
39
+
40
  .stButton>button {
41
  background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
42
+ color: white;
43
+ border: none;
44
+ border-radius: 12px;
45
+ font-weight: 600;
46
+ letter-spacing: 0.5px;
47
+ height: 3rem;
48
+ transition: all 0.3s ease;
49
+ }
50
+ .stButton>button:hover {
51
+ box-shadow: 0 0 20px rgba(79, 172, 254, 0.4);
52
+ transform: scale(1.02);
53
  }
54
+
55
+ [data-testid="stMetricValue"] { color: #00f2fe; font-weight: 800; }
56
  </style>
57
  """, unsafe_allow_html=True)
58
 
59
  # --- CLOUD DATA LOGGING (GOOGLE SHEETS) ---
60
+ if "GSHEETS_JSON" in st.secrets:
61
+ creds = json.loads(st.secrets["GSHEETS_JSON"])
62
+ conn = st.connection("gsheets", type=GSheetsConnection, credentials=creds)
63
+ else:
64
+ conn = st.connection("gsheets", type=GSheetsConnection)
65
 
66
  def save_to_cloud(text, ai_label, ai_score, corrected_label=None):
67
  try:
68
+ sheet_url = st.secrets.get("GSHEETS_URL", "")
69
+ # Using "Sheet1" as per your previous spreadsheet setup
70
+ existing_data = conn.read(spreadsheet=sheet_url, worksheet="Sheet1", ttl=0)
71
  except:
72
  existing_data = pd.DataFrame()
73
 
74
+ needs_review = "YES" if 0.33 <= ai_score <= 0.65 else "NO"
75
  new_entry = pd.DataFrame([{
76
  "Timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
77
  "Text": text,
78
  "AI_Label": ai_label,
79
  "Confidence": f"{ai_score:.2%}",
80
+ "Needs_Review": needs_review,
81
  "Correction": corrected_label if corrected_label else "N/A"
82
  }])
83
 
84
  updated_df = pd.concat([existing_data, new_entry], ignore_index=True)
85
+ conn.update(spreadsheet=sheet_url, worksheet="Sheet1", data=updated_df)
86
 
87
  # --- MODEL ENGINE ---
88
+ MODEL_PATH = "SumedhGajbhiye/Sentiment-Analyzer"
89
 
90
  @st.cache_resource
91
+ def load_engine(path):
92
+ # Pulls directly from your HF Model Repo
93
+ return pipeline("sentiment-analysis", model=path, tokenizer=path)
94
+
95
+ # --- HEADER SECTION ---
96
+ col_h1, col_h2 = st.columns([3, 1])
97
+ with col_h1:
98
+ st.title("Sentiment Analyzer")
99
+ st.caption("Advanced Bilingual Sentiment Analysis for English, Hindi & Hinglish")
100
+
101
+ # --- SIDEBAR HUD ---
102
+ with st.sidebar:
103
+ st.markdown("### πŸ› οΈ ENGINE STATUS")
104
  try:
105
+ sheet_url = st.secrets.get("GSHEETS_URL", "")
106
+ df_log = conn.read(spreadsheet=sheet_url, worksheet="Sheet1", ttl=0)
107
+ st.metric("Total Ingested", len(df_log))
108
+ st.divider()
109
+ st.download_button("πŸ“€ Export Dataset", df_log.to_csv(index=False), "engine_feedback.csv", "text/csv")
110
+ except:
111
+ st.info("Engine is connecting to cloud...")
 
 
112
 
113
+ # --- ANALYSIS INTERFACE ---
114
+ classifier = load_engine(MODEL_PATH)
115
 
116
  if classifier:
117
+ user_input = st.text_input(
118
+ "QUERY INPUT:",
119
+ placeholder="Enter sentence for deep sentiment analysis...",
120
+ key="main_input",
121
+ label_visibility="collapsed"
122
+ )
123
 
124
  if user_input:
125
+ with st.status("Initializing Neural Weights...", expanded=False) as status:
126
+ time.sleep(0.4)
127
  result = classifier(user_input)[0]
128
+ status.update(label="Analysis Complete", state="complete", expanded=False)
129
+
130
+ label = result['label']
131
+ score = result['score']
132
+
133
+ emoji_map = {"Positive": "🟒", "Neutral": "🟑", "Negative": "πŸ”΄"}
134
+ color = "#00ff88" if "POS" in label.upper() else "#ff4b4b" if "NEG" in label.upper() else "#ffaa00"
135
+
136
+ # --- RESULTS GLASS CARD ---
137
+ st.markdown(f'''
138
+ <div class="glass-card">
139
+ <h4 style="color: #888; margin:0;">CLASSIFICATION RESULT</h4>
140
+ <h1 style="color: {color}; margin:0; font-size: 3.5rem;">{label} {emoji_map.get(label, "")}</h1>
141
+ <p style="color: #aaa; margin-top: 10px;">Deep linguistic scan detected {label.lower()} intent with {score:.1%} confidence.</p>
142
+ </div>
143
+ ''', unsafe_allow_html=True)
144
+
145
+ # --- CHART & CORRECTION ROW ---
146
+ col_chart, col_feed = st.columns([1, 2])
147
+
148
+ with col_chart:
149
  fig = go.Figure(go.Indicator(
150
  mode = "gauge+number",
151
  value = score * 100,
152
+ domain = {'x': [0, 1], 'y': [0, 1]},
153
  gauge = {
154
+ 'axis': {'range': [None, 100], 'tickcolor': "#888", 'tickwidth': 2},
155
  'bar': {'color': color},
156
  'bgcolor': "rgba(0,0,0,0)",
157
  'borderwidth': 2,
158
+ 'bordercolor': "rgba(255,255,255,0.1)",
159
  }
160
  ))
161
+
162
+ fig.update_layout(
163
+ height=280,
164
+ margin=dict(t=50, b=50, l=40, r=40),
165
+ paper_bgcolor='rgba(0,0,0,0)',
166
+ font={'color': "#fff", 'family': "Inter"}
167
+ )
168
  st.plotly_chart(fig, use_container_width=True)
169
 
170
+ with col_feed:
171
+ st.markdown("### βš–οΈ HUMAN VERIFICATION")
172
+ c1, c2 = st.columns(2)
173
+ with c1:
174
+ if st.button("CONFIRM ACCURACY"):
175
+ save_to_cloud(user_input, label, score)
176
+ st.toast("Logic logged to cloud database.")
177
+ time.sleep(1.0)
178
+ st.rerun()
179
 
180
+ with c2:
181
+ correction = st.selectbox("OVERRIDE LABEL:", ["Positive", "Neutral", "Negative"])
182
+ if st.button("FORCE UPDATE ENGINE"):
183
+ save_to_cloud(user_input, label, score, corrected_label=correction)
184
+ st.toast(f"Engine forced to {correction}")
185
+ time.sleep(1.0)
186
+ st.rerun()
187
+
188
+ # --- RECENT LOGS ---
189
+ try:
190
+ with st.expander("πŸ“‚ VIEW SYSTEM LOGS"):
191
+ st.dataframe(df_log.tail(10), use_container_width=True)
192
+ except:
193
+ pass