YUVALON commited on
Commit
b6d4759
Β·
verified Β·
1 Parent(s): 8da7a7f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +278 -200
app.py CHANGED
@@ -24,271 +24,349 @@ except Exception as e:
24
  pad_token_id=50256
25
  )
26
 
27
- def create_short_caption(text, max_words=5):
28
- """Ensure caption is max 5 words"""
29
- words = text.split()
30
- if len(words) <= max_words:
31
- return text
32
- return ' '.join(words[:max_words])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- def generate_instagram_caption(description):
35
  """Generate 5 short, catchy Instagram captions (max 5 words each)"""
36
  if not description.strip():
37
  return "Please enter a description of your photo!"
38
 
39
- # Set a random seed for variety
40
- set_seed(random.randint(1, 10000))
41
-
42
- # Cool and catchy caption templates (will be trimmed to 5 words)
43
- cool_templates = [
44
  "Squad goals right here",
 
45
  "Living our best life",
46
- "Good vibes only always",
47
  "Making memories with favorites",
48
- "This crew hits different",
49
- "Unstoppable energy with besties",
50
- "Main character energy activated",
51
- "Plot twist we're legendary",
52
- "Caught being absolutely iconic",
53
- "Serving looks and laughs",
54
- "That golden hour magic",
55
- "Friendship level absolutely maximum",
56
- "Current mood pure happiness",
57
- "Creating chaos looking cute",
58
- "Weekend warriors in action",
59
- "Living proof dreams work",
60
- "Grateful for these humans",
61
- "When life gets good",
62
- "Positive vibes attract everything",
63
- "Making ordinary moments special"
 
 
 
 
 
 
 
 
 
 
64
  ]
65
 
66
- # Generate captions based on description context
67
- captions = []
68
-
69
- # Try to generate some with AI
70
  for i in range(3):
71
- try:
72
- prompt = f"Cool Instagram caption for {description}:"
73
- generated = generator(
74
- prompt,
75
- max_length=len(prompt.split()) + 8,
76
- num_return_sequences=1,
77
- temperature=0.9,
78
- do_sample=True,
79
- top_p=0.95,
80
- repetition_penalty=1.2,
81
- pad_token_id=50256
82
- )
83
-
84
- full_text = generated[0]['generated_text']
85
- caption_text = full_text.replace(prompt, "").strip()
86
-
87
- # Clean and shorten
88
- caption_text = caption_text.strip('"\'').strip()
89
- if caption_text and len(caption_text) > 3:
90
- short_caption = create_short_caption(caption_text, 5)
91
- if short_caption not in captions:
92
- captions.append(short_caption)
93
-
94
- except Exception as e:
95
- print(f"Generation error: {e}")
96
- continue
97
 
98
- # Add cool predefined captions
99
- random.shuffle(cool_templates)
100
- for template in cool_templates:
101
- if len(captions) >= 5:
102
- break
103
- short_caption = create_short_caption(template, 5)
104
- if short_caption not in captions:
105
- captions.append(short_caption)
106
 
107
- # Context-specific captions based on description
108
- context_captions = []
109
- desc_lower = description.lower()
110
 
111
- if any(word in desc_lower for word in ['friend', 'group', 'squad', 'crew', 'team', 'gang']):
112
- context_captions = [
113
- "Squad goals achieved today",
114
- "Friends who slay together",
115
- "Main character energy activated",
116
- "Chaos creators looking cute",
117
- "Weekend warriors in action"
118
- ]
119
- elif any(word in desc_lower for word in ['sunset', 'beach', 'ocean', 'water']):
120
- context_captions = [
121
- "Chasing sunsets and dreams",
122
- "Salt air good vibes",
123
- "Beach therapy session complete",
124
- "Ocean child energy activated",
125
- "Waves and good times"
126
- ]
127
- elif any(word in desc_lower for word in ['coffee', 'morning', 'work', 'laptop']):
128
- context_captions = [
129
- "Morning hustle mode on",
130
- "Coffee powered productivity session",
131
- "Grinding with good vibes",
132
- "Main character work energy",
133
- "Caffeine and determination daily"
134
- ]
135
- elif any(word in desc_lower for word in ['food', 'dinner', 'eating', 'restaurant']):
136
- context_captions = [
137
- "Good food better company",
138
- "Eating our way happy",
139
- "Dinner dates hit different",
140
- "Food coma incoming soon",
141
- "Taste buds officially satisfied"
142
- ]
143
- elif any(word in desc_lower for word in ['adventure', 'hiking', 'mountain', 'nature']):
144
- context_captions = [
145
- "Adventure mode fully activated",
146
- "Mountain therapy session complete",
147
- "Nature calls we answer",
148
- "Hiking boots happy feet",
149
- "Views and good vibes"
150
- ]
151
 
