#!/usr/bin/env python
# -*- coding: utf-8 -*-
import streamlit as st
import sqlite3
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
from datetime import datetime
import json
st.set_page_config(page_title="Sentiment Evolution Tracker", layout="wide")
# CSS personalizado
st.markdown("""
""", unsafe_allow_html=True)
@st.cache_resource
def get_db_connection():
conn = sqlite3.connect('data/sentiment_analysis.db')
conn.row_factory = sqlite3.Row
return conn
# Título y descripción
st.title("🎯 Sentiment Evolution Tracker")
st.markdown("*Sistema MCP para monitoreo de satisfacción empresarial*")
# Tabs principales
tab1, tab2, tab3, tab4 = st.tabs(["📊 Dashboard", "🔍 Detalles Clientes", "📈 Tendencias", "🛠️ MCP Tools"])
# TAB 1: DASHBOARD
with tab1:
col1, col2, col3, col4 = st.columns(4)
conn = get_db_connection()
cursor = conn.cursor()
# Métricas
cursor.execute('SELECT COUNT(*) as count FROM customer_profiles')
num_clientes = cursor.fetchone()[0]
cursor.execute('SELECT COUNT(*) as count FROM conversations')
num_analyses = cursor.fetchone()[0]
cursor.execute('SELECT AVG(sentiment_score) as avg FROM conversations')
avg_sentiment = cursor.fetchone()[0] or 0
cursor.execute('SELECT COUNT(*) as count FROM risk_alerts WHERE resolved = 0')
active_alerts = cursor.fetchone()[0]
with col1:
st.markdown(f"""
""", unsafe_allow_html=True)
with col2:
st.markdown(f"""
""", unsafe_allow_html=True)
with col3:
st.markdown(f"""
Sentimiento Promedio
{avg_sentiment:.0f}/100
""", unsafe_allow_html=True)
with col4:
st.markdown(f"""
Alertas Activas
{active_alerts}
""", unsafe_allow_html=True)
st.divider()
# Gráficas
col_left, col_right = st.columns(2)
with col_left:
# Gráfica de riesgo por cliente
cursor.execute('SELECT customer_id, churn_risk * 100 as risk FROM customer_profiles ORDER BY risk DESC')
datos = cursor.fetchall()
clientes_ids = [d['customer_id'] for d in datos]
riesgos = [d['risk'] for d in datos]
fig_riesgo = go.Figure(data=[
go.Bar(x=clientes_ids, y=riesgos,
marker=dict(color=['#e74c3c' if r > 70 else '#f39c12' if r > 50 else '#27ae60' for r in riesgos]))
])
fig_riesgo.update_layout(title="Riesgo de Churn por Cliente (%)", xaxis_title="Cliente", yaxis_title="Riesgo (%)")
st.plotly_chart(fig_riesgo, use_container_width=True)
with col_right:
# Gráfica de sentimiento por cliente
cursor.execute('SELECT customer_id, lifetime_sentiment FROM customer_profiles ORDER BY lifetime_sentiment DESC')
datos_sent = cursor.fetchall()
clientes_sent = [d['customer_id'] for d in datos_sent]
sentimientos = [d['lifetime_sentiment'] for d in datos_sent]
fig_sent = go.Figure(data=[
go.Bar(x=clientes_sent, y=sentimientos,
marker=dict(color='#764ba2'))
])
fig_sent.update_layout(title="Sentimiento Promedio por Cliente", xaxis_title="Cliente", yaxis_title="Sentimiento (0-100)")
st.plotly_chart(fig_sent, use_container_width=True)
st.divider()
# Tabla de clientes
st.subheader("📋 Clientes Registrados")
cursor.execute('''
SELECT customer_id, lifetime_sentiment, churn_risk, total_interactions, last_contact
FROM customer_profiles
ORDER BY churn_risk DESC
''')
clientes_data = []
for row in cursor.fetchall():
clientes_data.append({
'Cliente': row['customer_id'],
'Sentimiento': f"{row['lifetime_sentiment']:.1f}",
'Riesgo Churn': f"{row['churn_risk']:.1%}",
'Interacciones': row['total_interactions'],
'Último Contacto': row['last_contact'][:10] if row['last_contact'] else 'N/A'
})
df = pd.DataFrame(clientes_data)
st.dataframe(df, use_container_width=True)
conn.close()
# TAB 2: DETALLES CLIENTES
with tab2:
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute('SELECT customer_id FROM customer_profiles ORDER BY customer_id')
clientes = [row[0] for row in cursor.fetchall()]
cliente_seleccionado = st.selectbox("Selecciona un cliente:", clientes)
if cliente_seleccionado:
cursor.execute('SELECT * FROM customer_profiles WHERE customer_id = ?', (cliente_seleccionado,))
cliente = cursor.fetchone()
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Sentimiento Promedio", f"{cliente['lifetime_sentiment']:.1f}/100")
with col2:
st.metric("Riesgo Churn", f"{cliente['churn_risk']:.1%}")
with col3:
st.metric("Interacciones", cliente['total_interactions'])
st.subheader(f"Historial de {cliente_seleccionado}")
cursor.execute('''
SELECT timestamp, message, sentiment_score
FROM conversations
WHERE customer_id = ?
ORDER BY timestamp DESC
''', (cliente_seleccionado,))
conversaciones = cursor.fetchall()
for conv in conversaciones:
sentiment = conv['sentiment_score']
if sentiment > 70:
color = "🟢"
elif sentiment > 50:
color = "🟡"
else:
color = "🔴"
st.write(f"{color} **{conv['timestamp'][:10]}** - Sentimiento: {sentiment}/100")
st.write(f"*{conv['message']}*")
st.divider()
conn.close()
# TAB 3: TENDENCIAS
with tab3:
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute('SELECT customer_id FROM customer_profiles ORDER BY customer_id')
clientes = [row[0] for row in cursor.fetchall()]
clientes_multi = st.multiselect("Selecciona clientes para comparar:", clientes, default=clientes[:2])
if clientes_multi:
for cliente in clientes_multi:
cursor.execute('''
SELECT timestamp, sentiment_score
FROM conversations
WHERE customer_id = ?
ORDER BY timestamp
''', (cliente,))
datos = cursor.fetchall()
if datos:
fechas = [d['timestamp'][:10] for d in datos]
sentimientos = [d['sentiment_score'] for d in datos]
fig = go.Figure()
fig.add_trace(go.Scatter(x=fechas, y=sentimientos, mode='lines+markers', name=cliente))
fig.update_layout(title=f"Evolución de Sentimiento - {cliente}")
st.plotly_chart(fig, use_container_width=True)
conn.close()
# TAB 4: MCP TOOLS
with tab4:
st.subheader("🛠️ Herramientas MCP Disponibles")
tool_info = {
"analyze_sentiment_evolution": {
"desc": "Analiza si el sentimiento SUBE (RISING), BAJA (DECLINING) o se mantiene (STABLE)",
"uso": "Detecta tendencias para alertar sobre clientes en riesgo"
},
"detect_risk_signals": {
"desc": "Detecta palabras clave de riesgo en mensajes (cancelar, problema, insatisfecho)",
"uso": "Identifica inmediatamente problemas graves"
},
"predict_next_action": {
"desc": "Predice si el cliente hará CHURN, RESOLUTION o ESCALATION",
"uso": "Anticipa próximas acciones para intervenir"
},
"get_customer_history": {
"desc": "Obtiene perfil completo del cliente con historial",
"uso": "Análisis detallado para decisiones gerenciales"
},
"get_high_risk_customers": {
"desc": "Lista clientes por encima de threshold de riesgo",
"uso": "Priorizar intervención en clientes críticos"
},
"get_database_statistics": {
"desc": "Estadísticas globales del sistema",
"uso": "Dashboard ejecutivo de KPIs"
},
"save_analysis": {
"desc": "Guarda análisis manual de un cliente",
"uso": "Registro de decisiones y acciones tomadas"
}
}
for tool, info in tool_info.items():
with st.expander(f"📌 {tool}"):
st.write(f"**Descripción:** {info['desc']}")
st.write(f"**Uso:** {info['uso']}")
st.divider()
st.markdown("---")
st.markdown("""
**Sentiment Evolution Tracker v1.0**
Sistema MCP para monitoreo de satisfacción empresarial.
Desarrollado para Hugging Face MCP 1st Birthday Hackathon.
[📖 Docs](https://github.com/rubenreyes/mcp-nlp-server) | [🐙 GitHub](https://github.com) | [💬 Discord](https://discord.gg/huggingface)
""")