import json import gradio as gr from textblob import TextBlob import os def sentiment_analysis(text: str) -> dict: """ Analyze the sentiment of the given text. Simplified version for Hugging Face Spaces. """ if not text or not text.strip(): return { "error": "Please enter some text to analyze", "polarity": 0, "subjectivity": 0, "assessment": "neutral", "confidence": "low" } try: blob = TextBlob(text) sentiment = blob.sentiment # Calculate confidence based on polarity strength polarity_abs = abs(sentiment.polarity) if polarity_abs >= 0.7: confidence = "high" elif polarity_abs >= 0.3: confidence = "medium" else: confidence = "low" # More nuanced assessment if sentiment.polarity > 0.1: assessment = "positive" elif sentiment.polarity < -0.1: assessment = "negative" else: assessment = "neutral" result = { "polarity": round(sentiment.polarity, 3), "subjectivity": round(sentiment.subjectivity, 3), "assessment": assessment, "confidence": confidence, "word_count": len(text.split()), "character_count": len(text), "text_preview": text[:100] + "..." if len(text) > 100 else text } return result except Exception as e: return { "error": f"Analysis failed: {str(e)}", "polarity": 0, "subjectivity": 0, "assessment": "error", "confidence": "low" } def format_results(result: dict) -> str: """Format the analysis results for better display.""" if "error" in result: return f"❌ **Error:** {result['error']}" # Emoji mapping for sentiment emoji_map = { "positive": "😊", "negative": "😞", "neutral": "😐", "error": "❌" } # Color coding for polarity polarity = result["polarity"] if polarity > 0: polarity_color = "🟢" polarity_desc = "Positive" elif polarity < 0: polarity_color = "🔴" polarity_desc = "Negative" else: polarity_color = "🟡" polarity_desc = "Neutral" # Confidence indicators confidence_icons = { "high": "🔥", "medium": "⚡", "low": "💫" } formatted = f""" ## 📊 Sentiment Analysis Results ### {emoji_map[result['assessment']]} Overall Assessment: **{result['assessment'].title()}** ### 📈 Detailed Metrics: - **Polarity:** {polarity_color} **{result['polarity']}** ({polarity_desc}) - Range: -1.0 (very negative) to +1.0 (very positive) - **Subjectivity:** 🎯 **{result['subjectivity']}** - Range: 0.0 (objective) to 1.0 (subjective) - **Confidence:** {confidence_icons.get(result['confidence'], '❓')} **{result['confidence'].title()}** ### 📝 Text Statistics: - **Words:** {result['word_count']} - **Characters:** {result['character_count']} - **Preview:** "{result.get('text_preview', 'N/A')}" ### 💡 Interpretation: - **Polarity** measures emotional tone from negative to positive - **Subjectivity** measures opinion vs factual content - **Confidence** indicates strength of sentiment signal --- *🔗 Powered by TextBlob NLP • Ready for MCP integration* """ return formatted def analyze_with_formatting(text: str) -> str: """Wrapper function that combines analysis and formatting.""" result = sentiment_analysis(text) return format_results(result) def batch_analyze_simple(texts_input: str) -> str: """Simple batch analysis for multiple texts.""" if not texts_input.strip(): return "❌ Please enter some texts, one per line." texts = [line.strip() for line in texts_input.split('\n') if line.strip()] if not texts: return "❌ No valid texts found." results = [] positive_count = 0 negative_count = 0 neutral_count = 0 total_polarity = 0 for i, text in enumerate(texts, 1): result = sentiment_analysis(text) if "error" not in result: assessment = result["assessment"] if assessment == "positive": positive_count += 1 elif assessment == "negative": negative_count += 1 else: neutral_count += 1 total_polarity += result["polarity"] results.append(f"**Text {i}:** {result['assessment']} ({result['polarity']}) - \"{result['text_preview']}\"") else: results.append(f"**Text {i}:** Error - {result['error']}") avg_polarity = total_polarity / len(texts) if texts else 0 summary = f""" ## 📊 Batch Analysis Results ### 📈 Summary Statistics: - **Total Texts:** {len(texts)} - **Average Polarity:** {round(avg_polarity, 3)} - **Positive:** {positive_count} ({round(positive_count/len(texts)*100, 1)}%) - **Negative:** {negative_count} ({round(negative_count/len(texts)*100, 1)}%) - **Neutral:** {neutral_count} ({round(neutral_count/len(texts)*100, 1)}%) ### 📋 Individual Results: {chr(10).join(results)} """ return summary # Sample texts for quick testing sample_texts = [ "I absolutely love this product! It's amazing and works perfectly.", "This is the worst experience I've ever had. Completely disappointed.", "The weather today is partly cloudy with a chance of rain.", "I'm not sure how I feel about this new update. It has some good features but also some issues.", "Artificial intelligence is transforming various industries including healthcare, finance, and transportation." ] # Create the Gradio interface with gr.Blocks( theme=gr.themes.Soft(), title="🎯 Sentiment Analyzer", css=""" .gradio-container { max-width: 1200px !important; margin: auto !important; } .main-header { text-align: center; background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-size: 2.5em; font-weight: bold; margin-bottom: 20px; } .subtitle { text-align: center; color: #666; font-size: 1.2em; margin-bottom: 30px; } """ ) as demo: gr.HTML("""
🎯 AI Sentiment Analyzer
Advanced sentiment analysis powered by TextBlob NLP
""") with gr.Tabs(): with gr.Tab("🔍 Single Analysis"): with gr.Row(): with gr.Column(scale=1): gr.Markdown("### 📝 Enter Your Text") text_input = gr.Textbox( placeholder="Type or paste your text here for sentiment analysis...", lines=6, max_lines=15, label="Text to Analyze", info="💡 Tip: Longer texts generally provide more accurate sentiment analysis" ) with gr.Row(): analyze_btn = gr.Button("🔍 Analyze Sentiment", variant="primary", size="lg") clear_btn = gr.Button("🗑️ Clear", variant="secondary", size="lg") gr.Markdown("### 🎯 Try Quick Examples") examples_dropdown = gr.Dropdown( choices=sample_texts, label="Select a sample text to analyze", value=None, interactive=True ) with gr.Column(scale=1): gr.Markdown("### 📊 Analysis Results") output = gr.Markdown( value="👋 **Welcome!** Enter some text and click 'Analyze Sentiment' to get started with AI-powered sentiment analysis.", label="Sentiment Analysis Output" ) with gr.Tab("📊 Batch Analysis"): gr.Markdown("### 📝 Analyze Multiple Texts") batch_input = gr.Textbox( placeholder="Enter multiple texts, one per line...\n\nExample:\nI love this product!\nThis is terrible.\nThe weather is nice today.", lines=8, label="Multiple Texts (one per line)", info="Enter each text on a separate line for batch analysis" ) batch_btn = gr.Button("📊 Analyze All", variant="primary", size="lg") batch_output = gr.Markdown( value="👋 Enter multiple texts above and click 'Analyze All' to get batch sentiment analysis.", label="Batch Analysis Results" ) # Additional info section with gr.Row(): with gr.Column(): gr.Markdown(""" ### 🔍 About This Tool This **AI-powered sentiment analyzer** uses advanced Natural Language Processing to determine: - **Emotional tone** (positive, negative, neutral) - **Subjectivity level** (opinion vs fact) - **Confidence scores** based on signal strength Perfect for analyzing: - 📝 Customer reviews and feedback - 📱 Social media posts and comments - 📧 Email and message sentiment - 📊 Survey responses and testimonials - 📈 Product feedback and ratings **Features:** - Real-time sentiment analysis - Batch processing for multiple texts - Detailed confidence metrics - User-friendly interface """) # Event handlers for Single Analysis analyze_btn.click( fn=analyze_with_formatting, inputs=text_input, outputs=output ) clear_btn.click( fn=lambda: ("", "👋 **Welcome!** Enter some text and click 'Analyze Sentiment' to get started."), outputs=[text_input, output] ) examples_dropdown.change( fn=lambda x: x if x else "", inputs=examples_dropdown, outputs=text_input ) text_input.submit( fn=analyze_with_formatting, inputs=text_input, outputs=output ) # Event handlers for Batch Analysis batch_btn.click( fn=batch_analyze_simple, inputs=batch_input, outputs=batch_output ) # Simple launch for Hugging Face Spaces if __name__ == "__main__": print("🚀 Starting Sentiment Analyzer for Hugging Face Spaces...") demo.launch(mcp_server=True)