152
- # Add context-specific captions
153
- for context_cap in context_captions:
154
- if len(captions) >= 5:
155
- break
156
- short_caption = create_short_caption(context_cap, 5)
157
- if short_caption not in captions:
158
- captions.append(short_caption)
159
-
160
- # Ensure we have exactly 5 captions
161
- universal_captions = [
162
- "Living our best life",
163
- "Good vibes only always",
164
- "Making memories count today",
165
- "Plot twist we're iconic",
166
- "Current mood pure happiness",
167
- "Grateful for these moments",
168
- "Creating magic happening now",
169
- "Weekend warrior energy activated",
170
- "Positive vibes attract everything",
171
- "This crew hits different"
172
- ]
173
-
174
- for universal_cap in universal_captions:
175
- if len(captions) >= 5:
176
- break
177
- short_caption = create_short_caption(universal_cap, 5)
178
- if short_caption not in captions:
179
- captions.append(short_caption)
180
-
181
- # Return exactly 5 captions
182
- final_captions = captions[:5]
183
 
184
  # Format as numbered list
185
  result = ""
186
- for i, caption in enumerate(final_captions, 1):
187
  result += f"{i}. {caption}\n"
188
 
189
  return result.strip()
190
 
191
- # Create the Gradio interface
192
- with gr.Blocks(
193
- theme=gr.themes.Soft(),
194
- css="""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  .main-header {
196
- text-align: center;
197
- background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1);
198
- -webkit-background-clip: text;
199
- -webkit-text-fill-color: transparent;
200
- font-size: 2.5em;
201
- font-weight: bold;
202
- margin-bottom: 0.5em;
203
- }
204
- .subtitle {
205
- text-align: center;
206
- color: #666;
207
- font-size: 1.1em;
208
- margin-bottom: 2em;
209
  }
210
- .generate-btn {
211
- background: linear-gradient(45deg, #ff6b6b, #4ecdc4) !important;
212
- border: none !important;
213
- color: white !important;
214
- font-weight: bold !important;
215
- font-size: 1.1em !important;
216
- padding: 12px 24px !important;
217
- border-radius: 25px !important;
218
- transition: all 0.3s ease !important;
219
- }
220
- .generate-btn:hover {
221
- transform: translateY(-2px) !important;
222
- box-shadow: 0 5px 15px rgba(0,0,0,0.2) !important;
223
  }
224
- """
 
 
 
 
 
 
 
 
 
 
225
  ) as demo:
226
 
227
- gr.HTML('<h1 class="main-header">πŸ“Έ Instacap – AI Instagram Caption Generator</h1>')
228
- gr.HTML('<p class="subtitle">Transform your photo descriptions into short, catchy Instagram captions!</p>')
229
 
230
  with gr.Row():
231
- with gr.Column(scale=1):
232
  description_input = gr.Textbox(
233
- label="Describe your photo",
234
- placeholder="E.g., group photo with friends, sunset beach picnic, coffee shop vibes",
235
  lines=3,
236
- max_lines=5
 
237
  )
238
 
239
  generate_btn = gr.Button(
240
- "Generate Caption ✨",
241
  variant="primary",
242
  elem_classes="generate-btn"
243
  )
244
 
245
- with gr.Column(scale=1):
246
  caption_output = gr.Textbox(
247
- label="Your 5 Short & Catchy Captions (Max 5 words each)",
248
  lines=8,
249
  max_lines=10,
250
  interactive=False,
251
- show_copy_button=True
 
252
  )
253
 
254
- # Add some example inputs
255
  gr.Examples(
256
  examples=[
257
- ["group photo with friends laughing"],
258
- ["sunset beach picnic, cozy vibe"],
259
- ["coffee shop laptop work, productive morning"],
260
- ["hiking mountain trail, adventure time"],
261
- ["friends dinner party, good food"],
262
- ["morning yoga session, peaceful zen"],
263
- ["city skyline night view, urban lights"],
264
- ["weekend brunch with squad, happy vibes"]
265
  ],
266
  inputs=description_input,
267
  outputs=caption_output,
268
- fn=generate_instagram_caption,
269
- cache_examples=False
 
270
  )
271
 
272
  # Connect the button to the function
