Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import re | |
| import random | |
| import json | |
| from dotenv import load_dotenv | |
| import os | |
| from openai import OpenAI | |
| import tiktoken | |
| # 🔐 Load API Key from .env | |
| load_dotenv() | |
| api_key = os.getenv("OPENAI_API_KEY") | |
| client = OpenAI(api_key=api_key) | |
| # 1) Load your product catalog once at startup | |
| def load_product_catalog(path="products.json"): | |
| with open(path, "r", encoding="utf-8") as f: | |
| data = json.load(f) | |
| # Expecting products_desc to be a dict: { "iboothme X": "…", … } | |
| return data["products_desc"] | |
| PRODUCT_CATALOG = load_product_catalog() | |
| def count_tokens(text: str, model: str = "gpt-4") -> int: | |
| try: | |
| encoding = tiktoken.encoding_for_model(model) | |
| except KeyError: | |
| encoding = tiktoken.get_encoding("cl100k_base") | |
| return len(encoding.encode(text)) | |
| # 2) Helper to pull full descriptions for a list of product names | |
| def get_product_descriptions(product_names: list[str]) -> str: | |
| entries = [] | |
| for name in product_names: | |
| desc = PRODUCT_CATALOG.get(name) | |
| if desc: | |
| entries.append(f"**{name}**\n{desc}") | |
| return "\n\n".join(entries) | |
| # Keyword extraction from the paragraph | |
| def extract_keywords(paragraph: str) -> list[str]: | |
| prompt = f""" | |
| You are an expert in experiential event planning. | |
| Extract 5-10 short, specific, and thematic keywords or concepts from the event description below. These will be used to inspire immersive, tech-powered event ideas. | |
| Each keyword should be 2-4 words long and describe a concrete idea or theme (e.g., "photo booths", "smart vending", "interactive storytelling"). | |
| Event Description: | |
| \"{paragraph}\" | |
| Return the keywords as a comma-separated list. | |
| """ | |
| response = client.chat.completions.create( | |
| model="gpt-4", | |
| messages=[{"role": "user", "content": prompt}], | |
| temperature=0.7, | |
| max_tokens=200 | |
| ) | |
| raw = response.choices[0].message.content | |
| return [kw.strip().lower() for kw in re.split(r'[,\n]', raw) if kw.strip()] | |
| # (Optional) Keyword extraction from titles/links | |
| def extract_keywords_from_title_and_link(title: str, link: str) -> list[str]: | |
| prompt = f""" | |
| You are an expert in event innovation. | |
| Given the title and link below, extract 3-5 short, specific, and meaningful keywords or themes (2-4 words each) that describe what the page is about. | |
| Title: {title} | |
| Link: {link} | |
| Return the keywords as a comma-separated list. | |
| """ | |
| response = client.chat.completions.create( | |
| model="gpt-4", | |
| messages=[{"role": "user", "content": prompt}], | |
| temperature=0.6, | |
| max_tokens=150 | |
| ) | |
| raw = response.choices[0].message.content | |
| return [kw.strip().lower() for kw in re.split(r'[,\n]', raw) if kw.strip()] | |
| # (Optional) Web search for inspiration | |
| def search_similar_events_and_products_openai(keywords: list[str]) -> list[tuple[str,str]]: | |
| input_text = f"Generate 10 useful URLs for experiential event ideas or iboothme.com inspiration related to the keywords: {', '.join(keywords)}" | |
| try: | |
| response = client.responses.create( | |
| model="gpt-4.1", | |
| tools=[{"type": "web_search_preview"}], | |
| input=input_text | |
| ) | |
| content = response.output_text | |
| results = [] | |
| for line in content.split("\n"): | |
| if "http" in line: | |
| parts = line.split(" - ", 1) | |
| if len(parts) == 2: | |
| results.append((parts[0].strip(), parts[1].strip())) | |
| else: | |
| url = line.strip() | |
| results.append((url, url)) | |
| return results[:10] | |
| except Exception as e: | |
| print("Search failed:", e) | |
| return [] | |
| # Core idea generation, enriched with random product descriptions | |
| def generate_event_ideas( | |
| paragraph: str, | |
| product_info: str, | |
| search_links: list[tuple[str,str]], | |
| all_keywords: list[str], | |
| idea_count: int | |
| ) -> str: | |
| search_summary = "\n".join([f"- {title}: {url}" for title, url in search_links]) | |
| include_games = any("game" in kw for kw in all_keywords) | |
| game_instruction = "Include at least two game-related ideas (e.g., quiz game, vending challenge)." if include_games else "" | |
| examples = """ | |
| Carefully analyze these examples to understand the kind of events iboothme typically does. Use this knowledge to shape your new ideas accordingly. | |
| 1. **Pedal-Powered Smoothie Activation (Philips)** | |
| Guests cycle to virtually blend a smoothie. Once the digital blending completes, a real smoothie or branded item is dispensed. | |
| 2. **Interactive Foosball with Smart Tech** | |
| Classic foosball is enhanced with real-time goal sensors, AI commentary, lighting, and fog effects for an immersive, competitive experience. | |
| 3. **Mystery Phone Giftbox Game** | |
| A phone booth randomly rings. The first guest to answer receives a code to try and unlock a branded giftbox prize. | |
| 4. **Autotune Karaoke Booth** | |
| Guests sing karaoke; the system auto-enhances their voice and records a fun branded music video for sharing. | |
| 5. **Precision Ball Challenge** | |
| Guests score points by throwing balls into different-sized holes—smaller holes yield more points. A live leaderboard adds to the excitement. | |
| 6. **Virtual Product Customization (Nike)** | |
| Kids scan a QR code, customize virtual products (like shoes or gear), and submit details to be notified when it's ready—blending gamification and CRM. | |
| 7. **Digital Ramadan or Eid Games** | |
| Gamified web-based experiences that celebrate festive moments (e.g., quiz vending machines, dua generators, or memory games with prizes). | |
| 8. **Gamified Vending (Virgin, Makeup For Ever)** | |
| Guests activate vending machines via QR code or interactive game. Winners get physical prizes, digital souvenirs, or brand samples,a unique code unlocks a real-world giftbox. | |
| 9. **Venom-Themed AI Photo Booth** | |
| An immersive, themed booth where guests take selfies that are transformed with custom visual effects tied to the Venom movie. | |
| 10. **Virtual Mosaic Wall** | |
| Each participant’s selfie or message contributes to a larger digital mosaic displayed on a screen, forming a logo or image over time. | |
| 11. **Sanitizer Dispenser Booth with Data Capture** | |
| Hygiene stations that combine sanitizer use with fun branded interactions, collecting engagement data during activation. | |
| 12. **Live-Draw Photo Booth with Projection** | |
| Guests take a photo, which gets branded and projected live on big screens in a visual story format (e.g., mural or timeline). | |
| 13. **Giftbox Quiz Station** | |
| Guests answer brand-related quiz questions. Correct answers unlock a surprise giftbox reward. Fun, educational, and shareable. | |
| 14. **AI Doodle-to-Art Transformation** | |
| Guests draw a doodle on-screen; AI turns it into digital art, which they can download or print on souvenirs. | |
| """ | |
| prompt = f""" | |
| #### Important Instructions To Perform Before Generating Ideas: | |
| -Before you begin, clearly look for real-world ideas previously done by iboothme in below triple backtick. | |
| {examples} | |
| -Use these as inspiration to understand the **ideas they use for there events**, visual style, and creative concepts they typically use. | |
| -Incorporate this knowledge into the ideation process to ensure all concepts align with iboothme’s authentic brand portfolio. | |
| -Look for Iboothme existing products to get the knowldge of products they use for genrating and designing ideas for event, below is the description of their products in backtick: | |
| {product_info} | |
| #### Very Very Important: | |
| -Ideas should be according to the event descrition - like what the Description is about. | |
| -Always use simple wording that is easy to understand - ** no high level english or words**. | |
| -Ideas should be **Unique and realistic in a way that they can be implemented**. | |
| -Don't make impossible to implement ideas. | |
| -Ideas should meet the persona of iboothme and can be implemented using iboothme product. | |
| #### Task To Do: | |
| -You are an expert event strategist for iboothme, a company offering creative experiences like AI photo booths, smart vending machines, audio booths, personalization stations, immersive visual storytellingetc etc. | |
| -Below are full descriptions of three randomly selected iboothme products, to keep all ideas on-brand , the Description of event client wants to do and the inspiration from related ideas: | |
| ```{product_info}``` | |
| Event Description: | |
| ```{paragraph}``` | |
| Inspiration from Related Ideas: | |
| ```{search_summary}``` | |
| #### Real iboothme-style ideas: | |
| {examples} | |
| -Your task is to design and generate {idea_count} creative and compelling event concepts based on the knowledge you gather about iboothme persona , their existing event ideas in above examples ,their existing products description and inspiration from related ideas | |
| -These ideas will be pitched to clients, so they must feel premium, memorable, and on-brand. | |
| ####Important Guidelines: | |
| -Do not list product names directly. Instead, embed iboothme capabilities (e.g., smart booths, photo moments, personalized merch, interactive vending etc) implicitly in the concept. | |
| -Include one game-style idea and one Studio Ghibli-style visual theme | |
| -Personalized giveaways (e.g., custom t-shirts, stickers, Labibu dolls) | |
| {game_instruction} | |
| -Include subtle user journey or emotional takeaway | |
| -Use iboothme’s brand tone: light, simple, fun, and emotionally engaging | |
| #### Important: | |
| -Avoid AR, VR, holograms, or projection domes | |
| -Do not repeat photo‑booth formats | |
| #### Output Format -Event Idea Format (for each idea): | |
| 1. **Catchy Title** | |
| 2. **Concept Paragraph** — "Idea" Briefly describe what the idea is about. Keep it simple and imaginative. | |
| 3. **User Journey Paragraph** —"User Journey" Describe exactly what a guest would experience at the activation. | |
| Include: | |
| - What they first see and feel | |
| - How they interact (step-by-step) | |
| - What emotional moments or surprises are included | |
| - What personalized item or memory they take away | |
| Return only the final ideas in markdown format. | |
| """ | |
| # Count tokens BEFORE sending | |
| token_count = count_tokens(prompt, model="gpt-4") | |
| print(f"🔢 Prompt Token Count: {token_count}") | |
| resp = client.chat.completions.create( | |
| model="gpt-4", | |
| messages=[{"role": "user", "content": prompt}], | |
| temperature=0.95, | |
| max_tokens=1500 | |
| ) | |
| return resp.choices[0].message.content | |
| # Main orchestration | |
| def main_workflow(paragraph: str) -> str: | |
| print("main_workflow called with paragraph:", paragraph) | |
| if not paragraph.strip(): | |
| print("No paragraph provided.") | |
| return "❌ Please enter an event description." | |
| # 1. Randomly pick 3 products from your catalog | |
| try: | |
| gadget_names = random.sample(list(PRODUCT_CATALOG.keys()), k=14) | |
| print("Randomly selected products:", gadget_names) | |
| product_info = get_product_descriptions(gadget_names) | |
| except Exception as e: | |
| print("Error selecting products:", e) | |
| return f"❌ Error selecting products: {e}" | |
| # 2. Gather keywords + optional web search | |
| try: | |
| base_kw = extract_keywords(paragraph) | |
| print("Extracted base keywords:", base_kw) | |
| links = search_similar_events_and_products_openai(base_kw) | |
| print("Found links:", links) | |
| link_kw = [] | |
| for t, u in links: | |
| kws = extract_keywords_from_title_and_link(t, u) | |
| print(f"Extracted keywords from link ({t}, {u}):", kws) | |
| link_kw.extend(kws) | |
| all_kw = sorted(set(base_kw + link_kw)) | |
| print("All keywords:", all_kw) | |
| except Exception as e: | |
| print("Error in keyword extraction or web search:", e) | |
| return f"❌ Error in keyword extraction or web search: {e}" | |
| # 3. Generate ideas | |
| try: | |
| idea_count = 7 | |
| print("Idea count:", idea_count) | |
| ideas_md = generate_event_ideas(paragraph, product_info, links, all_kw, idea_count) | |
| print("Generated ideas markdown.") | |
| except Exception as e: | |
| print("Error generating ideas:", e) | |
| return f"❌ Error generating ideas: {e}" | |
| # 4. Summarize top keywords | |
| summaries = [] | |
| for kw in all_kw[:10]: | |
| try: | |
| print(f"Summarizing keyword: {kw}") | |
| r = client.chat.completions.create( | |
| model="gpt-4", | |
| messages=[{"role": "user", "content": f"Give a short one-line event idea description using the keyword: {kw}"}], | |
| temperature=0.6, | |
| max_tokens=60 | |
| ) | |
| desc = r.choices[0].message.content.strip() | |
| summaries.append(f"- **{kw.title()}**: {desc}") | |
| except Exception as e: | |
| print(f"Error summarizing keyword {kw}:", e) | |
| summaries.append(f"- **{kw.title()}**") | |
| summary_md = "\n".join(summaries) | |
| print("Returning final markdown output.") | |
| return f""" | |
| 🌐 **Relevant Keywords :** | |
| {summary_md} | |
| {ideas_md} | |
| """ | |
| # 8) Styling and Gradio interface | |
| custom_theme = gr.themes.Base( | |
| primary_hue="purple", | |
| secondary_hue="purple", | |
| neutral_hue="gray" | |
| ).set( | |
| body_background_fill="white", | |
| block_background_fill="white", | |
| block_border_width="2px", | |
| block_border_color="#a18cd1", | |
| button_primary_background_fill="linear-gradient(90deg, #a18cd1 0%, #fbc2eb 100%)", | |
| button_primary_text_color="white", | |
| input_background_fill="white", | |
| input_border_color="#a18cd1" | |
| ) | |
| custom_css = """ | |
| #iboothme-heading { | |
| font-weight: 900 !important; | |
| font-size: 2.5rem !important; | |
| background: linear-gradient(90deg, #a18cd1 0%, #fbc2eb 100%); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: black; | |
| margin-bottom: 0.5em; | |
| text-align: center; | |
| letter-spacing: 1px; | |
| } | |
| #desc-subheading { | |
| text-align: center; | |
| font-size: 1.15rem; | |
| font-weight: 500; | |
| color: #6d4fa7; | |
| margin-bottom: 2em; | |
| } | |
| .gradio-container { min-height: 100vh; } | |
| .gr-box, .gr-input, .gr-button, .gr-markdown, .gr-textbox, .gr-column, .gr-row { | |
| border-radius: 18px !important; | |
| } | |
| #event-desc-box { | |
| border: 2px solid #a18cd1 !important; | |
| box-shadow: 0 4px 24px 0 rgba(161,140,209,0.10) !important; | |
| background: white !important; | |
| } | |
| #generate-btn { | |
| font-weight: bold; | |
| font-size: 1.1rem; | |
| background: linear-gradient(90deg, #a18cd1 0%, #fbc2eb 100%) !important; | |
| color: white !important; | |
| border-radius: 12px !important; | |
| box-shadow: 0 2px 8px 0 rgba(161,140,209,0.10) !important; | |
| margin-top: 1.5em; | |
| } | |
| #output-box { | |
| border: 2px solid #a18cd1 !important; | |
| box-shadow: 0 4px 24px 0 rgba(161,140,209,0.10) !important; | |
| background: black !important; | |
| color: white !important; | |
| } | |
| """ | |
| with gr.Blocks(theme=custom_theme, css=custom_css,title="iboothme Event Ideation App") as demo: | |
| gr.Markdown( | |
| "<div id='iboothme-heading'>🎉 <b>iboothme Event Idea Generator</b></div>" | |
| "<div id='desc-subheading'>Describe your event goal and receive interactive, tech‑powered ideas!</div>" | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| paragraph = gr.Textbox( | |
| label="📝 Describe Your Event (e.g. Women’s Day, Product Launch)", | |
| lines=4, | |
| elem_id="event-desc-box" | |
| ) | |
| with gr.Column(scale=1, min_width=220): | |
| submit_btn = gr.Button("🚀 Generate Event Concepts", elem_id="generate-btn") | |
| output = gr.Markdown(elem_id="output-box") | |
| submit_btn.click( | |
| fn=main_workflow, | |
| inputs=[paragraph], | |
| outputs=output, | |
| show_progress=True | |
| ) | |
| demo.launch(inline=False, share=True) |