Spaces:
Sleeping
Sleeping
import gradio as gr | |
import google.generativeai as genai | |
import re | |
import json | |
def count_characters(text): | |
"""Count characters in text.""" | |
return len(text) if text else 0 | |
def format_output(title, brand_name, bullet1, bullet2, suggested_keywords=None): | |
"""Format the output with character counts.""" | |
output = f"Title ({count_characters(title)}/60 characters):\n{title}\n\n" | |
output += f"Brand Name ({count_characters(brand_name)}/50 characters):\n{brand_name}\n\n" | |
output += f"Bullet Point 1 ({count_characters(bullet1)}/256 characters):\n{bullet1}\n\n" | |
output += f"Bullet Point 2 ({count_characters(bullet2)}/256 characters):\n{bullet2}" | |
if suggested_keywords: | |
output += f"\n\nSuggested Additional Keywords:\n{suggested_keywords}" | |
return output | |
def generate_prompt(quote, niche, target, keywords): | |
"""Generate the prompt for Gemini API.""" | |
combined_prompt = f"""You are an Amazon Merch on Demand SEO expert specializing in creating optimized t-shirt and apparel listings. | |
MY INPUT IS ABOUT: A {niche} t-shirt with the design/quote: "{quote}" for {target}. | |
YOU MUST ONLY create an Amazon apparel listing about that EXACT input - no substitutions or different themes allowed. | |
Generate a listing that includes: | |
1. Title (exactly 60 characters): Must include "{niche}" and reference the design/quote "{quote}" and target audience "{target}" | |
2. Brand Name (34-50 characters): Create a fitting brand name for this specific {niche} apparel for {target} | |
3. Bullet Point 1 (240-256 characters): Highlight key features using ALL CAPS for the first 2-3 words. Focus ONLY on the design, quote, and niche theme. | |
4. Bullet Point 2 (240-256 characters): Highlight additional features using ALL CAPS for the first 2-3 words. Focus ONLY on the design, quote, and niche theme. | |
IMPORTANT RULES FOR BULLET POINTS: | |
- Bullet points must be between 240-256 characters | |
- DO NOT include generic phrases like "PREMIUM QUALITY" or references to material quality | |
- DO NOT include phrases like "This comfortable and stylish tee is made with high-quality materials for a soft feel and long-lasting wear" | |
- Focus ONLY on the specific design, niche, and quote provided | |
- Every sentence must directly relate to the quote, niche theme, and target audience | |
- Do not include any content that strays from the specific theme provided | |
The listing should be specifically for t-shirts, hoodies, or sweaters for the Amazon Merch on Demand program. | |
The listing MUST be about: {niche} + {quote} + for {target}. Do not generate content about other holidays, quotes, or audiences. | |
Use these specific keywords in your listing: {keywords} | |
Respond ONLY with a JSON object in this format: | |
{{ | |
"title": "Title text here", | |
"brand_name": "Brand name here", | |
"bullet_point_1": "Bullet point 1 text here", | |
"bullet_point_2": "Bullet point 2 text here", | |
"suggested_keywords": "Comma separated list of 5 additional keywords" | |
}} | |
The output must follow these exact character counts: | |
- Title: Exactly 60 characters | |
- Brand Name: Between 34-50 characters | |
- Bullet Point 1: Between 240-256 characters | |
- Bullet Point 2: Between 240-256 characters""" | |
return combined_prompt | |
def generate_multiple_variations_prompt(quote, niche, target, keywords): | |
"""Generate the prompt for multiple variations of title and brand name.""" | |
combined_prompt = f"""You are an Amazon Merch on Demand SEO expert specializing in creating optimized t-shirt and apparel listings. | |
MY INPUT IS ABOUT: A {niche} t-shirt with the design/quote: "{quote}" for {target}. | |
YOU MUST ONLY create variations about that EXACT input - no substitutions or different themes allowed. | |
Generate 3 different variations for the Title and Brand Name based on the provided information. | |
All variations MUST be about {niche} + "{quote}" + for {target} audience. | |
The titles MUST include: | |
- The specific holiday/event: {niche} | |
- Reference to the quote/design: "{quote}" | |
- The target audience: {target} | |
Focus only on t-shirts, sweaters, and hoodies for the Amazon Merch on Demand program. | |
All titles must be exactly 60 characters and brand names between 34-50 characters. | |
Respond ONLY with a JSON object in this format: | |
{{ | |
"title_variations": [ | |
"Title variation 1 text here (exactly 60 characters)", | |
"Title variation 2 text here (exactly 60 characters)", | |
"Title variation 3 text here (exactly 60 characters)" | |
], | |
"brand_name_variations": [ | |
"Brand name variation 1 here (34-50 characters)", | |
"Brand name variation 2 here (34-50 characters)", | |
"Brand name variation 3 here (34-50 characters)" | |
] | |
}}""" | |
return combined_prompt | |
def generate_amazon_listing(api_key, quote, niche, target, keywords): | |
"""Generate Amazon listing using Gemini API.""" | |
try: | |
# Configure the Gemini API with the provided key | |
genai.configure(api_key=api_key) | |
model = genai.GenerativeModel('gemini-1.5-pro') | |
# Generate the main listing | |
prompt = generate_prompt(quote, niche, target, keywords) | |
response = model.generate_content( | |
prompt, | |
generation_config={ | |
"temperature": 0.3, # Lower temperature for more focused results | |
"top_p": 0.8, | |
"max_output_tokens": 2048 | |
} | |
) | |
# Extract JSON from the response | |
response_text = response.text | |
match = re.search(r'{.*}', response_text, re.DOTALL) | |
if match: | |
json_str = match.group(0) | |
try: | |
result = json.loads(json_str) | |
# Validate that the output actually matches the input criteria | |
title = result.get("title", "") | |
if not (quote.lower() in title.lower() or | |
niche.lower() in title.lower() or | |
any(t.lower() in title.lower() for t in target.lower().split(','))): | |
return f"Error: Generated title doesn't match the requested theme: '{quote}', '{niche}', or '{target}'. Please try again." | |
# Validate bullet point lengths | |
bullet1 = result.get("bullet_point_1", "") | |
bullet2 = result.get("bullet_point_2", "") | |
if len(bullet1) < 240 or len(bullet1) > 256: | |
return f"Error: Bullet point 1 length ({len(bullet1)}) is not between 240-256 characters. Please try again." | |
if len(bullet2) < 240 or len(bullet2) > 256: | |
return f"Error: Bullet point 2 length ({len(bullet2)}) is not between 240-256 characters. Please try again." | |
# Check for generic content in bullet points | |
generic_phrases = ["premium quality", "high-quality materials", "soft feel", "long-lasting wear", | |
"comfortable and stylish", "perfect gift", "great gift"] | |
for phrase in generic_phrases: | |
if phrase in bullet1.lower() or phrase in bullet2.lower(): | |
return f"Error: Generated bullet points contain generic phrase '{phrase}'. Please try again." | |
except json.JSONDecodeError: | |
return "Error parsing JSON response from Gemini API" | |
else: | |
return "Could not extract JSON from Gemini API response" | |
# Generate variations | |
variations_prompt = generate_multiple_variations_prompt(quote, niche, target, keywords) | |
response_var = model.generate_content( | |
variations_prompt, | |
generation_config={ | |
"temperature": 0.4, # Lower temperature for more focused results | |
"top_p": 0.8, | |
"max_output_tokens": 2048 | |
} | |
) | |
# Extract JSON from the variations response | |
response_var_text = response_var.text | |
match_var = re.search(r'{.*}', response_var_text, re.DOTALL) | |
if match_var: | |
json_str_var = match_var.group(0) | |
try: | |
variations = json.loads(json_str_var) | |
except json.JSONDecodeError: | |
variations = { | |
"title_variations": ["Error generating variations"], | |
"brand_name_variations": ["Error generating variations"] | |
} | |
else: | |
variations = { | |
"title_variations": ["Error generating variations"], | |
"brand_name_variations": ["Error generating variations"] | |
} | |
# Format main output | |
main_output = format_output( | |
result.get("title", "Error generating title"), | |
result.get("brand_name", "Error generating brand name"), | |
result.get("bullet_point_1", "Error generating bullet point 1"), | |
result.get("bullet_point_2", "Error generating bullet point 2"), | |
result.get("suggested_keywords", "Error generating suggested keywords") | |
) | |
# Format variations output | |
variations_output = "ADDITIONAL VARIATIONS:\n\n" | |
variations_output += "Title Variations:\n" | |
for i, var in enumerate(variations.get("title_variations", []), 1): | |
variations_output += f"{i}. {var} ({count_characters(var)}/60 characters)\n" | |
variations_output += "\nBrand Name Variations:\n" | |
for i, var in enumerate(variations.get("brand_name_variations", []), 1): | |
variations_output += f"{i}. {var} ({count_characters(var)}/50 characters)\n" | |
return main_output + "\n\n" + variations_output | |
except Exception as e: | |
return f"Error: {str(e)}" | |
# Create the Gradio interface | |
def create_interface(): | |
with gr.Blocks(title="Amazon Merch on Demand Listing Generator") as app: | |
gr.Markdown("# Amazon Merch on Demand Listing Generator") | |
gr.Markdown("Generate SEO-optimized t-shirt and apparel listings for Amazon Merch on Demand using Gemini 1.5 Pro AI.") | |
with gr.Row(): | |
with gr.Column(): | |
api_key = gr.Textbox(label="Gemini API Key", placeholder="Enter your Gemini API key", type="password") | |
quote = gr.Textbox(label="Quote/Design/Idea", placeholder="Enter the quote or design idea") | |
niche = gr.Textbox(label="Holiday/Event", placeholder="Enter the holiday or event (e.g., St Patrick's Day)") | |
target = gr.Textbox(label="Target Audience", placeholder="Teacher, Mom, Dad, etc.") | |
keywords = gr.Textbox(label="Target Keywords", placeholder="Enter keywords separated by commas", lines=5) | |
submit_btn = gr.Button("Generate Amazon Listing", variant="primary") | |
with gr.Column(): | |
output = gr.Textbox(label="Generated Amazon Listing", lines=25) | |
submit_btn.click( | |
fn=generate_amazon_listing, | |
inputs=[api_key, quote, niche, target, keywords], | |
outputs=output | |
) | |
gr.Markdown("## Example Input") | |
gr.Markdown(''' | |
``` | |
Quote/Design: Rainbow with a quote "Lucky To Be A Teacher" | |
Holiday: St Patricks Day | |
Target: Teacher, Teacher Mom | |
Keywords: lucky, teacher, rainbow, st, patricks, day, t-shirt, patrick's, outfit, design, leopard, cheetah, print, shamrock, clover, perfect, men, women, teachers, celebrate, saint, patrick, special, unique, makes, great, gifts, idea, substitute, love, irish, culture, pattys, holiday, teach, shamrocks, cute, design, awesome, show, students | |
``` | |
''') | |
return app | |
# Create and launch the app | |
app = create_interface() | |
# For deployment on Hugging Face Spaces | |
if __name__ == "__main__": | |
app.launch() |