273
  generate_btn.click(
274
- fn=generate_instagram_caption,
275
  inputs=description_input,
276
  outputs=caption_output
277
  )
278
 
279
  # Also trigger on Enter key
280
  description_input.submit(
281
- fn=generate_instagram_caption,
282
  inputs=description_input,
283
  outputs=caption_output
284
  )
285
 
286
  gr.HTML(
287
  """
288
- <div style="text-align: center; margin-top: 2em; color: #888; font-size: 0.9em;">
289
- <p>πŸ’‘ Tip: Be specific for better context-matched captions!</p>
290
- <p>🎨 Get 5 short, catchy captions (max 5 words each)</p>
291
- <p>πŸ“‹ Perfect for group photos, adventures, and good vibes!</p>
 
 
292
  </div>
293
  """
294
  )
 
24
  pad_token_id=50256
25
  )
26
 
27
+ def generate_short_caption(description):
28
+ """Generate a short, catchy caption (max 5 words)"""
29
+ if not description.strip():
30
+ return ""
31
+
32
+ # Set random seed for variety
33
+ set_seed(random.randint(1, 10000))
34
+
35
+ # Short prompt templates for 5-word captions
36
+ prompts = [
37
+ f"Photo: {description}\nShort caption: Squad",
38
+ f"Photo: {description}\nCool caption: Good",
39
+ f"Photo: {description}\nCatchy caption: Living",
40
+ f"Photo: {description}\nFun caption: Making",
41
+ f"Photo: {description}\nTrendy caption: Caught"
42
+ ]
43
+
44
+ prompt = random.choice(prompts)
45
+
46
+ try:
47
+ generated = generator(
48
+ prompt,
49
+ max_length=len(prompt.split()) + 8, # Very short
50
+ num_return_sequences=1,
51
+ temperature=0.9,
52
+ do_sample=True,
53
+ top_p=0.95,
54
+ repetition_penalty=1.2,
55
+ pad_token_id=50256
56
+ )
57
+
58
+ full_text = generated[0]['generated_text']
59
+ caption = full_text.replace(prompt, "").strip()
60
+
61
+ # Clean and limit to 5 words
62
+ if caption:
63
+ words = caption.split()[:5]
64
+ if len(words) >= 2:
65
+ return " ".join(words)
66
+
67
+ except Exception as e:
68
+ print(f"Generation error: {e}")
69
+
70
+ return ""
71
 
72
+ def generate_instagram_captions(description):
73
  """Generate 5 short, catchy Instagram captions (max 5 words each)"""
74
  if not description.strip():
75
  return "Please enter a description of your photo!"
76
 
77
+ # Cool short captions for different vibes
78
+ cool_captions = [
 
 
 
79
  "Squad goals right here",
80
+ "Good vibes only today",
81
  "Living our best life",
 
82
  "Making memories with favorites",
83
+ "Caught in the moment",
84
+ "Friends like these though",
85
+ "Energy levels unmatched today",
86
+ "Vibes on point always",
87
+ "Good times roll forever",
88
+ "Squad up for success",
89
+ "Living for these moments",
90
+ "Making magic happen daily",
91
+ "Catching feelings and sunsets",
92
+ "Good company great memories",
93
+ "Squad deeper than ocean",
94
+ "Vibes immaculate as always",
95
+ "Energy infectious spread it",
96
+ "Good times never ending",
97
+ "Making waves together always",
98
+ "Caught smiling too much",
99
+ "Living life in color",
100
+ "Squad goals achieved today",
101
+ "Good vibes attract everything",
102
+ "Making moments matter most",
103
+ "Catching dreams with crew",
104
+ "Living loud loving harder",
105
+ "Squad tight bond stronger",
106
+ "Good energy good people",
107
+ "Making memories worth keeping",
108
+ "Caught being absolutely legendary"
109
  ]
110
 
111
+ # Generate some AI captions
112
+ ai_captions = []
 
 
113
  for i in range(3):
114
+ caption = generate_short_caption(description)
115
+ if caption:
116
+ ai_captions.append(caption)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
+ # Combine AI and predefined captions
119
+ all_captions = ai_captions + cool_captions
 
 
 
 
 
 
120
 
121
+ # Select 5 random captions
122
+ selected_captions = random.sample(all_captions, min(5, len(all_captions)))
 
123
 
