Sumedhzz commited on
Commit
75d538d
Β·
1 Parent(s): 7de38b7

Integrated Google Sheets cloud logging

Browse files
Files changed (2) hide show
  1. requirements.txt +1 -0
  2. src/streamlit_app.py +75 -122
requirements.txt CHANGED
@@ -4,4 +4,5 @@ torch
4
  torchvision
5
  safetensors
6
  pandas
 
7
  plotly
 
4
  torchvision
5
  safetensors
6
  pandas
7
+ st-gsheets-connection
8
  plotly
src/streamlit_app.py CHANGED
@@ -1,161 +1,114 @@
1
  import streamlit as st
2
  from transformers import pipeline
3
- import os
4
  import pandas as pd
5
  from datetime import datetime
6
- import time
7
  import plotly.graph_objects as go
 
8
 
9
  # --- PAGE CONFIG ---
10
  st.set_page_config(page_title="Sentiment Analyzer AI | Bilingual Engine", page_icon="🌐", layout="wide")
11
 
12
- # --- PROFESSIONAL NEUMORPHIC / GLASS CSS ---
13
  st.markdown("""
14
  <style>
15
- .stApp {
16
- background: linear-gradient(135deg, #12141d 0%, #1a1c2c 100%);
17
- color: #ffffff;
18
- }
19
- div[data-baseweb="input"] {
20
- background: rgba(255, 255, 255, 0.05) !important;
21
- backdrop-filter: blur(10px) !important;
22
- border-radius: 15px !important;
23
- border: 1px solid rgba(255, 255, 255, 0.1) !important;
24
- padding: 5px !important;
25
- }
26
  .glass-card {
27
  background: rgba(255, 255, 255, 0.05);
28
  backdrop-filter: blur(10px);
29
  border-radius: 20px;
30
  border: 1px solid rgba(255, 255, 255, 0.1);
31
- padding: 30px;
32
- margin-top: 20px;
33
- margin-bottom: 25px;
34
  }
35
  .stButton>button {
36
  background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
37
- color: white;
38
- border-radius: 12px;
39
- font-weight: 600;
40
- height: 3rem;
41
  }
42
- [data-testid="stMetricValue"] { color: #00f2fe; font-weight: 800; }
43
  </style>
44
  """, unsafe_allow_html=True)
45
 
46
- # --- DATA LOGGING ---
47
- FEEDBACK_FILE = "sentiment_feedback.csv"
48
-
49
- def save_smart_data(text, ai_label, ai_score, corrected_label=None):
50
- needs_review = "YES" if 0.33 <= ai_score <= 0.65 else "NO"
51
- new_data = {
52
- "Timestamp": [datetime.now().strftime("%Y-%m-%d %H:%M:%S")],
53
- "Text": [text],
54
- "AI_Label": [ai_label],
55
- "Confidence": [round(ai_score, 4)],
56
- "Needs_Review": [needs_review],
57
- "Corrected_Label": [corrected_label if corrected_label else ai_label]
58
- }
59
- df = pd.DataFrame(new_data)
60
- if not os.path.isfile(FEEDBACK_FILE):
61
- df.to_csv(FEEDBACK_FILE, index=False)
62
- else:
63
- df.to_csv(FEEDBACK_FILE, mode='a', header=False, index=False)
64
-
65
- # --- MODEL ENGINE PATH FIX ---
66
- import streamlit as st
67
- from transformers import pipeline
68
 
69
- # This MUST match your model repo name from Screenshot 281
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  MODEL_REPO = "SumedhGajbhiye/Sentiment-Analyzer"
71
 
72
  @st.cache_resource
73
  def load_analysis_engine():
74
  try:
75
- # This tells the app to download weights from the Hub, not the local folder
76
  return pipeline("sentiment-analysis", model=MODEL_REPO, tokenizer=MODEL_REPO)
77
  except Exception as e:
78
- st.error(f"Could not connect to System Core: {e}")
79
  return None
80
 
