Spaces:
Running
Running
File size: 7,113 Bytes
ffbd3ab 442f5c5 ffbd3ab 442f5c5 7a36cad 91b9b3a ffbd3ab 91b9b3a 442f5c5 ffbd3ab 2faf678 442f5c5 ffbd3ab 91b9b3a efd5730 d125af0 91b9b3a 7a36cad 91b9b3a 7a36cad 91b9b3a 7a36cad 2faf678 91b9b3a 2faf678 91b9b3a 7a36cad d125af0 7a36cad d125af0 91b9b3a 9fae22e 7a36cad 2faf678 91b9b3a 7a36cad 75d538d 91b9b3a efd5730 91b9b3a 75d538d 442f5c5 91b9b3a ffbd3ab 442f5c5 91b9b3a 9fae22e 442f5c5 91b9b3a 7a36cad 442f5c5 9607fc6 91b9b3a 9fae22e 442f5c5 91b9b3a 442f5c5 91b9b3a 7a36cad 442f5c5 91b9b3a 75d538d 2faf678 91b9b3a ffbd3ab 442f5c5 ffbd3ab 442f5c5 91b9b3a 442f5c5 91b9b3a 442f5c5 91b9b3a 442f5c5 91b9b3a 442f5c5 75d538d 7a36cad 75d538d 2faf678 75d538d 91b9b3a 442f5c5 2faf678 7a36cad 2faf678 442f5c5 2faf678 7a36cad 2faf678 91b9b3a 442f5c5 7a36cad 91b9b3a | 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 164 165 166 167 168 169 170 171 172 173 | import streamlit as st
from transformers import pipeline
import pandas as pd
from datetime import datetime
import time
import plotly.graph_objects as go
import json
import os
import gspread
from google.oauth2.service_account import Credentials
# --- PAGE CONFIG ---
st.set_page_config(page_title="Sentiment Analyzer AI | Bilingual Engine", page_icon="π", layout="wide")
# --- PROFESSIONAL NEUMORPHIC / GLASS CSS ---
st.markdown("""
<style>
.stApp { background: linear-gradient(135deg, #12141d 0%, #1a1c2c 100%); color: #ffffff; }
div[data-baseweb="input"] { background: rgba(255, 255, 255, 0.05) !important; backdrop-filter: blur(10px) !important; border-radius: 15px !important; border: 1px solid rgba(255, 255, 255, 0.1) !important; padding: 5px !important; }
.glass-card { background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(10px); border-radius: 20px; border: 1px solid rgba(255, 255, 255, 0.1); padding: 30px; margin-top: 20px; margin-bottom: 25px; transition: 0.4s ease; }
.stButton>button { background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%); color: white; border: none; border-radius: 12px; font-weight: 600; letter-spacing: 0.5px; height: 3rem; transition: all 0.3s ease; }
.stButton>button:hover { box-shadow: 0 0 20px rgba(79, 172, 254, 0.4); transform: scale(1.02); }
[data-testid="stMetricValue"] { color: #00f2fe; font-weight: 800; }
</style>
""", unsafe_allow_html=True)
# --- GOOGLE SHEETS CONNECTION (gspread - works in Docker) ---
def get_connection():
try:
# Docker Spaces inject secrets as ENV VARS
json_secrets = os.environ.get("GSHEETS_JSON")
sheet_url = os.environ.get("GSHEETS_URL")
# Fallback for local development
if not json_secrets:
json_secrets = st.secrets.get("GSHEETS_JSON")
if not sheet_url:
sheet_url = st.secrets.get("GSHEETS_URL")
if not json_secrets or not sheet_url:
st.error("β Secrets not found. Please add GSHEETS_JSON and GSHEETS_URL in Space Settings β Secrets.")
st.stop()
creds_dict = json.loads(json_secrets)
scopes = [
"https://spreadsheets.google.com/feeds",
"https://www.googleapis.com/auth/drive"
]
creds = Credentials.from_service_account_info(creds_dict, scopes=scopes)
client = gspread.authorize(creds)
sheet = client.open_by_url(sheet_url).worksheet("Sheet1")
return sheet, sheet_url
except json.JSONDecodeError:
st.error("β GSHEETS_JSON is not valid JSON. Please re-paste your service account key.")
st.stop()
except Exception as e:
st.error(f"β Connection Failed: {e}")
st.stop()
# --- INITIALIZATION ---
if 'conn' not in st.session_state or 'url' not in st.session_state:
conn, GSHEETS_URL = get_connection()
st.session_state.conn = conn
st.session_state.url = GSHEETS_URL
else:
conn = st.session_state.conn
GSHEETS_URL = st.session_state.url
# --- SAVE TO GOOGLE SHEETS ---
def save_to_cloud(text, ai_label, ai_score, corrected_label=None):
try:
sheet = st.session_state.conn
new_row = [
datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
text,
ai_label,
f"{ai_score:.2%}",
corrected_label if corrected_label else "N/A"
]
sheet.append_row(new_row)
return True
except Exception as e:
st.error(f"Cloud Save Failed: {e}")
return False
# --- MODEL ENGINE ---
MODEL_PATH = "SumedhGajbhiye/Sentiment-Analyzer"
@st.cache_resource
def load_engine(path):
return pipeline("sentiment-analysis", model=path, tokenizer=path)
# --- UI LAYOUT ---
col_h1, col_h2 = st.columns([3, 1])
with col_h1:
st.title("Sentiment Analyzer")
st.caption("Advanced Bilingual Sentiment Analysis for English, Hindi & Hinglish")
# --- SIDEBAR STATS ---
with st.sidebar:
st.markdown("### π οΈ ENGINE STATUS")
try:
sheet = st.session_state.conn
all_rows = sheet.get_all_records()
df_log = pd.DataFrame(all_rows)
st.metric("Total Ingested", len(df_log))
st.divider()
st.download_button("π€ Export Dataset", df_log.to_csv(index=False), "engine_feedback.csv", "text/csv")
except Exception:
df_log = pd.DataFrame()
st.info("Engine is connecting to cloud...")
# --- MAIN LOGIC ---
classifier = load_engine(MODEL_PATH)
if classifier:
user_input = st.text_input("QUERY INPUT:", placeholder="Enter sentence...", key="main_input", label_visibility="collapsed")
if user_input:
with st.status("Initializing Neural Weights...", expanded=False) as status:
time.sleep(0.4)
result = classifier(user_input)[0]
status.update(label="Analysis Complete", state="complete", expanded=False)
label = result['label']
score = result['score']
emoji_map = {"Positive": "π’", "Neutral": "π‘", "Negative": "π΄"}
color = "#00ff88" if "POS" in label.upper() else "#ff4b4b" if "NEG" in label.upper() else "#ffaa00"
st.markdown(f'''
<div class="glass-card">
<h4 style="color: #888; margin:0;">CLASSIFICATION RESULT</h4>
<h1 style="color: {color}; margin:0; font-size: 3.5rem;">{label} {emoji_map.get(label, "")}</h1>
<p style="color: #aaa; margin-top: 10px;">Deep linguistic scan detected {label.lower()} intent with {score:.1%} confidence.</p>
</div>
''', unsafe_allow_html=True)
col_chart, col_feed = st.columns([1, 2])
with col_chart:
fig = go.Figure(go.Indicator(
mode="gauge+number", value=score * 100,
gauge={'axis': {'range': [None, 100]}, 'bar': {'color': color}, 'bgcolor': "rgba(0,0,0,0)"}
))
fig.update_layout(height=280, margin=dict(t=50, b=50, l=40, r=40), paper_bgcolor='rgba(0,0,0,0)', font={'color': "#fff"})
st.plotly_chart(fig, use_container_width=True)
with col_feed:
st.markdown("### βοΈ HUMAN VERIFICATION")
c1, c2 = st.columns(2)
with c1:
if st.button("CONFIRM ACCURACY"):
if save_to_cloud(user_input, label, score):
st.toast("β
Logic logged to cloud database.")
time.sleep(1.0)
st.rerun()
with c2:
correction = st.selectbox("OVERRIDE LABEL:", ["Positive", "Neutral", "Negative"])
if st.button("FORCE UPDATE ENGINE"):
if save_to_cloud(user_input, label, score, corrected_label=correction):
st.toast(f"β
Engine forced to {correction}")
time.sleep(1.0)
st.rerun()
# --- RECENT LOGS ---
try:
if not df_log.empty:
with st.expander("π VIEW SYSTEM LOGS"):
st.dataframe(df_log.tail(10), use_container_width=True)
except Exception:
pass
|