meta-ai-seo / app.py
cyberandy's picture
Update app.py
134d55e verified
raw
history blame
6.63 kB
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'<style>{f.read()}</style>', 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()