81
- # IMPORTANT: Find and delete the line in your code that says:
82
- # if not os.path.exists("model.safetensors"): st.error("System Core... not found")
83
-
84
-
85
-
86
- # --- HEADER SECTION ---
87
- st.title("Sentiment Analyzer")
88
- st.caption("Advanced Bilingual Sentiment Analysis for English, Hindi & Hinglish")
89
-
90
- # --- SIDEBAR HUD ---
91
- with st.sidebar:
92
- st.markdown("### πŸ› οΈ ENGINE STATUS")
93
- if os.path.exists(FEEDBACK_FILE):
94
- df_log = pd.read_csv(FEEDBACK_FILE)
95
- st.metric("Total Ingested", len(df_log))
96
- st.metric("Anomalies Flagged", len(df_log[df_log['Needs_Review'] == 'YES']))
97
- st.download_button("πŸ“€ Export Dataset", df_log.to_csv(index=False), "engine_feedback.csv", "text/csv")
98
- else:
99
- st.info("Waiting for input...")
100
 
101
- # --- ANALYSIS INTERFACE ---
102
- # 1. We call the cached loader (it handles the Hub download automatically)
103
  classifier = load_analysis_engine()
104
 
105
- if classifier is None:
106
- st.error("System Core could not be initialized. Please check the logs.")
107
- else:
108
- user_input = st.text_input(
109
- "QUERY INPUT:",
110
- placeholder="Enter sentence (English/Hindi/Hinglish)...",
111
- key="main_input"
112
- )
113
 
114
  if user_input:
115
- with st.status("Neural Scan in Progress...", expanded=False) as status:
116
- # Running the inference
117
  result = classifier(user_input)[0]
118
- status.update(label="Analysis Complete", state="complete")
119
-
120
- label = result['label']
121
- score = result['score']
122
-
123
- # Mapping labels (Adjust if your XLM-Roberta uses LABEL_0/1/2)
124
- emoji_map = {"POSITIVE": "🟒", "NEUTRAL": "🟑", "NEGATIVE": "πŸ”΄"}
125
-
126
- # Color logic
127
- color = "#00ff88" if "POS" in label.upper() else "#ff4b4b" if "NEG" in label.upper() else "#ffaa00"
128
-
129
- st.markdown(f'''
130
- <div class="glass-card">
131
- <h4 style="color: #888; margin:0;">RESULT</h4>
132
- <h1 style="color: {color}; margin:0; font-size: 3rem;">{label} {emoji_map.get(label.upper(), "")}</h1>
133
- <p style="color: #aaa;">Confidence: {score:.1%}</p>
134
- </div>
135
- ''', unsafe_allow_html=True)
136
-
137
- # Gauge Chart
138
- fig = go.Figure(go.Indicator(
139
- mode = "gauge+number",
140
- value = score * 100,
141
- gauge = {'axis': {'range': [0, 100]}, 'bar': {'color': color}}
142
- ))
143
- fig.update_layout(height=250, paper_bgcolor='rgba(0,0,0,0)', font={'color': "#fff"})
144
- st.plotly_chart(fig, use_container_width=True)
145
-
146
- # Human Verification
147
- c1, c2 = st.columns(2)
148
- with c1:
149
- if st.button("CONFIRM ACCURACY"):
150
- save_smart_data(user_input, label, score)
151
- st.toast("Saved!")
152
- with c2:
153
- correction = st.selectbox("CORRECT LABEL:", ["Positive", "Neutral", "Negative"])
154
- if st.button("SAVE CORRECTION"):
155
- save_smart_data(user_input, label, score, corrected_label=correction)
156
- st.toast("Correction logged!")
157
-
158
- # --- LOGS ---
159
- if os.path.exists(FEEDBACK_FILE):
160
- with st.expander("πŸ“‚ VIEW RECENT LOGS"):
161
- st.dataframe(pd.read_csv(FEEDBACK_FILE).tail(5), use_container_width=True)
 
1
  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.")