Spaces:
Sleeping
Sleeping
| # app.py | |
| import os | |
| import streamlit as st | |
| from dotenv import load_dotenv | |
| from agents import create_research_crew | |
| from utils import format_json_output, update_progress | |
| from styles import main_styles | |
| # Load environment variables | |
| load_dotenv() | |
| # Streamlit server configuration for Hugging Face Spaces | |
| st.set_page_config( | |
| page_title="Market Research Generator", | |
| page_icon="๐", | |
| layout="wide", | |
| initial_sidebar_state="expanded", | |
| menu_items={ | |
| 'Get Help': 'https://www.huggingface.co', | |
| 'Report a bug': "https://www.huggingface.co", | |
| 'About': "Market Research Report Generator using AI" | |
| } | |
| ) | |
| # Set the server to allow external connections | |
| from streamlit.web.server.server import Server | |
| Server.address = "0.0.0.0" | |
| # Add styles | |
| st.markdown(main_styles, unsafe_allow_html=True) | |
| def get_api_keys(): | |
| """Get API keys from environment or Hugging Face Secrets""" | |
| try: | |
| serper_key = os.environ.get('SERPER_API_KEY') | |
| openai_key = os.environ.get('OPENAI_API_KEY') | |
| print("API Keys loaded successfully") | |
| return serper_key, openai_key | |
| except Exception as e: | |
| st.error(f"Error loading API keys: {str(e)}") | |
| return None, None | |
| def parse_section_content(content, section_marker): | |
| """Parse content between section markers""" | |
| if section_marker in content: | |
| start = content.find(section_marker) + len(section_marker) | |
| next_marker = content.find('###', start) | |
| if next_marker != -1: | |
| return content[start:next_marker].strip() | |
| return content[start:].strip() | |
| return "" | |
| def run_market_research(topic: str, progress_container): | |
| """Run the market research process""" | |
| try: | |
| # Create and run the crew | |
| crew = create_research_crew(topic) | |
| # Update progress | |
| update_progress(progress_container, 25, "Gathering market data...") | |
| st.write("๐ Research Analyst is gathering market data...") | |
| update_progress(progress_container, 50, "Analyzing findings...") | |
| st.write("๐ Data Analyst is processing insights...") | |
| update_progress(progress_container, 75, "Generating report...") | |
| st.write("โ๏ธ Report Writer is creating the document...") | |
| # Execute the crew and get result | |
| result = crew.kickoff() | |
| # Get raw text from result | |
| if hasattr(result, 'raw_output'): | |
| raw_text = str(result.raw_output) | |
| else: | |
| raw_text = str(result) | |
| # Split into main sections | |
| sections = {} | |
| current_section = "" | |
| current_content = [] | |
| for line in raw_text.split('\n'): | |
| if line.strip().startswith('==='): | |
| if current_section: | |
| sections[current_section] = '\n'.join(current_content) | |
| current_section = line.strip().replace('===', '').strip() | |
| current_content = [] | |
| else: | |
| current_content.append(line) | |
| if current_section and current_content: | |
| sections[current_section] = '\n'.join(current_content) | |
| # Process Executive Summary | |
| exec_summary = sections.get('EXECUTIVE SUMMARY', '') | |
| exec_summary_parts = { | |
| 'summary': parse_section_content(exec_summary, 'EXECUTIVE SUMMARY'), | |
| 'market_highlights': parse_section_content(exec_summary, '### Key Market Findings'), | |
| 'strategic_implications': parse_section_content(exec_summary, '### Strategic Implications'), | |
| 'recommendations': parse_section_content(exec_summary, '### Recommendations') | |
| } | |
| # Process Market Analysis | |
| market_analysis = sections.get('MARKET ANALYSIS', '') | |
| market_analysis_parts = { | |
| 'overview': parse_section_content(market_analysis, '### Market Overview'), | |
| 'dynamics': parse_section_content(market_analysis, '### Industry Dynamics'), | |
| 'competitive_landscape': parse_section_content(market_analysis, '### Competitive Landscape'), | |
| 'strategic_analysis': parse_section_content(market_analysis, '### Strategic Analysis') | |
| } | |
| # Process Sources | |
| sources_section = sections.get('SOURCES', '') | |
| sources = [ | |
| line.strip()[2:] for line in sources_section.split('\n') | |
| if line.strip().startswith('-') | |
| ] | |
| # Create final report structure | |
| processed_report = { | |
| 'exec_summary': exec_summary_parts, | |
| 'market_analysis': market_analysis_parts, | |
| 'future_outlook': sections.get('FUTURE OUTLOOK', ''), | |
| 'sources': sources | |
| } | |
| # Debug: Print sections found | |
| print("Sections found:", list(sections.keys())) | |
| print("Market Analysis sections:", list(market_analysis_parts.keys())) | |
| update_progress(progress_container, 100, "Report completed!") | |
| return processed_report | |
| except Exception as e: | |
| st.error(f"Error during research: {str(e)}") | |
| print(f"Full error details: {str(e)}") # For debugging | |
| return None | |
| def main(): | |
| st.title("๐ค AI Market Research Generator") | |
| # Get API keys | |
| serper_key, openai_key = get_api_keys() | |
| if not serper_key or not openai_key: | |
| st.error("Failed to load required API keys. Please check your Hugging Face Space secrets.") | |
| return | |
| # Initialize session states | |
| if 'generating' not in st.session_state: | |
| st.session_state.generating = False | |
| # Create tabs | |
| tab1, tab2 = st.tabs(["Generate Report", "View Reports"]) | |
| with tab1: | |
| st.subheader("Enter Research Topic") | |
| topic = st.text_input( | |
| "What market would you like to research?", | |
| placeholder="e.g., Electric Vehicles Market" | |
| ) | |
| if st.session_state.generating: | |
| st.button("Generating Report...", disabled=True) | |
| else: | |
| if st.button("Generate Report", type="primary"): | |
| if not topic: | |
| st.error("Please enter a research topic") | |
| else: | |
| st.session_state.generating = True | |
| # Create progress container | |
| progress_container = st.container() | |
| try: | |
| with st.spinner("Generating comprehensive market research report..."): | |
| result = run_market_research(topic, progress_container) | |
| if result: | |
| st.session_state.current_report = result | |
| st.session_state.current_topic = topic | |
| st.success("Report generated successfully! View it in the Reports tab.") | |
| except Exception as e: | |
| st.error(f"Error generating report: {str(e)}") | |
| finally: | |
| st.session_state.generating = False | |
| with tab2: | |
| if 'current_report' in st.session_state: | |
| try: | |
| report = st.session_state.current_report | |
| topic = st.session_state.current_topic | |
| # Display AI Disclaimer | |
| st.warning("โ ๏ธ This report was generated using AI. While we strive for accuracy, please verify critical information independently.") | |
| # Report Title | |
| st.title(f"๐ Market Research Report: {topic}") | |
| # Executive Summary Section | |
| st.header("Executive Summary") | |
| if report['exec_summary']['summary']: | |
| st.markdown(report['exec_summary']['summary']) | |
| # Key Findings and Implications | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| with st.expander("Key Market Findings", expanded=True): | |
| st.markdown(report['exec_summary']['market_highlights']) | |
| with st.expander("Strategic Implications", expanded=True): | |
| st.markdown(report['exec_summary']['strategic_implications']) | |
| with col2: | |
| with st.expander("Recommendations", expanded=True): | |
| st.markdown(report['exec_summary']['recommendations']) | |
| # Market Analysis Section | |
| st.header("Market Analysis") | |
| # Market Analysis Tabs | |
| market_tabs = st.tabs([ | |
| "Market Overview", | |
| "Industry Dynamics", | |
| "Competitive Landscape", | |
| "Strategic Analysis" | |
| ]) | |
| with market_tabs[0]: | |
| st.markdown(report['market_analysis']['overview']) | |
| with market_tabs[1]: | |
| st.markdown(report['market_analysis']['dynamics']) | |
| with market_tabs[2]: | |
| st.markdown(report['market_analysis']['competitive_landscape']) | |
| with market_tabs[3]: | |
| st.markdown(report['market_analysis']['strategic_analysis']) | |
| # Future Outlook | |
| st.header("Future Outlook") | |
| st.markdown(report['future_outlook']) | |
| # Sources | |
| if report['sources']: | |
| st.header("Sources") | |
| for source in report['sources']: | |
| st.markdown(f"โข {source}") | |
| # Download Report | |
| st.download_button( | |
| label="๐ฅ Download Complete Report", | |
| data=f"""# Market Research Report: {topic} | |
| ## Executive Summary | |
| {report['exec_summary']['summary']} | |
| ### Key Market Findings | |
| {report['exec_summary']['market_highlights']} | |
| ### Strategic Implications | |
| {report['exec_summary']['strategic_implications']} | |
| ### Recommendations | |
| {report['exec_summary']['recommendations']} | |
| ## Market Analysis | |
| ### Market Overview | |
| {report['market_analysis']['overview']} | |
| ### Industry Dynamics | |
| {report['market_analysis']['dynamics']} | |
| ### Competitive Landscape | |
| {report['market_analysis']['competitive_landscape']} | |
| ### Strategic Analysis | |
| {report['market_analysis']['strategic_analysis']} | |
| ## Future Outlook | |
| {report['future_outlook']} | |
| ## Sources | |
| {chr(10).join([f"โข {source}" for source in report['sources']])}""", | |
| file_name=f"{topic.lower().replace(' ', '_')}_market_research.md", | |
| mime="text/markdown" | |
| ) | |
| except Exception as e: | |
| st.error(f"Error displaying report: {str(e)}") | |
| st.write("Raw report data:", report) # Debug information | |
| if __name__ == "__main__": | |
| main() |