Vnmrsharma commited on
Commit
d556179
·
verified ·
1 Parent(s): 436d7d9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -41
app.py CHANGED
@@ -6,59 +6,82 @@ from io import BytesIO
6
  import tempfile
7
  import concurrent.futures
8
  import os
 
 
9
 
10
- api_key = os.environ.get("API_KEY")
11
- univin_model = os.environ.get("univin")
12
-
13
  client = genai.Client(api_key=api_key)
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  PROMPT_VARIATIONS = [
16
  # 1: White background
17
  "Chain-of-Thought: Step 1: Carefully analyze the input image and document every single detail of the product—text, colour, material finish, branding, dimensions, and any embellishments—ensuring no detail is overlooked. Step 2: Generate a highly professional 800×800px image with a pure white background and bright natural lighting, strictly preserving the product’s text, colour, shape and finish exactly as in the original image, with zero alterations. Step 3: Rigorously verify pixel-by-pixel that the output matches the original product data 100 %, then deliver a ready-for-e-commerce upload image.",
18
- # 2: Chnaged
19
  "Chain-of-Thought: Step 1: Meticulously analyze the input image and record every product detail—text, colour, material finish, branding, dimensions, texture, and any embellishments—ensuring nothing is overlooked. Step 2: Generate a highly professional 800×800px image of the product from a precise 45° top-down angle against a green garden background with even lighting, strictly preserving the product’s text, colours, shape and finish exactly as in the original image, with zero alterations. Step 3: Perform a rigorous pixel-level comparison to confirm 100 % fidelity to the original product data and deliver an e-commerce–ready image.",
20
- # 3: Slightly elevated angle, modern indoor
21
  "Chain-of-Thought: Step 1: Scrutinize the input image to record every element of the product—text, colour palette, material finish, and branding—without exception. Step 2: Generate a highly professional 800×800px image from a slightly elevated angle and open lid if the product have a lid in a modern indoor setting with warm lighting, strictly preserving the product’s original text, colours and all details exactly as in the source. Step 3: Double-check at full resolution that no aspect of the product has been altered and that the image is e-commerce ready.",
22
- # 4: Low angle, cool ambient lighting
23
  "Chain-of-Thought: Step 1: Analyze the input image pixel-for-pixel to note every product detail—text, colour, texture, finish, branding and proportions—ensuring nothing is missed. Step 2: Generate a highly professional 800×800px image using a A serene, spa-like setting with elements of tranquility like smooth stones, bamboo, and a calming water feature, ideal for wellness or beauty products. background, with the product’s text, colours, materials and details preserved exactly as in the original. Step 3: Verify 100 % fidelity at the pixel level and confirm readiness for online catalog upload.",
24
- # 5: Vibrant outdoor background
25
  "Chain-of-Thought: Step 1: Inspect the input image meticulously and record every detail—text, colour gradients, material texture, and branding—ensuring total accuracy. Step 2: Generate a highly professional 800×800px image with a vibrant outdoor background and natural sunlight, strictly preserving the product’s original text, colours, finish and all details unchanged. Step 3: Validate that the final image is flawless, matches the original exactly, and is optimized for e-commerce display.",
26
- # 6: Subtle gradient background
27
  "Chain-of-Thought: Step 1: Review the input image thoroughly, capturing and logging every detail—text, colour accuracy, surface finish, and branding—100 % intact. Step 2: Generate a highly professional 800×800px image with a subtle gradient background and soft diffused lighting, ensuring that the product’s text, colours and all design details remain precisely as in the source. Step 3: Perform a pixel-level check to confirm no alterations and that the image meets e-commerce quality standards.",
28
- # 7: Artistic abstract background
29
  "Chain-of-Thought: Step 1: Examine the original product image in depth, noting every detail—text, colour tones, material texture, branding logos and dimensions—with absolute precision. Step 2: Generate a highly professional 800×800px image featuring an abstract background with perfect lighting, strictly preserving the product’s text, colours and every fine detail exactly as in the original. Step 3: Verify pixel-perfect fidelity and confirm the output is upload-ready for an online store.",
30
- # 9: Rich lifestyle background
31
  "Chain-of-Thought: Step 1: Scrutinize the input image in full detail, logging every aspect of the product—text, colour accuracy, branding, material texture, finish, and proportions—to guarantee total fidelity. Step 2: Generate a highly professional 800×800px image of the product placed A cozy, homely setting with a comfortable, inviting ambiance, featuring elements like soft lighting, plush textiles, and warm tones, suitable for home goods or comfort products. ensuring that the product’s text, colours, materials and every detail remain exactly as in the original image without any modification. Step 3: Validate at the pixel level that the output matches the original image perfectly and confirm readiness for online catalog upload.",
32
  ]
33
 
34
  def process_variation(variation, input_image, product_name):
 
 
35
  text_input = (
36
  f"Hi, this is a picture of a product. The name of the product is {product_name}.",
37
  variation
38
  )
39
  response = client.models.generate_content(
40
- model=univin_model,
41
  contents=[text_input, input_image],
42
  config=types.GenerateContentConfig(response_modalities=['Text', 'Image'])
43
  )
 
