Spaces:
Sleeping
Sleeping
File size: 10,596 Bytes
4568847 3b79c90 4568847 3b79c90 4568847 3b79c90 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
import gradio as gr
import re
import random
import json
from dotenv import load_dotenv
import os
from openai import OpenAI
# 🔐 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()
# 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 ""
prompt = f"""
You are an expert event strategist for iboothme, a company offering creative experiences like AI photo booths, smart vending machines, audio booths, personalization stations, and immersive visual storytelling.
Below are full descriptions of three randomly selected iboothme products, to keep all ideas on-brand:
{product_info}
Based on the event description below, generate {idea_count} unique and diverse iboothme-powered event ideas.
Make sure that the syntax of the brand is always "iboothme" (all lowercase).
**Event Description:**
{paragraph}
**Inspiration from Related Ideas:**
{search_summary}
💡 **Your Task:**
Create ideas that are immersive, memorable, and creatively use iboothme's photo, video, and audio-based technologies. Do not use AR, VR, projection mapping, or other tech-heavy elements.
You must include:
- At least two game-related ideas
- Studio Ghibli-inspired visuals in one idea
- Personalized giveaways (e.g., custom t-shirts, stickers, Labibu dolls)
{game_instruction}
❗ Important:
- Avoid AR, VR, holograms, or projection domes
- Do not repeat photo‑booth formats
- Every idea should have a creative title
- Each idea should be described in a paragraph
- Immediately after, write a second paragraph describing the user journey flow
Return **only** the final ideas in markdown format.
"""
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=4)
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 = random.choice([5,6,7,8])
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:**
{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; background: white !important; }
.gr-box, .gr-input, .gr-button, .gr-markdown, .gr-textbox, .gr-column, .gr-row {
border-radius: 18px !important;
}
#event-desc-box, #output-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;
}
"""
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) |