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(""" """, 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'''

CLASSIFICATION RESULT

{label} {emoji_map.get(label, "")}

Deep linguistic scan detected {label.lower()} intent with {score:.1%} confidence.

''', 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