Spaces:
Paused
Paused
| import traceback | |
| import gradio as gr | |
| import numpy as np | |
| import os | |
| from langchain_community.chat_models import ChatOpenAI | |
| from langchain.schema import HumanMessage, SystemMessage, AIMessage | |
| from langchain_anthropic import ChatAnthropic, ChatAnthropicMessages | |
| from langchain_groq import ChatGroq | |
| import openai | |
| feature_text = "Brand: Duckly. \nProduct name: Duck runner pro. \nKey properties: t-shirt, for running, sweat wicking, for marathon, 100% cotton." | |
| garment_type = "all" | |
| reference_text = "" | |
| structure_text = \ | |
| """# Headline {{ headline | inspiring, bold, action-oriented, max 8 words }} | |
| ## Introduction | |
| {{ introduction_paragraph | motivational, passionate, 2-3 sentences }} | |
| ## Features and Benefits | |
| {% for feature in features %} | |
| ### Feature {{ loop.index }}: {{ feature.name | dynamic, direct, 5-6 words }} | |
| {{ feature.details | energetic, clear, 3-4 sentences }} | |
| {% endfor %} | |
| ## Technical Specifications | |
| {{ technical_specs | informative, to the point, concise list format }} | |
| """ | |
| structure_text_1 = """[type: UK website, style=true, language=English] | |
| {{ introduction_paragraph | motivational, passionate, 1-2 sentences }} | |
| {% for feature in features as bulleted list %} | |
| {{ feature.description | dynamic, direct, 3-6 words }} | |
| {% endfor %} | |
| {{ technical_specs | informative, to the point, concise list format }}""" | |
| structure_text_2 = """[type: Japanese newsletter, style=true, language=Japanese] | |
| {{ introduction_paragraph | motivational, passionate, 3-6 sentences }}""" | |
| languages = ["American English", | |
| "British English", | |
| "German", | |
| "French", | |
| "Chinese", | |
| "Spanish", | |
| "Dutch", | |
| "Italian", | |
| "Japanese", | |
| "Polish", | |
| "Portuguese"] | |
| models = ["gpt-4-turbo", | |
| "gpt-4o", | |
| "gpt-3.5-turbo", | |
| "claude-3-sonnet-20240229", | |
| "claude-3-opus-20240229", | |
| #"llama3-70b-8192", | |
| ] | |
| openai.api_key = os.environ["OPENAI_API_KEY"] | |
| import base64 | |
| import requests | |
| # OpenAI API Key | |
| # Function to encode the image | |
| def encode_image(image_path): | |
| with open(image_path, "rb") as image_file: | |
| return base64.b64encode(image_file.read()).decode('utf-8') | |
| import json | |
| def get_json(text: str): | |
| text = text.strip().replace('`', '').replace('json', '') | |
| if text.startswith("No garment detected"): | |
| return { | |
| "features": [], | |
| "intended_use": [], | |
| "alt_text": [] | |
| } | |
| return json.loads(text) | |
| def detect_features(image_paths, garment_type, language="English"): | |
| # Path to your image | |
| # image_path = "path_to_your_image.jpg" | |
| # Getting the base64 string | |
| try: | |
| base64_images = [encode_image(image_path[0]) for image_path in image_paths] | |
| if garment_type == "" or garment_type == "all": | |
| garment_type = "garment" | |
| headers = { | |
| "Content-Type": "application/json", | |
| "Authorization": f"Bearer {openai.api_key}" | |
| } | |
| payload = { | |
| "model": "gpt-4o", | |
| # "model": "gpt-4-turbo", | |
| "messages": [ | |
| { | |
| "role": "user", | |
| "content": [ | |
| { | |
| "type": "text", | |
| "text": """Describe the features of the %s in the photos in less than 100 words. | |
| What is the intended use of the %s in this image, use at most 5 words for intended use? | |
| Generate alt text for each of the images. | |
| Make sure to output the alt text in %s language. | |
| If the photo does not contain a garment, return 'No garment detected'. | |
| If the photo contains a garment, return the result in in the following JSON format without any preceding or trailing text: | |
| { | |
| "features": [list of comma separated features], | |
| "intended_use": [list of comma separated intended uses], | |
| "alt_text": [list of alt text for image 1, alt text for image 2] | |
| }""" % (garment_type, garment_type, language) | |
| }, | |
| ] + [{ | |
| "type": "image_url", | |
| "image_url": { | |
| "url": f"data:image/jpeg;base64,{base64_image}" | |
| } | |
| } for base64_image in base64_images] | |
| } | |
| ], | |
| "temperature": 0.0, | |
| "max_tokens": 300 | |
| } | |
| response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload) | |
| print(response) | |
| response = response.json() | |
| print("image features", response["choices"][0]['message']['content']) | |
| jresponse = get_json(response["choices"][0]['message']['content']) | |
| return jresponse, base64_images | |
| except Exception as e: | |
| print(e.__class__, e) | |
| traceback.print_exc() | |
| return "", [] | |
| def generate(*data): | |
| global visible | |
| print("visible", visible) | |
| feature, image, garment_type, model, temperature = data[:5] | |
| struct_ref = data[5:] | |
| print(f"features {feature},\n image {image},\n garment_type {garment_type},\n model {model},\n temperature {temperature},\n struct_ref {struct_ref}") | |
| image_features, base64_images = detect_features(image, garment_type) | |
| detected_features = "" | |
| intended_use = "" | |
| alt_texts = [] | |
| if image_features is not None and len(image_features) > 0: | |
| alt_texts = image_features["alt_text"] | |
| detected_features = ", ".join(image_features["features"]) | |
| intended_use = "Intended use: " + ", ".join(image_features["intended_use"]) | |
| print(f"Detected features: {detected_features}, Intended use: {intended_use}, Alt text: {alt_texts}") | |
| if model.startswith("gpt"): | |
| chat = ChatOpenAI(model=model) | |
| elif model.startswith("claude"): | |
| chat = ChatAnthropic(model_name=model, anthropic_api_key=os.environ["ANTHROPIC_API_KEY"]) | |
| else: | |
| chat = ChatGroq(model_name=model, api_key=os.environ["GROQ_API_KEY"]) | |
| batch = [] | |
| for i in range(visible + 1): | |
| structure = struct_ref[2 * i] | |
| reference = struct_ref[2 * i + 1] | |
| messages = [ | |
| SystemMessage(content=f"""You are a helpful assistant that writes about products for ecommerce websites."""), | |
| HumanMessage(content=f"""Write a product description with the following features. | |
| Make sure that the description follows the structure of the reference structure. | |
| Make sure to use markdown format for the output. | |
| Make sure that the entire output is written entirely in language defined in the reference structure. | |
| Use language that is suitable for the type of document specified in the reference structure. | |
| Use a consistent tone of voice throughout the text. | |
| If the reference text is not empty, write the product description in the tone of voice of the reference text. | |
| Make sure to output the product description only, do not include any preceeding text like "Here is your product description". | |
| Do not include any part of the reference structure in the output. | |
| \n\n {feature + detected_features} \n{intended_use} \nReference structure: {structure}\n Reference text: {reference}""")] | |
| batch.append(messages) | |
| description = "" | |
| response = chat.batch(batch, temperature=temperature) | |
| print(response) | |
| description = "\n---\n".join([msg.content for msg in response]) | |
| md_content = description | |
| alt_texts_str = '\n\n### Alt text\n\n' + '\n- ' + '\n- '.join(alt_texts) if len(alt_texts) > 0 else "" | |
| alt_text_dict = {k[0]: v for (k, v) in zip(image, alt_texts)} if len(alt_texts) > 0 else {} | |
| result_json = {"outputs": [msg.content for msg in response], "alt_text": alt_text_dict} | |
| result_md = md_content + alt_texts_str + '\n'.join([f'' if base64_image != "" else "" for (base64_image, alt_text) in zip(base64_images, alt_texts)]) | |
| return result_md, result_json | |
| visible = 0 | |
| def add_output_click(*struct_ref): | |
| global visible | |
| print("Adding output ", visible) | |
| # print(struct_ref) | |
| visible += 1 | |
| structure_texts = struct_ref[::2] | |
| reference_texts = struct_ref[1::2] | |
| structures = [gr.Textbox(label=f"Structure {i}", lines=10, value=structure_texts[i], interactive=True, visible=i <= visible) for i in range(10)] | |
| references = [gr.Textbox(label=f"Reference copy {i}", lines=3, value=reference_texts[i], interactive=True, visible=i <= visible) for i in range(10)] | |
| struct_ref = [val for pair in zip(structures, references) for val in pair] | |
| return struct_ref | |
| def remove_output_click(*struct_ref): | |
| global visible | |
| print("Removing output", visible) | |
| if visible == 0: | |
| return struct_ref | |
| visible -= 1 | |
| structure_texts = struct_ref[::2] | |
| reference_texts = struct_ref[1::2] | |
| structures = [gr.Textbox(label=f"Structure {i}", lines=10, value=structure_texts[i] if i <= visible else "", interactive=True, visible=i <= visible) for i in range(10)] | |
| references = [gr.Textbox(label=f"Reference copy {i}", lines=3, value=reference_texts[i] if i <= visible else "", interactive=True, visible=i <= visible) for i in range(10)] | |
| struct_ref = [val for pair in zip(structures, references) for val in pair] | |
| return struct_ref | |
| def show_advanced(model, temperature): | |
| model = gr.Dropdown(models, value="gpt-4-turbo", interactive=True, label="Model", visible=True) | |
| temperature = gr.Slider(minimum=0., maximum=1.0, value=0., interactive=True, label="Temperature", visible=True) | |
| return model, temperature | |
| with gr.Blocks() as demo: | |
| with gr.Row(): | |
| with gr.Column(): | |
| feature = gr.Textbox(label="Features", value=feature_text, lines=3, interactive=True) | |
| image = gr.Gallery(label="Images") | |
| garment_type = gr.Textbox(label="Garment Type", value="all", lines=1, interactive=True) | |
| # language = gr.Dropdown(languages, value="American English", interactive=True, label="Language") | |
| with gr.Accordion(label="Advanced Options", open=False): | |
| model = gr.Dropdown(models, value="gpt-4-turbo", interactive=True, label="Model", visible=True) | |
| temperature = gr.Slider(minimum=0., maximum=1.0, value=0., interactive=True, label="Temperature", visible=True) | |
| with gr.Row(): | |
| submit = gr.Button(value="Submit") | |
| # advanced = gr.Button(value="Advanced") | |
| with gr.Column(): | |
| struct_ref = [val for i in range(10) for val in | |
| [gr.Textbox(label=f"Structure {i}", lines=10, value="", interactive=True, visible=i <= visible), | |
| gr.Textbox(label=f"Reference copy {i}", lines=3, value="", interactive=True, visible=i <= visible)]] | |
| struct_ref[0].value = structure_text_1 | |
| # struct_ref[2].value = structure_text_2 | |
| with gr.Row(): | |
| add_output = gr.Button(value="Add Output") | |
| remove_output = gr.Button(value="Remove Output") | |
| add_output.click(add_output_click, inputs=struct_ref, outputs=struct_ref) | |
| remove_output.click(remove_output_click, inputs=struct_ref, outputs=struct_ref) | |
| with gr.Column(): | |
| md_output = gr.Markdown(label="Output", show_label=True) | |
| json_output = gr.JSON(label="JSON Output") | |
| submit.click(generate, inputs=[feature, image, garment_type, model, temperature, *struct_ref], | |
| outputs=[md_output, json_output]) | |
| # advanced.click(show_advanced, inputs=[], outputs=[model, temperature]) | |
| import bcrypt | |
| def authf(username, password): | |
| try: | |
| with open("passwords.txt", "r") as f: | |
| for line in f.readlines(): | |
| u, p = line.strip().split() | |
| # print(u, p, password) | |
| if u == username and bcrypt.checkpw(password.encode('utf-8'), p.encode('utf-8')): | |
| return True | |
| except Exception as e: | |
| print("Error reading password", e) | |
| traceback.print_exc() | |
| return False | |
| if __name__ == '__main__': | |
| demo.launch(server_name="0.0.0.0", auth=authf) | |