124
+ # Ensure each caption is max 5 words
125
+ final_captions = []
126
+ for caption in selected_captions:
127
+ words = caption.split()[:5]
128
+ if len(words) >= 2:
129
+ final_captions.append(" ".join(words))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
+ # Fill with defaults if needed
132
+ while len(final_captions) < 5:
133
+ fallback = random.choice(cool_captions)
134
+ words = fallback.split()[:5]
135
+ final_caption = " ".join(words)
136
+ if final_caption not in final_captions:
137
+ final_captions.append(final_caption)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
  # Format as numbered list
140
  result = ""
141
+ for i, caption in enumerate(final_captions[:5], 1):
142
  result += f"{i}. {caption}\n"
143
 
144
  return result.strip()
145
 
146
+ # Instagram-inspired theme with custom CSS
147
+ instagram_css = """
148
+ /* Instagram color scheme */
149
+ :root {
150
+ --ig-primary: #E4405F;
151
+ --ig-secondary: #833AB4;
152
+ --ig-tertiary: #F77737;
153
+ --ig-quaternary: #FCAF45;
154
+ --ig-blue: #405DE6;
155
+ --ig-bg: #FAFAFA;
156
+ --ig-text: #262626;
157
+ --ig-border: #DBDBDB;
158
+ }
159
+
160
+ /* Main container styling */
161
+ .gradio-container {
162
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
163
+ min-height: 100vh;
164
+ }
165
+
166
+ /* Header styling */
167
+ .main-header {
168
+ text-align: center;
169
+ background: linear-gradient(45deg, var(--ig-primary), var(--ig-secondary), var(--ig-tertiary), var(--ig-quaternary));
170
+ -webkit-background-clip: text;
171
+ -webkit-text-fill-color: transparent;
172
+ background-clip: text;
173
+ font-size: 3em;
174
+ font-weight: 900;
175
+ margin-bottom: 0.5em;
176
+ text-shadow: 0 2px 4px rgba(0,0,0,0.1);
177
+ }
178
+
179
+ .subtitle {
180
+ text-align: center;
181
+ color: white;
182
+ font-size: 1.2em;
183
+ margin-bottom: 2em;
184
+ text-shadow: 0 1px 2px rgba(0,0,0,0.3);
185
+ }
186
+
187
+ /* Card styling */
188
+ .card {
189
+ background: rgba(255, 255, 255, 0.95) !important;
190
+ border-radius: 20px !important;
191
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1) !important;
192
+ backdrop-filter: blur(10px) !important;
193
+ border: 1px solid rgba(255,255,255,0.2) !important;
194
+ padding: 2rem !important;
195
+ margin: 1rem !important;
196
+ }
197
+
198
+ /* Input styling */
199
+ .gr-textbox {
200
+ border-radius: 15px !important;
201
+ border: 2px solid var(--ig-border) !important;
202
+ transition: all 0.3s ease !important;
203
+ }
204
+
205
+ .gr-textbox:focus {
206
+ border-color: var(--ig-primary) !important;
207
+ box-shadow: 0 0 0 3px rgba(228, 64, 95, 0.1) !important;
208
+ }
209
+
210
+ /* Button styling */
211
+ .generate-btn {
212
+ background: linear-gradient(45deg, var(--ig-primary), var(--ig-secondary)) !important;
213
+ border: none !important;
214
+ color: white !important;
215
+ font-weight: bold !important;
216
+ font-size: 1.2em !important;
217
+ padding: 15px 30px !important;
218
+ border-radius: 25px !important;
219
+ transition: all 0.3s ease !important;
220
+ box-shadow: 0 4px 15px rgba(228, 64, 95, 0.3) !important;
221
+ }
222
+
223
+ .generate-btn:hover {
224
+ transform: translateY(-3px) !important;
225
+ box-shadow: 0 8px 25px rgba(228, 64, 95, 0.4) !important;
226
+ background: linear-gradient(45deg, var(--ig-secondary), var(--ig-primary)) !important;
227
+ }
228
+
229
+ /* Output styling */
230
+ .output-box {
231
+ background: rgba(255, 255, 255, 0.9) !important;
232
+ border-radius: 15px !important;
233
+ border: 2px solid var(--ig-border) !important;
234
+ font-family: 'Instagram Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
235
+ font-size: 1.1em !important;
236
+ line-height: 1.6 !important;
237
+ }
238
+
239
+ /* Examples styling */
240
+ .gr-examples {
241
+ background: rgba(255, 255, 255, 0.8) !important;
242
+ border-radius: 15px !important;
243
+ padding: 1rem !important;
244
+ margin-top: 1rem !important;
245
+ }
246
+
247
+ .gr-examples .gr-button {
248
+ background: linear-gradient(45deg, var(--ig-tertiary), var(--ig-quaternary)) !important;
249
+ border: none !important;
250
+ border-radius: 10px !important;
251
+ color: white !important;
252
+ margin: 0.25rem !important;
253
+ transition: all 0.3s ease !important;
254
+ }
255
+
256
+ .gr-examples .gr-button:hover {
257
+ transform: translateY(-2px) !important;
258
+ box-shadow: 0 4px 12px rgba(0,0,0,0.2) !important;
259
+ }
260
+
261
+ /* Tips section */
262
+ .tips-section {
263
+ background: rgba(255, 255, 255, 0.9) !important;
264
+ border-radius: 15px !important;
265
+ padding: 1.5rem !important;
266
+ margin-top: 2rem !important;
267
+ text-align: center !important;
268
+ box-shadow: 0 4px 20px rgba(0,0,0,0.1) !important;
269
+ }
270
+
271
+ .tips-section p {
272
+ color: var(--ig-text) !important;
273
+ font-size: 1em !important;
274
+ margin: 0.5rem 0 !important;
275
+ }
276
+
277
+ /* Mobile responsive */
278
+ @media (max-width: 768px) {
279
  .main-header {
280
+ font-size: 2.2em !important;
 
 
 
 
 
 
 
 
 
 
 
 
281
  }
282
+
283
+ .card {
284
+ margin: 0.5rem !important;
285
+ padding: 1.5rem !important;
 
 
 
 
 
 
 
 
 
286
  }
287
+ }
288
+ """
289
+
290
+ # Create the Gradio interface
291
+ with gr.Blocks(
292
+ theme=gr.themes.Soft(
293
+ primary_hue="red",
294
+ secondary_hue="purple",
295
+ neutral_hue="gray"
296
+ ),
297
+ css=instagram_css
298
  ) as demo:
