Spaces:
Sleeping
Sleeping
| """ | |
| Main application file for the Emoji Mashup app. | |
| This module handles the Gradio interface and application setup. | |
| """ | |
| import gradio as gr | |
| from utils import logger | |
| from emoji_processor import EmojiProcessor | |
| from config import EMBEDDING_MODELS | |
| import random | |
| import os | |
| class EmojiMashupApp: | |
| def __init__(self): | |
| """Initialize the Gradio application.""" | |
| logger.info("Initializing Emoji Mashup App") | |
| self.processor = EmojiProcessor(model_key="mpnet", use_cached_embeddings=True) # Default to mpnet | |
| self.processor.load_emoji_dictionaries() | |
| # Store all example sentences for the random picker | |
| self.all_examples = [] | |
| def create_model_dropdown_choices(self): | |
| """Create formatted choices for the model dropdown. | |
| Returns: | |
| List of formatted model choices | |
| """ | |
| return [ | |
| f"{key} ({info['size']}) - {info['notes']}" | |
| for key, info in EMBEDDING_MODELS.items() | |
| ] | |
| def handle_model_change(self, dropdown_value, use_cached_embeddings): | |
| """Handle model selection change from dropdown. | |
| Args: | |
| dropdown_value: Selected value from dropdown | |
| use_cached_embeddings: Whether to use cached embeddings | |
| Returns: | |
| Status message about model change | |
| """ | |
| # Extract model key from dropdown value (first word before space) | |
| model_key = dropdown_value.split()[0] if dropdown_value else "mpnet" | |
| # Update processor cache setting | |
| self.processor.use_cached_embeddings = use_cached_embeddings | |
| if model_key in EMBEDDING_MODELS: | |
| success = self.processor.switch_model(model_key) | |
| if success: | |
| cache_status = "using cached embeddings" if use_cached_embeddings else "computing fresh embeddings" | |
| return f"Switched to {model_key} model ({cache_status}): {EMBEDDING_MODELS[model_key]['notes']}" | |
| else: | |
| return f"Failed to switch to {model_key} model" | |
| else: | |
| return f"Unknown model: {model_key}" | |
| def get_random_example(self): | |
| """Get a random example from the collected examples. | |
| Returns: | |
| A randomly selected example sentence | |
| """ | |
| if not self.all_examples: | |
| # Return a default message if no examples are available | |
| return "I feel so happy and excited today!" | |
| return random.choice(self.all_examples) | |
| def process_with_model(self, model_selection, text, use_cached_embeddings): | |
| """Process text with selected model. | |
| Args: | |
| model_selection: Selected model from dropdown | |
| text: User input text | |
| use_cached_embeddings: Whether to use cached embeddings | |
| Returns: | |
| Tuple of (emotion emoji, event emoji, mashup image) | |
| """ | |
| # Extract model key from dropdown value (first word before space) | |
| model_key = model_selection.split()[0] if model_selection else "mpnet" | |
| # Update processor cache setting | |
| self.processor.use_cached_embeddings = use_cached_embeddings | |
| if model_key in EMBEDDING_MODELS: | |
| self.processor.switch_model(model_key) | |
| # Process text with current model | |
| return self.processor.sentence_to_emojis(text) | |
| def create_interface(self): | |
| """Create and configure the Gradio interface. | |
| Returns: | |
| Gradio Interface object | |
| """ | |
| # Define all example sentences | |
| primary_examples = [ | |
| "I feel so happy and excited today!", | |
| "I'm feeling really sad and down right now", | |
| "I completely trust my best friend with my life", | |
| "That smells absolutely disgusting and makes me nauseous", | |
| "I'm terrified of what might happen next", | |
| "I'm furious about how they treated me yesterday", | |
| "Wow! I can't believe what just happened - totally unexpected!", | |
| "I'm eagerly waiting to see what happens next" | |
| ] | |
| secondary_examples = [ | |
| "I deeply love and adore my family more than anything", | |
| "I respect their authority and will follow their instructions", | |
| "I'm in awe of the magnificent view from the summit", | |
| "I'm disappointed by the unexpected poor quality of work", | |
| "I feel so guilty and ashamed about what I did", | |
| "I have nothing but contempt for their dishonest behavior", | |
| "I'm determined to confront them about this issue", | |
| "I'm optimistic and hopeful about what the future holds" | |
| ] | |
| tertiary_examples = [ | |
| "I'm feeling anxious about my upcoming presentation", | |
| "I'm hopeful that everything will work out in the end", | |
| "I felt jealous when I saw them together laughing", | |
| "Looking at old photos makes me feel nostalgic and sentimental", | |
| "I'm in complete despair and see no way out of this situation", | |
| "I'm so embarrassed and ashamed of my behavior yesterday", | |
| "I have a strange fascination with creepy abandoned buildings", | |
| "I was absolutely delighted by the unexpected gift" | |
| ] | |
| # Store all examples for the random picker | |
| self.all_examples = primary_examples + secondary_examples + tertiary_examples | |
| with gr.Blocks(title="Sentence → Emoji Mashup") as interface: | |
| gr.Markdown("# Sentence → Emoji Mashup") | |
| gr.Markdown("Get the top emotion and event emoji from your sentence, and view the mashup!") | |
| with gr.Row(): | |
| with gr.Column(scale=3): | |
| # Model selection dropdown | |
| model_dropdown = gr.Dropdown( | |
| choices=self.create_model_dropdown_choices(), | |
| value=self.create_model_dropdown_choices()[0], # Default to first model (mpnet) | |
| label="Embedding Model", | |
| info="Select the model used for text-emoji matching" | |
| ) | |
| # Cache toggle | |
| cache_toggle = gr.Checkbox( | |
| label="Use cached embeddings", | |
| value=True, | |
| info="When enabled, embeddings will be saved to and loaded from disk" | |
| ) | |
| # Text input with random example button | |
| with gr.Row(): | |
| text_input = gr.Textbox( | |
| lines=2, | |
| placeholder="Type a sentence...", | |
| label="Your message", | |
| scale=9 | |
| ) | |
| random_btn = gr.Button("🎲 Random", scale=1, min_width=40, size="sm", variant="secondary") | |
| # Process button | |
| submit_btn = gr.Button("Generate Emoji Mashup", variant="primary") | |
| with gr.Column(scale=2): | |
| # Model info display | |
| model_info = gr.Textbox( | |
| value=f"Using mpnet model (using cached embeddings): {EMBEDDING_MODELS['mpnet']['notes']}", | |
| label="Model Info", | |
| interactive=False | |
| ) | |
| # Output displays | |
| emotion_out = gr.Text(label="Top Emotion Emoji") | |
| event_out = gr.Text(label="Top Event Emoji") | |
| mashup_out = gr.Image(label="Mashup Emoji") | |
| # Share button and result message | |
| share_btn = gr.Button("Copy Link to Clipboard", variant="secondary", visible=False) | |
| share_result = gr.Textbox(visible=False, label="Share Status") | |
| # Set up event handlers | |
| model_dropdown.change( | |
| fn=self.handle_model_change, | |
| inputs=[model_dropdown, cache_toggle], | |
| outputs=[model_info] | |
| ) | |
| cache_toggle.change( | |
| fn=self.handle_model_change, | |
| inputs=[model_dropdown, cache_toggle], | |
| outputs=[model_info] | |
| ) | |
| # Random example button handler | |
| random_btn.click( | |
| fn=self.get_random_example, | |
| inputs=None, | |
| outputs=text_input | |
| ) | |
| # Process button handler with share button visibility update | |
| def process_and_show_share(model_selection, text, use_cached_embeddings): | |
| result = self.process_with_model(model_selection, text, use_cached_embeddings) | |
| # Make share button visible after generating result | |
| return result[0], result[1], result[2], True, False | |
| submit_btn.click( | |
| fn=process_and_show_share, | |
| inputs=[model_dropdown, text_input, cache_toggle], | |
| outputs=[emotion_out, event_out, mashup_out, share_btn, share_result] | |
| ) | |
| # Simple share button handler - just show a message | |
| def show_share_message(): | |
| return True, "Link copied! Share this page's URL with others to show your result." | |
| share_btn.click( | |
| fn=show_share_message, | |
| inputs=None, | |
| outputs=[share_result, share_result] | |
| ) | |
| # Examples section - using Tabs instead of Accordion to ensure visibility | |
| gr.Markdown("## Emotion Examples") | |
| gr.Markdown("Try these examples based on Plutchik's Wheel of Emotions:") | |
| with gr.Tabs() as tabs: | |
| with gr.TabItem("Primary Emotions"): | |
| gr.Examples( | |
| examples=[[example] for example in primary_examples], | |
| inputs=text_input | |
| ) | |
| with gr.TabItem("Secondary Emotions"): | |
| gr.Examples( | |
| examples=[[example] for example in secondary_examples], | |
| inputs=text_input | |
| ) | |
| with gr.TabItem("Tertiary Emotions"): | |
| gr.Examples( | |
| examples=[[example] for example in tertiary_examples], | |
| inputs=text_input | |
| ) | |
| return interface | |
| def run(self, share=True): | |
| """Launch the Gradio application. | |
| Args: | |
| share: Whether to create a public sharing link | |
| """ | |
| logger.info("Starting Emoji Mashup App") | |
| interface = self.create_interface() | |
| # Check if running on Hugging Face Spaces | |
| is_on_spaces = os.environ.get("SPACE_ID") is not None | |
| # If on Spaces, never use share=True | |
| if is_on_spaces: | |
| # When on Spaces, don't use share parameter at all | |
| interface.launch() | |
| else: | |
| # When running locally, default to share=True unless explicitly set | |
| if share is None: | |
| share = True | |
| interface.launch(share=share) | |
| # Main entry point | |
| if __name__ == "__main__": | |
| app = EmojiMashupApp() | |
| app.run() |