44
  for part in response.candidates[0].content.parts:
45
  if part.inline_data is not None:
46
- generated_img = Image.open(BytesIO(part.inline_data.data))
47
- with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp_file:
48
- generated_img.save(tmp_file, format="PNG")
49
- return tmp_file.name
 
50
  return None
51
 
 
52
  def generate_images(input_image, product_name):
53
  with concurrent.futures.ThreadPoolExecutor() as executor:
54
  futures = [
55
- executor.submit(process_variation, variation, input_image, product_name)
56
- for variation in PROMPT_VARIATIONS
57
  ]
58
- output_files = [future.result() for future in futures if future.result() is not None]
59
- return output_files
60
 
61
- # Improved UI Layout and Styling
62
  custom_css = """
63
  #generate-button {
64
  background-color: #4A90E2;
@@ -85,35 +108,22 @@ custom_css = """
85
  demo = gr.Blocks(css=custom_css, theme=gr.themes.Soft())
86
  with demo:
87
  gr.Markdown("""
88
- ## 🎨 Uni-Imaginator
89
- **Create professional, e-commerce–ready product images effortlessly.**
90
  """)
91
  with gr.Row(elem_id="input-row"):
92
  with gr.Column(scale=1):
93
- input_image = gr.Image(
94
- type="pil", label="Upload Product Image", elem_id="upload-img",
95
- interactive=True
96
- )
97
- product_name = gr.Textbox(
98
- label="Product Name", placeholder="Enter your product's name here",
99
- elem_id="product-name"
100
- )
101
- generate_button = gr.Button(
102
- "Generate Images", variant="primary", elem_id="generate-button"
103
- )
104
  with gr.Column(scale=1):
105
  gr.Markdown("""
106
  **How to Use:**
107
  1. Upload a clear photo of your product.
108
  2. Enter the product name.
109
- 3. Click **Generate Images** to see a gallery of styled product shots.
110
  """)
111
- gallery = gr.Gallery(
112
- label="Generated Images", elem_id="gallery",
113
- columns=4, object_fit="contain", height="auto", show_label=False
114
- )
115
- generate_button.click(
116
- fn=generate_images, inputs=[input_image, product_name], outputs=gallery
117
- )
118
 
119
  demo.launch()
 
6
  import tempfile
7
  import concurrent.futures
8
  import os
9
+ import time
10
+ from threading import Lock
11
 
12
+ # Load API credentials from environment
13
+ api_key = os.environ.get("API_KEY")
14
+ univin_model = os.environ.get("univin")
15
  client = genai.Client(api_key=api_key)
16
 
17
+ # Rate limiting: maximum 10 calls per minute (one call every 6 seconds)
18
+ CALL_INTERVAL = 60.0 / 10.0 # seconds
19
+ dt_lock = Lock()
20
+ _last_call_time = 0.0
21
+
22
+ def throttle():
23
+ global _last_call_time
24
+ with dt_lock:
25
+ now = time.time()
26
+ elapsed = now - _last_call_time
27
+ if elapsed < CALL_INTERVAL:
28
+ time.sleep(CALL_INTERVAL - elapsed)
29
+ _last_call_time = time.time()
30
+
31
+ # Detailed prompt variations for different backgrounds/angles
32
+ after = "..." # placeholder to show continuation; see full PROMPT_VARIATIONS in code
33
  PROMPT_VARIATIONS = [
34
  # 1: White background
35
  "Chain-of-Thought: Step 1: Carefully analyze the input image and document every single detail of the product—text, colour, material finish, branding, dimensions, and any embellishments—ensuring no detail is overlooked. Step 2: Generate a highly professional 800×800px image with a pure white background and bright natural lighting, strictly preserving the product’s text, colour, shape and finish exactly as in the original image, with zero alterations. Step 3: Rigorously verify pixel-by-pixel that the output matches the original product data 100 %, then deliver a ready-for-e-commerce upload image.",
36
+ # 2: Garden background
37
  "Chain-of-Thought: Step 1: Meticulously analyze the input image and record every product detail—text, colour, material finish, branding, dimensions, texture, and any embellishments—ensuring nothing is overlooked. Step 2: Generate a highly professional 800×800px image of the product from a precise 45° top-down angle against a green garden background with even lighting, strictly preserving the product’s text, colours, shape and finish exactly as in the original image, with zero alterations. Step 3: Perform a rigorous pixel-level comparison to confirm 100 % fidelity to the original product data and deliver an e-commerce–ready image.",
38
+ # 3: Modern indoor
39
  "Chain-of-Thought: Step 1: Scrutinize the input image to record every element of the product—text, colour palette, material finish, and branding—without exception. Step 2: Generate a highly professional 800×800px image from a slightly elevated angle and open lid if the product have a lid in a modern indoor setting with warm lighting, strictly preserving the product’s original text, colours and all details exactly as in the source. Step 3: Double-check at full resolution that no aspect of the product has been altered and that the image is e-commerce ready.",
40
+ # 4: Spa-like setting
41
  "Chain-of-Thought: Step 1: Analyze the input image pixel-for-pixel to note every product detail—text, colour, texture, finish, branding and proportions—ensuring nothing is missed. Step 2: Generate a highly professional 800×800px image using a A serene, spa-like setting with elements of tranquility like smooth stones, bamboo, and a calming water feature, ideal for wellness or beauty products. background, with the product’s text, colours, materials and details preserved exactly as in the original. Step 3: Verify 100 % fidelity at the pixel level and confirm readiness for online catalog upload.",
42
+ # 5: Vibrant outdoor
43
  "Chain-of-Thought: Step 1: Inspect the input image meticulously and record every detail—text, colour gradients, material texture, and branding—ensuring total accuracy. Step 2: Generate a highly professional 800×800px image with a vibrant outdoor background and natural sunlight, strictly preserving the product’s original text, colours, finish and all details unchanged. Step 3: Validate that the final image is flawless, matches the original exactly, and is optimized for e-commerce display.",
44
+ # 6: Gradient background
45
  "Chain-of-Thought: Step 1: Review the input image thoroughly, capturing and logging every detail—text, colour accuracy, surface finish, and branding—100 % intact. Step 2: Generate a highly professional 800×800px image with a subtle gradient background and soft diffused lighting, ensuring that the product’s text, colours and all design details remain precisely as in the source. Step 3: Perform a pixel-level check to confirm no alterations and that the image meets e-commerce quality standards.",
46
+ # 7: Abstract background
47
  "Chain-of-Thought: Step 1: Examine the original product image in depth, noting every detail—text, colour tones, material texture, branding logos and dimensions—with absolute precision. Step 2: Generate a highly professional 800×800px image featuring an abstract background with perfect lighting, strictly preserving the product’s text, colours and every fine detail exactly as in the original. Step 3: Verify pixel-perfect fidelity and confirm the output is upload-ready for an online store.",
48
+ # 8: Lifestyle setting
49
  "Chain-of-Thought: Step 1: Scrutinize the input image in full detail, logging every aspect of the product—text, colour accuracy, branding, material texture, finish, and proportions—to guarantee total fidelity. Step 2: Generate a highly professional 800×800px image of the product placed A cozy, homely setting with a comfortable, inviting ambiance, featuring elements like soft lighting, plush textiles, and warm tones, suitable for home goods or comfort products. ensuring that the product’s text, colours, materials and every detail remain exactly as in the original image without any modification. Step 3: Validate at the pixel level that the output matches the original image perfectly and confirm readiness for online catalog upload.",
50
  ]
