Danialebrat's picture
Adding files
d61f3de
"""
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)