Spaces:
Running
Running
| 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(""" | |
| <div class="main-header"> | |
| π― AI Sentiment Analyzer | |
| </div> | |
| <div class="subtitle"> | |
| Advanced sentiment analysis powered by TextBlob NLP | |
| </div> | |
| """) | |
| 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) |