51
 
52
  def process_variation(variation, input_image, product_name):
53
+ # Throttle to respect API rate limit
54
+ throttle()
55
  text_input = (
56
  f"Hi, this is a picture of a product. The name of the product is {product_name}.",
57
  variation
58
  )
59
  response = client.models.generate_content(
60
+ model=univin_model,
61
  contents=[text_input, input_image],
62
  config=types.GenerateContentConfig(response_modalities=['Text', 'Image'])
63
  )
64
+ # Extract generated image bytes
65
  for part in response.candidates[0].content.parts:
66
  if part.inline_data is not None:
67
+ img = Image.open(BytesIO(part.inline_data.data))
68
+ # Save to temp file
69
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp:
70
+ img.save(tmp, format="PNG")
71
+ return tmp.name
72
  return None
73
 
74
+
75
  def generate_images(input_image, product_name):
76
  with concurrent.futures.ThreadPoolExecutor() as executor:
77
  futures = [
78
+ executor.submit(process_variation, var, input_image, product_name)
79
+ for var in PROMPT_VARIATIONS
80
  ]
81
+ # Collect successful outputs
82
+ return [f.result() for f in futures if f.result() is not None]
83
 
84
+ # Gradio UI setup
85
  custom_css = """
86
  #generate-button {
87
  background-color: #4A90E2;
 
108
  demo = gr.Blocks(css=custom_css, theme=gr.themes.Soft())
109
  with demo:
110
  gr.Markdown("""
111
+ ## 🎨 Uni-Imaginator (Rate-Limited)
112
+ **Create professional, e-commerce–ready product images effortlessly—now respecting API rate limits.**
113
  """)
114
  with gr.Row(elem_id="input-row"):
115
  with gr.Column(scale=1):
116
+ input_image = gr.Image(type="pil", label="Upload Product Image", elem_id="upload-img")
117
+ product_name = gr.Textbox(label="Product Name", placeholder="Enter your product's name here", elem_id="product-name")
118
+ generate_button = gr.Button("Generate Images", variant="primary", elem_id="generate-button")
 
 
 
 
 
 
 
 
119
  with gr.Column(scale=1):
120
  gr.Markdown("""
121
  **How to Use:**
122
  1. Upload a clear photo of your product.
123
  2. Enter the product name.
124
+ 3. Click **Generate Images** and wait a few moments while images are processed within rate limits.
125
  """)
126
+ gallery = gr.Gallery(label="Generated Images", elem_id="gallery", columns=4, object_fit="contain", height="auto", show_label=False)
127
+ generate_button.click(fn=generate_images, inputs=[input_image, product_name], outputs=gallery)
 
 
 
 
 
128
 
129
  demo.launch()