mroccuper commited on
Commit
438e750
·
verified ·
1 Parent(s): 15ee1ac

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +151 -113
app.py CHANGED
@@ -48,18 +48,14 @@ Use these specific keywords in your listing: {keywords}
48
 
49
  Respond ONLY with a JSON object in this format:
50
  {{
51
- "title": "Title text here",
52
- "brand_name": "Brand name here",
53
- "bullet_point_1": "Bullet point 1 text here",
54
- "bullet_point_2": "Bullet point 2 text here",
55
- "suggested_keywords": "Comma separated list of 5 additional keywords"
56
  }}
57
 
58
- The output must follow these exact character counts:
59
- - Title: Exactly 60 characters
60
- - Brand Name: Between 34-50 characters
61
- - Bullet Point 1: Between 240-256 characters
62
- - Bullet Point 2: Between 240-256 characters"""
63
 
64
  return combined_prompt
65
 
@@ -84,126 +80,146 @@ All titles must be exactly 60 characters and brand names between 34-50 character
84
  Respond ONLY with a JSON object in this format:
85
  {{
86
  "title_variations": [
87
- "Title variation 1 text here (exactly 60 characters)",
88
- "Title variation 2 text here (exactly 60 characters)",
89
- "Title variation 3 text here (exactly 60 characters)"
90
  ],
91
  "brand_name_variations": [
92
- "Brand name variation 1 here (34-50 characters)",
93
- "Brand name variation 2 here (34-50 characters)",
94
- "Brand name variation 3 here (34-50 characters)"
95
  ]
96
- }}"""
 
 
97
 
98
  return combined_prompt
99
 
100
  def generate_amazon_listing(api_key, quote, niche, target, keywords):
101
  """Generate Amazon listing using Gemini API."""
 
 
 
 
 
 
102
  try:
103
  # Configure the Gemini API with the provided key
104
  genai.configure(api_key=api_key)
105
- model = genai.GenerativeModel('gemini-1.5-pro')
106
-
107
- # Generate the main listing
108
- prompt = generate_prompt(quote, niche, target, keywords)
109
 
110
- response = model.generate_content(
111
- prompt,
 
112
  generation_config={
113
- "temperature": 0.3, # Lower temperature for more focused results
114
  "top_p": 0.8,
115
- "max_output_tokens": 2048
116
  }
117
  )
118
 
119
- # Extract JSON from the response
120
- response_text = response.text
121
- match = re.search(r'{.*}', response_text, re.DOTALL)
122
- if match:
 
 
 
 
 
 
 
 
 
123
  json_str = match.group(0)
124
  try:
125
  result = json.loads(json_str)
 
 
126
 
