Download visualization/app.py from MusoraProductDepartment/brand_sentiment_analysis: direct link, hf CLI and curl.
- Browser
- Download file 5.29 kB
-
https://huggingface.co/spaces/MusoraProductDepartment/brand_sentiment_analysis/resolve/main/visualization/app.py
- Command line
-
hf download hf://spaces/MusoraProductDepartment/brand_sentiment_analysis/visualization/app.py
-
curl -L -o app.py https://huggingface.co/spaces/MusoraProductDepartment/brand_sentiment_analysis/resolve/main/visualization/app.py
5.29 kB
| """ | |
| 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) |