299
 
300
+ gr.HTML('<h1 class="main-header">πŸ“Έ InstaCap – AI Caption Generator</h1>')
301
+ gr.HTML('<p class="subtitle">Create short, catchy Instagram captions in seconds! ✨</p>')
302
 
303
  with gr.Row():
304
+ with gr.Column(scale=1, elem_classes="card"):
305
  description_input = gr.Textbox(
306
+ label="πŸ“ Describe your photo",
307
+ placeholder="E.g., group photo with friends, sunset vibes, coffee date...",
308
  lines=3,
309
+ max_lines=5,
310
+ elem_classes="gr-textbox"
311
  )
312
 
313
  generate_btn = gr.Button(
314
+ "✨ Generate Captions",
315
  variant="primary",
316
  elem_classes="generate-btn"
317
  )
318
 
319
+ with gr.Column(scale=1, elem_classes="card"):
320
  caption_output = gr.Textbox(
321
+ label="🎯 Your 5 Short Captions (Max 5 Words Each)",
322
  lines=8,
323
  max_lines=10,
324
  interactive=False,
325
+ show_copy_button=True,
326
+ elem_classes="output-box"
327
  )
328
 
329
+ # Add examples with Instagram-style descriptions
330
  gr.Examples(
331
  examples=[
332
+ ["group photo with best friends"],
333
+ ["sunset beach vibes together"],
334
+ ["coffee date good times"],
335
+ ["squad night out fun"],
336
+ ["adventure hiking with crew"],
337
+ ["cozy indoor friend hangout"],
338
+ ["party celebration with everyone"],
339
+ ["weekend brunch with favorites"]
340
  ],
341
  inputs=description_input,
342
  outputs=caption_output,
343
+ fn=generate_instagram_captions,
344
+ cache_examples=False,
345
+ elem_classes="gr-examples"
346
  )
347
 
348
  # Connect the button to the function
349
  generate_btn.click(
350
+ fn=generate_instagram_captions,
351
  inputs=description_input,
352
  outputs=caption_output
353
  )
354
 
355
  # Also trigger on Enter key
356
  description_input.submit(
357
+ fn=generate_instagram_captions,
358
  inputs=description_input,
359
  outputs=caption_output
360
  )
361
 
362
  gr.HTML(
363
  """
364
+ <div class="tips-section">
365
+ <p>πŸ’‘ <strong>Pro Tips:</strong></p>
366
+ <p>🎯 Each caption is max 5 words for maximum impact</p>
367
+ <p>⚑ Perfect for group photos, adventures, and good vibes</p>
368
+ <p>πŸ“± Copy and paste directly to Instagram</p>
369
+ <p>πŸ”„ Generate again for new options</p>
370
  </div>
371
  """
372
  )