|
import base64 |
|
import requests |
|
import gradio as gr |
|
from PIL import Image |
|
import numpy as np |
|
from datetime import datetime |
|
import os |
|
|
|
|
|
api_key = os.getenv("OPENAI_API_KEY") |
|
|
|
|
|
|
|
def encode_image(image_array): |
|
|
|
img = Image.fromarray(np.uint8(image_array)) |
|
img_buffer = os.path.join( |
|
"/tmp", f"temp_image_{datetime.now().strftime('%Y%m%d_%H%M%S')}.jpg" |
|
) |
|
img.save(img_buffer, format="JPEG") |
|
|
|
with open(img_buffer, "rb") as image_file: |
|
return base64.b64encode(image_file.read()).decode("utf-8") |
|
|
|
|
|
|
|
def generate_product_description(image, description_type, custom_instruction=None): |
|
|
|
base64_image = encode_image(image) |
|
|
|
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {api_key}"} |
|
|
|
|
|
description_prompts = { |
|
"Short Formal π": "Based on the image, craft a concise and compelling product description that highlights key features and benefits in a formal tone.", |
|
"Bullet Points π": "From the image, provide a detailed list of bullet points describing the product's features, benefits, and unique selling points.", |
|
"Amazon Optimized π": "Create an Amazon-style product description based on the image, including key features, benefits, relevant keywords for SEO, and a persuasive call to action.", |
|
"Fashion π": "Generate a stylish and trendy product description for a fashion item shown in the image, emphasizing its design, materials, and how it fits into current fashion trends.", |
|
"Sport π": "Using the image, develop an energetic and engaging product description for a sports-related item, highlighting its performance features and benefits for athletic activities.", |
|
"Technical Specifications βοΈ": "Extract and present the product's technical specifications from the image in a clear and concise manner, suitable for tech-savvy customers.", |
|
"SEO Optimized π": "Write an SEO-friendly product description based on the image, incorporating relevant keywords and phrases to enhance search engine visibility.", |
|
"Social Media Style π±": "Create a catchy and engaging product description suitable for social media platforms, using the image as inspiration.", |
|
"Luxury π": "Craft an elegant and sophisticated product description for the luxury item shown in the image, emphasizing exclusivity, premium quality, and craftsmanship.", |
|
"Kid-Friendly π§Έ": "Generate a fun and appealing product description for a children's product based on the image, using language that resonates with both kids and parents.", |
|
"Health and Beauty π": "Develop a compelling product description for a health or beauty item shown in the image, highlighting its benefits, ingredients, and usage tips.", |
|
"Electronic Gadgets π±": "Write a tech-focused product description for the electronic gadget in the image, focusing on its innovative features, specifications, and user advantages.", |
|
"Eco-Friendly π±": "Create an eco-conscious product description for the environmentally friendly product shown in the image, emphasizing sustainability and green benefits.", |
|
"Personalized Gifts π": "Generate a heartfelt product description for the personalized gift in the image, highlighting customization options and sentimental value.", |
|
"Seasonal Promotion π": "Craft a seasonal promotional product description based on the image, incorporating festive themes and limited-time offers to encourage immediate purchase.", |
|
"Clearance Sale π·οΈ": "Write an urgent and enticing product description for the item in the image, emphasizing discounted prices and limited stock availability.", |
|
"Cross-Selling π": "Develop a product description that not only highlights the item in the image but also suggests complementary products, encouraging additional purchases.", |
|
"Up-Selling β¬οΈ": "Create a persuasive product description that highlights premium features of the item in the image, encouraging customers to consider higher-end versions.", |
|
"Multi-Language Support π": "Provide a product description based on the image in multiple languages to cater to a diverse customer base.", |
|
"User Testimonials β": "Incorporate fictional user testimonials or reviews into the product description based on the image, adding credibility and social proof.", |
|
"Instructional π": "Write a product description that includes usage instructions or assembly steps for the item shown in the image.", |
|
"Bundle Offer π¦": "Craft a product description that promotes the item in the image as part of a bundle deal, highlighting the added value.", |
|
"Gift Guide Entry π": "Generate a product description suitable for inclusion in a gift guide, emphasizing why the item in the image makes a great gift.", |
|
"Limited Edition π": "Create an exclusive product description for the limited-edition item shown in the image, highlighting its uniqueness and scarcity.", |
|
"Subscription Model π": "Write a product description that promotes the item in the image as part of a subscription service, detailing recurring benefits.", |
|
"B2B Focused π’": "Develop a professional product description suitable for business-to-business contexts, emphasizing features relevant to corporate clients.", |
|
} |
|
|
|
|
|
if description_type == "Other" and custom_instruction: |
|
instruction = custom_instruction |
|
else: |
|
instruction = description_prompts.get( |
|
description_type, "Create a product description based on the image." |
|
) |
|
|
|
|
|
payload = { |
|
"model": "gpt-4o-mini", |
|
"messages": [ |
|
{ |
|
"role": "user", |
|
"content": [ |
|
{"type": "text", "text": instruction}, |
|
{ |
|
"type": "image_url", |
|
"image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}, |
|
}, |
|
], |
|
} |
|
], |
|
"max_tokens": 300, |
|
} |
|
|
|
response = requests.post( |
|
"https://api.openai.com/v1/chat/completions", headers=headers, json=payload |
|
) |
|
response_data = response.json() |
|
|
|
|
|
if response.status_code != 200: |
|
raise ValueError( |
|
f"OpenAI API Error: {response_data.get('error', {}).get('message', 'Unknown Error')}" |
|
) |
|
|
|
|
|
return response_data["choices"][0]["message"]["content"] |
|
|
|
|
|
|
|
css = """ |
|
body { |
|
font-family: 'Inter', sans-serif; |
|
background-color: #ffffff; |
|
color: #333333; |
|
} |
|
#output { |
|
height: 500px; |
|
overflow: auto; |
|
border: 1px solid #ccc; |
|
padding: 20px; |
|
font-size: 1em; /* Reduced font size */ |
|
border-radius: 8px; |
|
} |
|
button, select, input[type="button"], input[type="submit"] { |
|
background-color: #3452db; /* Correct WordLift blue */ |
|
color: white; |
|
border-radius: 5px; /* Slightly smaller radius */ |
|
padding: 10px 20px; |
|
border: none; |
|
font-size: 1em; |
|
cursor: pointer; |
|
box-shadow: none; /* Removed heavy shadow */ |
|
} |
|
button:hover, select:hover, input[type="button"]:hover, input[type="submit"]:hover { |
|
background-color: #2c44ba; /* Slightly darker shade for hover */ |
|
} |
|
.gr-box { |
|
border: 1px solid #e1e1e1; |
|
border-radius: 5px; |
|
box-shadow: none; /* Removed heavy shadow */ |
|
padding: 15px; /* Reduced padding */ |
|
} |
|
.gr-block { |
|
margin-bottom: 15px; /* Reduced margin */ |
|
} |
|
.output-text { |
|
font-size: 1.1em; /* Reduced font size */ |
|
color: #000000; |
|
padding: 10px; /* Reduced padding */ |
|
border-radius: 5px; |
|
box-shadow: none; /* Removed heavy shadow */ |
|
border: 1px solid #e1e1e1; |
|
} |
|
""" |
|
|
|
|
|
with gr.Blocks(css=css) as demo: |
|
gr.Markdown("<h1>WordLift Product Description Generation - [FREE]</h1>") |
|
with gr.Tab(label="WordLift Product Description Generation"): |
|
with gr.Row(): |
|
with gr.Column(): |
|
input_img = gr.Image(label="Input Picture", elem_classes="gr-box") |
|
description_type = gr.Dropdown( |
|
label="Select Description Type", |
|
choices=[ |
|
"Short Formal π", |
|
"Bullet Points π", |
|
"Amazon Optimized π", |
|
"Fashion π", |
|
"Sport π", |
|
"Technical Specifications βοΈ", |
|
"SEO Optimized π", |
|
"Social Media Style π±", |
|
"Luxury π", |
|
"Kid-Friendly π§Έ", |
|
"Health and Beauty π", |
|
"Electronic Gadgets π±", |
|
"Eco-Friendly π±", |
|
"Personalized Gifts π", |
|
"Seasonal Promotion π", |
|
"Clearance Sale π·οΈ", |
|
"Cross-Selling π", |
|
"Up-Selling β¬οΈ", |
|
"Multi-Language Support π", |
|
"User Testimonials β", |
|
"Instructional π", |
|
"Bundle Offer π¦", |
|
"Gift Guide Entry π", |
|
"Limited Edition π", |
|
"Subscription Model π", |
|
"B2B Focused π’", |
|
"Other", |
|
], |
|
value="Short Formal π", |
|
elem_classes="gr-box" |
|
) |
|
custom_instruction = gr.Textbox( |
|
label="Custom Instruction (Only for 'Other')", visible=False, elem_classes="gr-box" |
|
) |
|
submit_btn = gr.Button(value="Submit", elem_classes="gr-box") |
|
with gr.Column(): |
|
output_text = gr.Markdown(label="Output Text", show_copy_button=True, elem_classes="output-text") |
|
|
|
|
|
def toggle_custom_instruction(type_selection): |
|
return gr.update(visible=(type_selection == "Other")) |
|
|
|
description_type.change( |
|
toggle_custom_instruction, |
|
inputs=[description_type], |
|
outputs=[custom_instruction], |
|
) |
|
|
|
submit_btn.click( |
|
generate_product_description, |
|
[input_img, description_type, custom_instruction], |
|
[output_text], |
|
) |
|
|
|
|
|
demo.queue(api_open=False) |
|
demo.launch(debug=True) |