File size: 5,294 Bytes
d61f3de | 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 174 175 176 177 178 179 180 | """
Musora Sentiment Analysis Dashboard
Main Streamlit Application
Run with: streamlit run app.py
"""
import streamlit as st
import sys
from pathlib import Path
import json
# Add parent directory to path
parent_dir = Path(__file__).resolve().parent
sys.path.append(str(parent_dir))
from data.data_loader import SentimentDataLoader
from components.dashboard import render_dashboard
from components.sentiment_analysis import render_sentiment_analysis
from components.reply_required import render_reply_required
# Load configuration
config_path = parent_dir / "config" / "viz_config.json"
with open(config_path, 'r') as f:
config = json.load(f)
# Page configuration
st.set_page_config(
page_title=config['page_config']['page_title'],
page_icon=config['page_config']['page_icon'],
layout=config['page_config']['layout'],
initial_sidebar_state=config['page_config']['initial_sidebar_state']
)
def main():
"""
Main application function
"""
# Sidebar
with st.sidebar:
st.image("visualization/img/musora.png", use_container_width=True)
st.title("Navigation")
# Page selection
page = st.radio(
"Select Page",
["π Dashboard", "π Sentiment Analysis", "π¬ Reply Required"],
index=0
)
st.markdown("---")
# Filters section
st.markdown("### π Global Filters")
# Initialize session state for filters
if 'filters_applied' not in st.session_state:
st.session_state.filters_applied = False
# Load data first to get filter options
with st.spinner("Loading data..."):
data_loader = SentimentDataLoader()
df = data_loader.load_data()
if df.empty:
st.error("No data available. Please check your Snowflake connection.")
return
# Get filter options
filter_options = data_loader.get_filter_options(df)
# Platform filter
selected_platforms = st.multiselect(
"Platforms",
options=filter_options['platforms'],
default=[]
)
# Brand filter
selected_brands = st.multiselect(
"Brands",
options=filter_options['brands'],
default=[]
)
# Sentiment filter
selected_sentiments = st.multiselect(
"Sentiments",
options=filter_options['sentiments'],
default=[]
)
# Date range filter (if available)
if 'comment_timestamp' in df.columns and not df.empty:
min_date = df['comment_timestamp'].min().date()
max_date = df['comment_timestamp'].max().date()
date_range = st.date_input(
"Date Range",
value=(min_date, max_date),
min_value=min_date,
max_value=max_date
)
else:
date_range = None
# Apply filters button
if st.button("π Apply Filters", use_container_width=True):
st.session_state.filters_applied = True
# Reset filters button
if st.button("π Reset Filters", use_container_width=True):
st.session_state.filters_applied = False
st.rerun()
st.markdown("---")
# Data refresh
st.markdown("### π Data Management")
if st.button("β»οΈ Reload Data", use_container_width=True):
st.cache_data.clear()
st.rerun()
# Display data info
st.markdown("---")
st.markdown("### βΉοΈ Data Info")
st.info(f"**Total Records:** {len(df):,}")
if 'processed_at' in df.columns and not df.empty:
last_update = df['processed_at'].max()
st.info(f"**Last Updated:** {last_update.strftime('%Y-%m-%d %H:%M')}")
# Apply filters if needed
if st.session_state.filters_applied:
df = data_loader.apply_filters(
df,
platforms=selected_platforms if selected_platforms else None,
brands=selected_brands if selected_brands else None,
sentiments=selected_sentiments if selected_sentiments else None,
date_range=date_range if date_range and len(date_range) == 2 else None
)
# Show filter summary
if df.empty:
st.warning("No data matches the selected filters. Please adjust your filters.")
return
else:
st.info(f"Showing {len(df):,} records after applying filters")
# Main content area - render selected page
if page == "π Dashboard":
render_dashboard(df)
elif page == "π Sentiment Analysis":
render_sentiment_analysis(df)
elif page == "π¬ Reply Required":
render_reply_required(df)
# Footer
st.markdown("---")
st.markdown(
"""
<div style='text-align: center; color: gray; padding: 20px;'>
<p>Musora Sentiment Analysis Dashboard v1.0</p>
<p>Powered by Streamlit | Data from Snowflake</p>
</div>
""",
unsafe_allow_html=True
)
if __name__ == "__main__":
try:
main()
except Exception as e:
st.error(f"An error occurred: {str(e)}")
st.exception(e) |