127
- # Validate that the output actually matches the input criteria
128
- title = result.get("title", "")
129
- if not (quote.lower() in title.lower() or
130
- niche.lower() in title.lower() or
131
- any(t.lower() in title.lower() for t in target.lower().split(','))):
132
- return f"Error: Generated title doesn't match the requested theme: '{quote}', '{niche}', or '{target}'. Please try again."
133
-
134
- # Validate bullet point lengths
135
- bullet1 = result.get("bullet_point_1", "")
136
- bullet2 = result.get("bullet_point_2", "")
137
-
138
- if len(bullet1) < 240 or len(bullet1) > 256:
139
- return f"Error: Bullet point 1 length ({len(bullet1)}) is not between 240-256 characters. Please try again."
140
-
141
- if len(bullet2) < 240 or len(bullet2) > 256:
142
- return f"Error: Bullet point 2 length ({len(bullet2)}) is not between 240-256 characters. Please try again."
143
-
144
- # Check for generic content in bullet points
145
- generic_phrases = ["premium quality", "high-quality materials", "soft feel", "long-lasting wear",
146
- "comfortable and stylish", "perfect gift", "great gift"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
- for phrase in generic_phrases:
149
- if phrase in bullet1.lower() or phrase in bullet2.lower():
150
- return f"Error: Generated bullet points contain generic phrase '{phrase}'. Please try again."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
- except json.JSONDecodeError:
153
- return "Error parsing JSON response from Gemini API"
154
- else:
155
- return "Could not extract JSON from Gemini API response"
156
-
157
- # Generate variations
158
- variations_prompt = generate_multiple_variations_prompt(quote, niche, target, keywords)
159
- response_var = model.generate_content(
160
- variations_prompt,
161
- generation_config={
162
- "temperature": 0.4, # Lower temperature for more focused results
163
- "top_p": 0.8,
164
- "max_output_tokens": 2048
165
- }
166
- )
167
-
168
- # Extract JSON from the variations response
169
- response_var_text = response_var.text
170
- match_var = re.search(r'{.*}', response_var_text, re.DOTALL)
171
- if match_var:
172
- json_str_var = match_var.group(0)
173
- try:
174
- variations = json.loads(json_str_var)
175
- except json.JSONDecodeError:
176
- variations = {
177
- "title_variations": ["Error generating variations"],
178
- "brand_name_variations": ["Error generating variations"]
179
- }
180
- else:
181
- variations = {
182
- "title_variations": ["Error generating variations"],
183
- "brand_name_variations": ["Error generating variations"]
184
- }
185
-
186
- # Format main output
187
- main_output = format_output(
188
- result.get("title", "Error generating title"),
189
- result.get("brand_name", "Error generating brand name"),
190
- result.get("bullet_point_1", "Error generating bullet point 1"),
191
- result.get("bullet_point_2", "Error generating bullet point 2"),
192
- result.get("suggested_keywords", "Error generating suggested keywords")
193
- )
194
-
195
- # Format variations output
196
- variations_output = "ADDITIONAL VARIATIONS:\n\n"
197
- variations_output += "Title Variations:\n"
198
- for i, var in enumerate(variations.get("title_variations", []), 1):
199
- variations_output += f"{i}. {var} ({count_characters(var)}/60 characters)\n"
200
-
201
- variations_output += "\nBrand Name Variations:\n"
202
- for i, var in enumerate(variations.get("brand_name_variations", []), 1):
203
- variations_output += f"{i}. {var} ({count_characters(var)}/50 characters)\n"
204
-
205
- return main_output + "\n\n" + variations_output
206
-
207
  except Exception as e:
208
  return f"Error: {str(e)}"
209
 
@@ -216,19 +232,34 @@ def create_interface():
216
  with gr.Row():
217
  with gr.Column():
218
  api_key = gr.Textbox(label="Gemini API Key", placeholder="Enter your Gemini API key", type="password")
219
- quote = gr.Textbox(label="Quote/Design/Idea", placeholder="Enter the quote or design idea")
220
- niche = gr.Textbox(label="Holiday/Event", placeholder="Enter the holiday or event (e.g., St Patrick's Day)")
221
- target = gr.Textbox(label="Target Audience", placeholder="Teacher, Mom, Dad, etc.")
222
- keywords = gr.Textbox(label="Target Keywords", placeholder="Enter keywords separated by commas", lines=5)
223
  submit_btn = gr.Button("Generate Amazon Listing", variant="primary")
224
 
225
  with gr.Column():
 
226
  output = gr.Textbox(label="Generated Amazon Listing", lines=25)
227
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  submit_btn.click(
229
- fn=generate_amazon_listing,
230
  inputs=[api_key, quote, niche, target, keywords],
231
- outputs=output
 
232
  )
233
 
234
  gr.Markdown("## Example Input")
@@ -241,6 +272,13 @@ Keywords: lucky, teacher, rainbow, st, patricks, day, t-shirt, patrick's, outfit
241
  ```
242
  ''')
243
 
 
 
 
 
 
 
 
244
  return app
245
 
246
  # Create and launch the app
 
48
 
49
  Respond ONLY with a JSON object in this format:
50
  {{
51
+ "title": "The title with exactly 60 characters",
52
+ "brand_name": "Brand name between 34-50 characters",
53
+ "bullet_point_1": "First bullet point between 240-256 characters that focuses on the design and theme",
54
+ "bullet_point_2": "Second bullet point between 240-256 characters that focuses on the design and theme",
55
+ "suggested_keywords": "5 additional keywords separated by commas"
56
  }}
57
 
58
+ REMINDER: Make sure to count the characters carefully. Title should be EXACTLY 60 characters. Bullet points should be between 240-256 characters."""
 
 
 
 
59
 
60
  return combined_prompt
61
 
 
80
  Respond ONLY with a JSON object in this format:
81
  {{
82
  "title_variations": [
83
+ "Title variation 1 - exactly 60 characters, count carefully",
84
+ "Title variation 2 - exactly 60 characters, count carefully",
85
+ "Title variation 3 - exactly 60 characters, count carefully"
86
  ],
87
  "brand_name_variations": [
88
+ "Brand name variation 1 (34-50 characters)",
89
+ "Brand name variation 2 (34-50 characters)",
90
+ "Brand name variation 3 (34-50 characters)"
91
  ]
92
+ }}
93
+
94
+ REMINDER: Make sure each title is EXACTLY 60 characters. Count carefully!"""
95
 
96
  return combined_prompt
97
 
98
  def generate_amazon_listing(api_key, quote, niche, target, keywords):
99
  """Generate Amazon listing using Gemini API."""
100
+ # Input validation
101
+ if not api_key:
102
+ return "Error: Please enter a valid Gemini API key"
103
+ if not quote or not niche or not target:
104
+ return "Error: Please fill in all required fields (Quote, Holiday/Event, and Target Audience)"
105
+
106
  try:
107
  # Configure the Gemini API with the provided key
108
  genai.configure(api_key=api_key)
 
 
 
 
109
 
110
+ # Create model with optimized settings
111
+ model = genai.GenerativeModel(
112
+ 'gemini-1.5-pro',
113
  generation_config={
114
+ "temperature": 0.3,
115
  "top_p": 0.8,
116
+ "max_output_tokens": 1024, # Reduced for faster response
117
  }
118
  )
119
 
120
+ # Generate the main listing
121
+ prompt = generate_prompt(quote, niche, target, keywords)
122
+
123
+ try:
124
+ # First try to get just the main listing for faster response
125
+ response = model.generate_content(prompt)
126
+
127
+ # Extract JSON from the response
128
+ response_text = response.text
129
+ match = re.search(r'{.*}', response_text, re.DOTALL)
130
+ if not match:
131
+ return "Error: Could not extract JSON from Gemini API response. Please try again."
132
+
133
  json_str = match.group(0)
134
  try:
135
  result = json.loads(json_str)
136
+ except json.JSONDecodeError:
137
+ return "Error parsing JSON response from Gemini API. Please try again."
138
 
139
+ # Validate that the output actually matches the input criteria
140
+ title = result.get("title", "")
141
+ if not (quote.lower() in title.lower() or
142
+ niche.lower() in title.lower() or
143
+ any(t.lower() in title.lower() for t in target.lower().split(','))):
144
+ return f"Error: Generated title doesn't match the requested theme: '{quote}', '{niche}', or '{target}'. Please try again."
145
+
146
+ # Validate bullet point lengths
147
+ bullet1 = result.get("bullet_point_1", "")
148
+ bullet2 = result.get("bullet_point_2", "")
149
+
150
+ if len(bullet1) < 240 or len(bullet1) > 256:
151
+ return f"Error: Bullet point 1 length ({len(bullet1)}) is not between 240-256 characters. Please try again."
152
+
153
+ if len(bullet2) < 240 or len(bullet2) > 256:
154
+ return f"Error: Bullet point 2 length ({len(bullet2)}) is not between 240-256 characters. Please try again."
155
+
156
+ # Check for generic content in bullet points
157
+ generic_phrases = ["premium quality", "high-quality materials", "soft feel", "long-lasting wear",
158
+ "comfortable and stylish", "perfect gift", "great gift"]
159
+
160
+ for phrase in generic_phrases:
161
+ if phrase in bullet1.lower() or phrase in bullet2.lower():
162
+ return f"Error: Generated bullet points contain generic phrase '{phrase}'. Please try again."
163
+
164
+ # Format main output first - so we have something to show quickly
165
+ main_output = format_output(
166
+ result.get("title", "Error generating title"),
167
+ result.get("brand_name", "Error generating brand name"),
168
+ result.get("bullet_point_1", "Error generating bullet point 1"),
169
+ result.get("bullet_point_2", "Error generating bullet point 2"),
170
+ result.get("suggested_keywords", "Error generating suggested keywords")
171
+ )
172
+
173
+ # Now try to get variations in a separate call
174
+ try:
175
+ variations_prompt = generate_multiple_variations_prompt(quote, niche, target, keywords)
176
+ response_var = model.generate_content(
177
+ variations_prompt,
178
+ generation_config={
179
+ "temperature": 0.4,
180
+ "top_p": 0.8,
181
+ "max_output_tokens": 1024
182
+ }
183
+ )
184
 
185
+ # Extract JSON from the variations response
186
+ response_var_text = response_var.text
187
+ match_var = re.search(r'{.*}', response_var_text, re.DOTALL)
188
+ if match_var:
189
+ json_str_var = match_var.group(0)
190
+ try:
191
+ variations = json.loads(json_str_var)
192
+
193
+ # Format variations output
194
+ variations_output = "\n\nADDITIONAL VARIATIONS:\n\n"
195
+ variations_output += "Title Variations:\n"
196
+ for i, var in enumerate(variations.get("title_variations", []), 1):
197
+ variations_output += f"{i}. {var} ({count_characters(var)}/60 characters)\n"
198
+
199
+ variations_output += "\nBrand Name Variations:\n"
200
+ for i, var in enumerate(variations.get("brand_name_variations", []), 1):
201
+ variations_output += f"{i}. {var} ({count_characters(var)}/50 characters)\n"
202
+
203
+ # Combine main output with variations
204
+ return main_output + variations_output
205
+
206
+ except json.JSONDecodeError:
207
+ # Return just the main output if we can't parse variations
208
+ return main_output + "\n\n(Could not generate variations)"
209
+ else:
210
+ # Return just the main output if we can't extract JSON for variations
211
+ return main_output + "\n\n(Could not generate variations)"
212
+
213
+ except Exception as var_error:
214
+ # Return just the main output if variations fail
215
+ return main_output + f"\n\n(Could not generate variations: {str(var_error)})"
216
 
217
+ except genai.types.generation_types.BlockedPromptException as e:
218
+ return f"Error: The prompt was blocked by Gemini API safety filters. Please modify your input and try again."
219
+
220
+ except Exception as e:
221
+ return f"Error generating main listing: {str(e)}"
222
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  except Exception as e:
224
  return f"Error: {str(e)}"
225
 
 
232
  with gr.Row():
233
  with gr.Column():
234
  api_key = gr.Textbox(label="Gemini API Key", placeholder="Enter your Gemini API key", type="password")
235
+ quote = gr.Textbox(label="Quote/Design/Idea", placeholder="Enter the quote or design idea", value="")
236
+ niche = gr.Textbox(label="Holiday/Event", placeholder="Enter the holiday or event (e.g., St Patrick's Day)", value="")
237
+ target = gr.Textbox(label="Target Audience", placeholder="Teacher, Mom, Dad, etc.", value="")
238
+ keywords = gr.Textbox(label="Target Keywords", placeholder="Enter keywords separated by commas", lines=5, value="")
239
  submit_btn = gr.Button("Generate Amazon Listing", variant="primary")
240
 
241
  with gr.Column():
242
+ status = gr.Textbox(label="Status", value="Ready to generate listing", interactive=False)
243
  output = gr.Textbox(label="Generated Amazon Listing", lines=25)
244
 
245
+ def on_submit(api_key, quote, niche, target, keywords):
246
+ # Update status first
247
+ yield "Generating listing... Please wait.", output.value
248
+
249
+ # Generate the listing
250
+ result = generate_amazon_listing(api_key, quote, niche, target, keywords)
251
+
252
+ # Update status with completion message
253
+ if "Error" in result:
254
+ yield "Error occurred. See details below.", result
255
+ else:
256
+ yield "Listing generated successfully!", result
257
+
258
  submit_btn.click(
259
+ fn=on_submit,
260
  inputs=[api_key, quote, niche, target, keywords],
261
+ outputs=[status, output],
262
+ show_progress="minimal"
263
  )
264
 
265
  gr.Markdown("## Example Input")
 
272
  ```
273
  ''')
274
 
275
+ gr.Markdown("""
276
+ ## Troubleshooting Tips
277
+ - If you experience timeouts, try using shorter, more specific inputs
278
+ - Make sure your Gemini API key is valid and has sufficient quota
279
+ - The app will prioritize showing the main listing first, then try to generate variations
280
+ """)
281
+
282
  return app
283
 
284
  # Create and launch the app