import streamlit as st from meta_ai_api import MetaAI from urllib.parse import urlparse import pandas as pd import plotly.express as px from nltk.sentiment.vader import SentimentIntensityAnalyzer import nltk import json # Initialize Meta AI API ai = MetaAI() PAGE_CONFIG = { "page_title": "Meta AI Query Analysis - a Free SEO Tool by WordLift", "page_icon": "img/fav-ico.png", "layout": "centered" } def local_css(file_name): with open(file_name) as f: st.markdown(f'', unsafe_allow_html=True) st.set_page_config(**PAGE_CONFIG) local_css("style.css") def fetch_response(query): response = ai.prompt(message=query) return response def display_sources(sources): if sources: for source in sources: # Parse the domain from the URL domain = urlparse(source['link']).netloc # Format and display the domain and title st.markdown(f"- **{domain}**: [{source['title']}]({source['link']})", unsafe_allow_html=True) else: st.write("No sources available.") # ---------------------------------------------------------------------------- # # Sentiment Analysis Function # ---------------------------------------------------------------------------- # # Download the VADER lexicon for sentiment analysis nltk.download('vader_lexicon') # Initialize the Sentiment Intensity Analyzer sid = SentimentIntensityAnalyzer() def sentiment_analysis(text): # Split the text into sentences sentences = [sentence.strip() for sentence in text.split('.') if sentence] # Create a DataFrame to hold the content and sentiment scores df = pd.DataFrame(sentences, columns=['content']) # Calculate sentiment scores for each sentence df['sentiment_scores'] = df['content'].apply(lambda x: sid.polarity_scores(x)) # Split sentiment_scores into separate columns df = pd.concat([df.drop(['sentiment_scores'], axis=1), df['sentiment_scores'].apply(pd.Series)], axis=1) # Determine the dominant sentiment and its confidence df['dominant_sentiment'] = df[['neg', 'neu', 'pos']].idxmax(axis=1) df['confidence'] = df[['neg', 'neu', 'pos']].max(axis=1) return df # ---------------------------------------------------------------------------- # # Advanced Analysis # ---------------------------------------------------------------------------- # def advanced_analysis(query, response_message): analysis_prompt = f"Analyze the question of the user '{query}', analyze the response '{response_message}' and provide a JSON that includes: the user's intent, up to four follow-up questions, the entities in the response." analysis_response = ai.prompt(message=analysis_prompt) return analysis_response def parse_analysis(analysis_message): try: # Check if the expected delimiter 'Here is the JSON:' is present if 'JSON:\n' in analysis_message: json_str = analysis_message.split('JSON:\n')[1].strip() analysis_data = json.loads(json_str) return analysis_data else: # If the delimiter is not found, return a default error message or handle it return {"error": "JSON delimiter not found in response"} except json.JSONDecodeError as e: # Handle cases where JSON decoding fails return {"error": "Failed to decode JSON", "details": str(e)} # ---------------------------------------------------------------------------- # # Main Function # ---------------------------------------------------------------------------- # def main(): # Path to the image image_path = 'img/meta-ai-logo.png' # Replace with your image's filename and extension # Create two columns col1, col2 = st.columns([1, 2]) # Adjust the ratio as needed for your layout # Use the first column to display the image with col1: st.image(image_path, width=60) # Use the second column to display the title and other content with col2: st.title("Meta AI SEO Tool") # User input user_query = st.text_area("Enter your query:", height=150) submit_button = st.button("Analyze Query") if submit_button and user_query: # Fetching response from Meta AI response = fetch_response(user_query) msg = response.get('message', 'No response message.') # Write response st.write(msg) # Run sentiment analysis df_sentiment = sentiment_analysis(msg) # Advanced analysis with second AI call advanced_response = advanced_analysis(user_query, msg) advanced_msg = advanced_response.get('message', 'No advanced analysis available.') # Parse the advanced analysis response analysis_data = parse_analysis(advanced_msg) if "error" in analysis_data: st.error("Error in analysis: " + analysis_data["error"]) if "details" in analysis_data: st.error("Details: " + analysis_data["details"]) else: # Display parsed data in a collapsible section with st.expander("Show Advanced Analysis"): st.write("### User Intent") st.write(analysis_data['user_intent']) st.write("### Follow-up Questions") for question in analysis_data['follow_up_questions']: st.write("- " + question) st.write("### Identified Entities") for entity_type, entities in analysis_data['entities'].items(): st.write(f"**{entity_type.capitalize()}**: {', '.join(entities)}") # Display the sentiment in a collapsible section with st.expander("Show Sentiment"): # Display negative sentence locations fig = px.scatter(df_sentiment, y='dominant_sentiment', color='dominant_sentiment', size='confidence', hover_data=['content'], color_discrete_map={"neg": "firebrick", "neu": "navajowhite", "pos": "darkgreen"}, labels={'dominant_sentiment': 'Sentiment'}, title='Sentiment Analysis of the Response') fig.update_layout(width=800, height=300) st.plotly_chart(fig) # Display the AI response in a collapsible section with st.expander("Show Sources"): # Display sources with clickable links in a collapsible section display_sources(response.get('sources', [])) if __name__ == "__main__": main()