| import base64 |
| import requests |
| import gradio as gr |
| from PIL import Image |
| import pillow_avif |
| import numpy as np |
| from datetime import datetime, date |
| import os |
| import json |
| import uuid |
| from http.cookies import SimpleCookie |
|
|
| |
| SESSION_FILE = "user_session_data.json" |
|
|
| |
| api_key = os.getenv("OPENAI_API_KEY") |
|
|
|
|
| |
| def check_and_reset_user_counter(user_id): |
| all_user_data = load_user_session_data(user_id) |
| user_data = all_user_data[user_id] |
| today = str(date.today()) |
| if user_data["last_reset_date"] != today: |
| user_data["last_reset_date"] = today |
| user_data["test_counter"] = 0 |
| save_user_session_data(all_user_data) |
| return user_data["test_counter"] |
|
|
| def save_user_session_data(all_user_data): |
| with open(SESSION_FILE, 'w') as f: |
| json.dump(all_user_data, f) |
|
|
| |
| def load_user_session_data(user_id): |
| if os.path.exists(SESSION_FILE): |
| with open(SESSION_FILE, 'r') as f: |
| all_user_data = json.load(f) |
| else: |
| all_user_data = {} |
| |
| if user_id not in all_user_data: |
| all_user_data[user_id] = {"last_reset_date": str(date.today()), "test_counter": 0} |
| |
| return all_user_data |
|
|
| |
| def increment_user_counter(user_id): |
| all_user_data = load_user_session_data(user_id) |
| all_user_data[user_id]["test_counter"] += 1 |
| save_user_session_data(all_user_data) |
| return all_user_data[user_id]["test_counter"] |
| |
| |
| def get_or_create_user_id(user_id): |
| if not user_id: |
| return str(uuid.uuid4()) |
| return user_id |
| |
| |
| def encode_image(image_array): |
| try: |
| |
| 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" |
| ) |
| |
| |
| if img.mode != 'RGB': |
| img = img.convert('RGB') |
| |
| |
| try: |
| img.save(img_buffer, format="JPEG", quality=95) |
| except Exception as e: |
| print(f"Error saving image: {e}") |
| |
| img = img.convert('RGB') |
| img.save(img_buffer, format="JPEG", quality=95) |
|
|
| |
| with open(img_buffer, "rb") as image_file: |
| encoded_image = base64.b64encode(image_file.read()).decode("utf-8") |
| |
| |
| if os.path.exists(img_buffer): |
| os.remove(img_buffer) |
| |
| return encoded_image |
| except Exception as e: |
| raise ValueError(f"Error processing image: {str(e)}") |
|
|
| |
| def generate_product_description(image, description_type, custom_instruction=None): |
| try: |
| |
| base64_image = encode_image(image) |
| except Exception as e: |
| raise gr.Error(f"Error processing image: {str(e)}. Please try uploading a different image format.") |
|
|
| 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.", |
| "Alt Text Generation 🦿": "Generate concise and descriptive alt text for the image, ensuring accessibility for users with visual impairments. Focus on the image's key elements and purpose.", |
| } |
|
|
|
|
| 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"] |
|
|
|
|
| |
| custom_css = """ |
| body { |
| font-family: 'Inter', sans-serif; |
| } |
| #output { |
| height: 500px; |
| overflow: auto; |
| border: 1px solid #ccc; |
| } |
| .redirect-message { |
| background-color: #f0f0f0; |
| border: 1px solid #ccc; |
| padding: 15px; |
| margin-top: 20px; |
| border-radius: 5px; |
| } |
| """ |
|
|
| |
| user_id = str(uuid.uuid4()) |
|
|
| with gr.Blocks(css=custom_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 🏢", |
| "Alt Text Generation 🦿", |
| |
| ], |
| 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") |
| redirect_message = gr.Markdown(visible=False, elem_classes="redirect-message") |
| test_counter_display = gr.Markdown(visible=True, label="Test Counter") |
| user_id_display = gr.Markdown(visible=False, label="User ID") |
| |
| |
| user_id_input = gr.Textbox(value="", visible=False) |
|
|
|
|
| |
| 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], |
| ) |
|
|
| def handle_submit(image, description_type, custom_instruction, user_id): |
| try: |
| if not user_id: |
| user_id = str(uuid.uuid4()) |
| |
| check_and_reset_user_counter(user_id) |
| test_counter = increment_user_counter(user_id) |
| |
| demo_link = "https://wordlift.io/book-a-demo/?utm_source=free-app&utm_medium=app&utm_campaign=product-description-generator" |
| |
| if test_counter <= 4: |
| try: |
| result = generate_product_description(image, description_type, custom_instruction) |
| except gr.Error as e: |
| return ( |
| str(e), |
| gr.update(visible=False), |
| gr.update(interactive=True), |
| f"Error occurred. You still have {4 - test_counter + 1} free test(s) remaining today.", |
| f"User ID: {user_id}", |
| user_id |
| ) |
| |
| remaining_tests = 4 - test_counter |
| |
| if remaining_tests > 0: |
| return ( |
| result, |
| gr.update(visible=False), |
| gr.update(interactive=True), |
| f"You have {remaining_tests} free test(s) remaining today.", |
| f"User ID: {user_id}", |
| user_id |
| ) |
| else: |
| redirect_text = f""" |
| Thank you for trying our product description generation tool! |
| |
| You've used all 4 of your free tests for today. We hope you found them helpful and insightful. |
| |
| To unlock unlimited access and discover how our AI-powered solution can revolutionize your content creation process: |
| |
| [Book a Personalized Demo with Our Experts]({demo_link}) |
| |
| During the demo, you'll get:<br> |
| • A tailored walkthrough of our full suite of features<br> |
| • Insights on how to optimize your specific content workflow<br> |
| • Answers to any questions you may have about our solution<br> |
| |
| We're excited to show you how we can help scale your content creation! |
| |
| (Your free tests will reset tomorrow, allowing you to try 4 more if you need additional time to decide.) |
| """ |
| return ( |
| result, |
| gr.update(visible=True, value=redirect_text), |
| gr.update(interactive=False), |
| "You've used all your free tests for today. We invite you to book a demo for full access!", |
| f"User ID: {user_id}", |
| user_id |
| ) |
| else: |
| redirect_text = f""" |
| Thank you for your interest in our product description generation tool! |
| |
| You've already used your 4 free tests for today. We hope they've given you a glimpse of how our AI can enhance your content creation. |
| |
| Ready to explore the full potential of our solution? |
| |
| [Book a Personalized Demo with Our Experts]({demo_link}) |
| |
| In this demo, you'll discover:<br> |
| • How our AI can be customized for your specific needs<br> |
| • Advanced features for scaling your content production using a [Product Knowledge Graph](https://wordlift.io/blog/en/product-knowledge-graph/)<br> |
| • ROI projections based on your current content workflow<br> |
| |
| Let's discuss how we can help you achieve your content goals! |
| |
| (Remember, your free tests will reset tomorrow if you need more time to evaluate.) |
| """ |
| return ( |
| "", |
| gr.update(visible=True, value=redirect_text), |
| gr.update(interactive=False), |
| "All free tests used. We invite you to book a demo for full access!", |
| f"User ID: {user_id}", |
| user_id |
| ) |
| except Exception as e: |
| return ( |
| f"An error occurred: {str(e)}", |
| gr.update(visible=False), |
| gr.update(interactive=True), |
| "Error processing request", |
| f"User ID: {user_id}", |
| user_id |
| ) |
|
|
|
|
| |
| submit_btn.click( |
| handle_submit, |
| inputs=[input_img, description_type, custom_instruction, user_id_input], |
| outputs=[output_text, redirect_message, submit_btn, test_counter_display, user_id_display, user_id_input] |
| ) |
| |
| |
| demo.queue(api_open=False) |
| demo.launch(debug=True) |