faizee07 commited on
Commit
ac574a7
Β·
verified Β·
1 Parent(s): f0989e3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +195 -63
app.py CHANGED
@@ -4,14 +4,14 @@ import os
4
  import requests
5
  import random
6
 
7
- # Initialize HF client
8
  def get_client():
 
9
  token = os.environ.get("HF_TOKEN", "")
10
  if not token:
11
  return None, "❌ Add HF_TOKEN to Space Settings β†’ Repository Secrets"
12
  return InferenceClient(token=token), None
13
 
14
- # Meme templates mapping
15
  MEME_TEMPLATES = {
16
  "Drake": "181913649",
17
  "Distracted Boyfriend": "112126428",
@@ -23,6 +23,9 @@ MEME_TEMPLATES = {
23
  "Bad Luck Brian": "61585",
24
  "Philosoraptor": "61516",
25
  "One Does Not Simply": "61579",
 
 
 
26
  }
27
 
28
  def generate_meme_text(idea: str, model: str):
@@ -32,47 +35,74 @@ def generate_meme_text(idea: str, model: str):
32
  return None, None, error
33
 
34
  try:
35
- prompt = f"""Generate meme text for: "{idea}"
36
 
37
- Return ONLY in this exact format:
38
- TOP: [text for top of meme]
39
- BOTTOM: [text for bottom of meme]
40
 
41
- Make it funny, relatable, and max 10 words each line."""
 
 
42
 
43
- response = ""
44
- for message in client.chat_completion(
45
- messages=[{"role": "user", "content": prompt}],
 
 
 
46
  model=model,
47
- max_tokens=200,
48
- stream=True,
49
- ):
50
- if message.choices[0].delta.content:
51
- response += message.choices[0].delta.content
52
 
53
  # Parse response
54
- lines = response.strip().split('\n')
 
 
55
  top_text = ""
56
  bottom_text = ""
57
 
58
  for line in lines:
 
59
  if line.startswith("TOP:"):
60
  top_text = line.replace("TOP:", "").strip()
61
  elif line.startswith("BOTTOM:"):
62
  bottom_text = line.replace("BOTTOM:", "").strip()
63
 
 
 
 
 
64
  if not top_text or not bottom_text:
65
- return None, None, "❌ Could not parse AI response. Try again."
 
 
 
 
66
 
67
  return top_text, bottom_text, None
68
 
69
  except Exception as e:
70
- return None, None, f"❌ Error: {str(e)}"
 
 
 
 
 
 
 
 
 
71
 
72
  def create_meme(idea: str, template: str, model: str):
73
  """Generate complete meme"""
74
- if not idea:
75
- return None, "❌ Enter a meme idea!"
 
 
76
 
77
  # Get AI-generated text
78
  top, bottom, error = generate_meme_text(idea, model)
@@ -94,114 +124,216 @@ def create_meme(idea: str, template: str, model: str):
94
  }
95
 
96
  try:
97
- response = requests.post(url, data=payload, timeout=10)
98
  data = response.json()
99
 
100
  if data['success']:
101
  meme_url = data['data']['url']
102
 
103
  # Download image
104
- img_response = requests.get(meme_url, timeout=10)
105
  if img_response.status_code == 200:
106
  temp_path = f"/tmp/meme_{random.randint(1000,9999)}.jpg"
107
  with open(temp_path, 'wb') as f:
108
  f.write(img_response.content)
109
 
110
- return temp_path, f"βœ… Success!\n\nTop: {top}\nBottom: {bottom}\n\nURL: {meme_url}"
 
 
 
 
 
 
 
 
 
 
111
  else:
112
- return None, f"βœ… Meme created!\n\nURL: {meme_url}"
113
  else:
114
- return None, f"❌ ImgFlip API error: {data.get('error_message', 'Unknown')}"
 
115
 
 
 
116
  except Exception as e:
117
- return None, f"❌ Error creating meme: {str(e)}"
118
 
119
- # Models
120
  MODELS = {
121
- "Qwen 2.5 72B": "Qwen/Qwen2.5-72B-Instruct",
122
- "Llama 3.2 3B": "meta-llama/Llama-3.2-3B-Instruct",
123
- "Mistral 7B": "mistralai/Mistral-7B-Instruct-v0.3",
 
 
124
  }
125
 
126
  # Examples
127
  examples = [
128
- ["When you finally fix the bug at 3 AM", "Success Kid", "Llama 3.2 3B"],
129
- ["Trying to explain code to non-developers", "Distracted Boyfriend", "Qwen 2.5 72B"],
130
- ["My code vs production", "Drake", "Llama 3.2 3B"],
 
 
 
131
  ]
132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  # UI
134
- with gr.Blocks(theme=gr.themes.Soft(), title="AI Meme Generator") as demo:
135
 
136
  gr.HTML("""
137
- <div style='text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
138
- padding: 30px; border-radius: 15px; color: white; margin-bottom: 20px;'>
139
  <h1>πŸ₯Έ AI Meme Generator</h1>
140
- <h3>Powered by HuggingFace + ImgFlip API</h3>
 
141
  </div>
142
  """)
143
 
144
- gr.Markdown("⚠️ **Setup:** Add `HF_TOKEN` to Space Settings β†’ Repository Secrets ([Get Token](https://huggingface.co/settings/tokens))")
 
 
 
145
 
146
  with gr.Row():
147
  with gr.Column(scale=2):
148
  idea = gr.Textbox(
149
- label="🎨 Meme Idea",
150
- placeholder="When you find a bug in production...",
151
- lines=2
 
152
  )
153
 
154
  with gr.Row():
155
  template = gr.Dropdown(
156
  choices=list(MEME_TEMPLATES.keys()),
157
  value="Drake",
158
- label="πŸ–ΌοΈ Template"
 
159
  )
160
 
161
  model = gr.Dropdown(
162
  choices=list(MODELS.keys()),
163
- value="Llama 3.2 3B",
164
- label="πŸ€– AI Model"
 
165
  )
166
 
167
- btn = gr.Button("πŸš€ Generate Meme", variant="primary", size="lg")
 
 
168
 
169
  with gr.Column(scale=1):
170
  gr.Markdown("""
171
- ### οΏ½οΏ½ Setup
172
 
173
- **1. Get Token:**
174
- - [HF Tokens](https://huggingface.co/settings/tokens)
175
- - Create "Read" token
176
- - Copy it
 
177
 
178
  **2. Add to Space:**
179
- - Settings β†’ Secrets
180
- - Name: `HF_TOKEN`
181
- - Value: (paste)
182
- - Restart
 
 
183
 
184
- **3. Generate!**
185
- - Pick template
186
- - Enter idea
187
- - Click generate
 
188
 
189
- ⚑ **Instant results!**
 
 
 
 
190
  """)
191
 
192
- output_img = gr.Image(label="Generated Meme", type="filepath")
193
- output_status = gr.Textbox(label="Status", lines=4)
 
 
 
 
 
 
 
 
 
 
 
 
 
194
 
195
  gr.Examples(
196
  examples=examples,
197
- inputs=[idea, template, model]
 
198
  )
199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  btn.click(
201
  fn=lambda i, t, m: create_meme(i, t, MODELS[m]),
202
  inputs=[idea, template, model],
203
  outputs=[output_img, output_status]
204
  )
205
 
 
206
  if __name__ == "__main__":
207
- demo.launch()
 
4
  import requests
5
  import random
6
 
 
7
  def get_client():
8
+ """Get HF client"""
9
  token = os.environ.get("HF_TOKEN", "")
10
  if not token:
11
  return None, "❌ Add HF_TOKEN to Space Settings β†’ Repository Secrets"
12
  return InferenceClient(token=token), None
13
 
14
+ # Meme templates
15
  MEME_TEMPLATES = {
16
  "Drake": "181913649",
17
  "Distracted Boyfriend": "112126428",
 
23
  "Bad Luck Brian": "61585",
24
  "Philosoraptor": "61516",
25
  "One Does Not Simply": "61579",
26
+ "Batman Slapping Robin": "438680",
27
+ "Ancient Aliens": "101470",
28
+ "X, X Everywhere": "347390",
29
  }
30
 
31
  def generate_meme_text(idea: str, model: str):
 
35
  return None, None, error
36
 
37
  try:
38
+ prompt = f"""Generate funny meme text for: "{idea}"
39
 
40
+ Format your response exactly like this:
41
+ TOP: [setup/first part - max 10 words]
42
+ BOTTOM: [punchline/second part - max 10 words]
43
 
44
+ Example for "when code works first try":
45
+ TOP: When your code works
46
+ BOTTOM: On the first try
47
 
48
+ Now create for: "{idea}"
49
+ TOP:"""
50
+
51
+ # Use text_generation instead of chat_completion
52
+ response = client.text_generation(
53
+ prompt,
54
  model=model,
55
+ max_new_tokens=150,
56
+ temperature=0.7,
57
+ do_sample=True,
58
+ return_full_text=False
59
+ )
60
 
61
  # Parse response
62
+ full_response = "TOP:" + response
63
+ lines = full_response.strip().split('\n')
64
+
65
  top_text = ""
66
  bottom_text = ""
67
 
68
  for line in lines:
69
+ line = line.strip()
70
  if line.startswith("TOP:"):
71
  top_text = line.replace("TOP:", "").strip()
72
  elif line.startswith("BOTTOM:"):
73
  bottom_text = line.replace("BOTTOM:", "").strip()
74
 
75
+ # Clean up text
76
+ top_text = top_text.split('\n')[0].strip('[]"\'')
77
+ bottom_text = bottom_text.split('\n')[0].strip('[]"\'')
78
+
79
  if not top_text or not bottom_text:
80
+ # Fallback to simple split
81
+ words = idea.split()
82
+ mid = len(words) // 2
83
+ top_text = ' '.join(words[:mid])
84
+ bottom_text = ' '.join(words[mid:])
85
 
86
  return top_text, bottom_text, None
87
 
88
  except Exception as e:
89
+ error_msg = str(e)
90
+
91
+ if "404" in error_msg:
92
+ return None, None, f"❌ Model not available. Try a different model.\n\nError: {error_msg}"
93
+ elif "503" in error_msg:
94
+ return None, None, "❌ Model is loading. Wait 30 seconds and try again."
95
+ elif "429" in error_msg:
96
+ return None, None, "❌ Rate limit. Wait 60 seconds."
97
+ else:
98
+ return None, None, f"❌ Error: {error_msg[:200]}"
99
 
100
  def create_meme(idea: str, template: str, model: str):
101
  """Generate complete meme"""
102
+ if not idea or len(idea.strip()) < 3:
103
+ return None, "❌ Enter a meme idea (minimum 3 characters)!"
104
+
105
+ status_msg = f"πŸ”„ Generating meme text with AI...\n\nIdea: {idea}\nTemplate: {template}\nModel: {model}"
106
 
107
  # Get AI-generated text
108
  top, bottom, error = generate_meme_text(idea, model)
 
124
  }
125
 
126
  try:
127
+ response = requests.post(url, data=payload, timeout=15)
128
  data = response.json()
129
 
130
  if data['success']:
131
  meme_url = data['data']['url']
132
 
133
  # Download image
134
+ img_response = requests.get(meme_url, timeout=15)
135
  if img_response.status_code == 200:
136
  temp_path = f"/tmp/meme_{random.randint(1000,9999)}.jpg"
137
  with open(temp_path, 'wb') as f:
138
  f.write(img_response.content)
139
 
140
+ return temp_path, f"""βœ… **Meme Generated Successfully!**
141
+
142
+ πŸ“ **Top Text:** {top}
143
+ πŸ“ **Bottom Text:** {bottom}
144
+
145
+ πŸ€– **AI Model:** {model}
146
+ πŸ–ΌοΈ **Template:** {template}
147
+
148
+ πŸ”— **Direct URL:** {meme_url}
149
+
150
+ πŸ’‘ Right-click image to save or share!"""
151
  else:
152
+ return None, f"βœ… Meme created!\n\nπŸ”— **URL:** {meme_url}\n\nTop: {top}\nBottom: {bottom}"
153
  else:
154
+ error_msg = data.get('error_message', 'Unknown error')
155
+ return None, f"❌ ImgFlip API Error: {error_msg}\n\nTry a different template or try again."
156
 
157
+ except requests.exceptions.Timeout:
158
+ return None, "❌ Request timeout. Try again."
159
  except Exception as e:
160
+ return None, f"❌ Error creating meme: {str(e)[:200]}"
161
 
162
+ # Models (using correct model IDs)
163
  MODELS = {
164
+ "Llama 3.2 3B (Recommended)": "meta-llama/Llama-3.2-3B-Instruct",
165
+ "Qwen 2.5 7B": "Qwen/Qwen2.5-7B-Instruct",
166
+ "Mistral 7B": "mistralai/Mistral-7B-Instruct-v0.2",
167
+ "Phi 3 Mini": "microsoft/Phi-3-mini-4k-instruct",
168
+ "Gemma 2B": "google/gemma-2b-it",
169
  }
170
 
171
  # Examples
172
  examples = [
173
+ ["When you finally fix the bug at 3 AM", "Success Kid", "Llama 3.2 3B (Recommended)"],
174
+ ["Junior dev vs Senior dev looking at same error", "Drake", "Llama 3.2 3B (Recommended)"],
175
+ ["My code in development vs in production", "Distracted Boyfriend", "Qwen 2.5 7B"],
176
+ ["Trying to explain code to non-developers", "Ancient Aliens", "Llama 3.2 3B (Recommended)"],
177
+ ["Me before coffee vs after coffee", "Two Buttons", "Llama 3.2 3B (Recommended)"],
178
+ ["When the code works on first try", "Disaster Girl", "Mistral 7B"],
179
  ]
180
 
181
+ # Custom CSS
182
+ custom_css = """
183
+ .gradio-container {max-width: 1200px !important;}
184
+ .header-gradient {
185
+ text-align: center;
186
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
187
+ padding: 30px;
188
+ border-radius: 15px;
189
+ color: white;
190
+ margin-bottom: 20px;
191
+ }
192
+ """
193
+
194
  # UI
195
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft(), title="πŸ₯Έ AI Meme Generator") as demo:
196
 
197
  gr.HTML("""
198
+ <div class="header-gradient">
 
199
  <h1>πŸ₯Έ AI Meme Generator</h1>
200
+ <h3>Powered by HuggingFace AI + ImgFlip API πŸ€—</h3>
201
+ <p>AI creates funny meme text, then generates your meme instantly!</p>
202
  </div>
203
  """)
204
 
205
+ gr.Markdown("""
206
+ ⚠️ **First Time Setup:** Add `HF_TOKEN` to Space Settings β†’ Repository Secrets
207
+ ([Get Free Token](https://huggingface.co/settings/tokens))
208
+ """)
209
 
210
  with gr.Row():
211
  with gr.Column(scale=2):
212
  idea = gr.Textbox(
213
+ label="🎨 Your Meme Idea",
214
+ placeholder="Example: When you find a bug in production on Friday...",
215
+ lines=2,
216
+ info="Describe your meme idea - AI will create funny text for it"
217
  )
218
 
219
  with gr.Row():
220
  template = gr.Dropdown(
221
  choices=list(MEME_TEMPLATES.keys()),
222
  value="Drake",
223
+ label="πŸ–ΌοΈ Meme Template",
224
+ info="Choose which meme format to use"
225
  )
226
 
227
  model = gr.Dropdown(
228
  choices=list(MODELS.keys()),
229
+ value="Llama 3.2 3B (Recommended)",
230
+ label="πŸ€– AI Model",
231
+ info="Llama 3.2 3B is fastest and most reliable"
232
  )
233
 
234
+ with gr.Row():
235
+ btn = gr.Button("πŸš€ Generate Meme", variant="primary", size="lg")
236
+ clear_btn = gr.ClearButton(components=[idea], value="πŸ—‘οΈ Clear")
237
 
238
  with gr.Column(scale=1):
239
  gr.Markdown("""
240
+ ### πŸ“– Quick Setup
241
 
242
+ **1. Get HuggingFace Token:**
243
+ - Visit [HF Tokens](https://huggingface.co/settings/tokens)
244
+ - Click "New token"
245
+ - Select "Read" permission
246
+ - Copy token (starts with `hf_`)
247
 
248
  **2. Add to Space:**
249
+ - Click Settings (top right)
250
+ - Go to "Repository Secrets"
251
+ - Add new secret:
252
+ - Name: `HF_TOKEN`
253
+ - Value: (paste token)
254
+ - Save and restart Space
255
 
256
+ **3. Create Memes:**
257
+ - Enter your idea
258
+ - Pick a template
259
+ - Click "Generate Meme"
260
+ - Download and share!
261
 
262
+ **πŸ’‘ Tips:**
263
+ - βœ… Be specific and descriptive
264
+ - βœ… Include context/scenario
265
+ - βœ… Use "Llama 3.2 3B" for best results
266
+ - βœ… Generation takes 2-5 seconds
267
  """)
268
 
269
+ with gr.Row():
270
+ output_img = gr.Image(
271
+ label="πŸ–ΌοΈ Your Generated Meme",
272
+ type="filepath",
273
+ height=400,
274
+ show_download_button=True
275
+ )
276
+
277
+ output_status = gr.Textbox(
278
+ label="πŸ“Š Status & Details",
279
+ lines=8,
280
+ show_copy_button=True
281
+ )
282
+
283
+ gr.Markdown("### πŸ’‘ Example Ideas (Click to Try!)")
284
 
285
  gr.Examples(
286
  examples=examples,
287
+ inputs=[idea, template, model],
288
+ label="Click any example to auto-fill and try it out"
289
  )
290
 
291
+ gr.Markdown("""
292
+ ---
293
+
294
+ ### πŸ”§ Troubleshooting
295
+
296
+ | Problem | Solution |
297
+ |---------|----------|
298
+ | ❌ Token not found | Add `HF_TOKEN` in Space Settings β†’ Repository Secrets |
299
+ | ❌ 404 Model error | Model may not be available - try "Llama 3.2 3B" |
300
+ | ❌ 503 Model loading | Wait 30 seconds for model to wake up |
301
+ | ❌ 429 Rate limit | Wait 60 seconds (free tier limits) |
302
+ | ❌ ImgFlip error | Try different template or retry |
303
+
304
+ ### 🎯 How It Works
305
+
306
+ 1. **You describe** your meme idea
307
+ 2. **AI generates** funny top and bottom text
308
+ 3. **ImgFlip creates** the meme with your chosen template
309
+ 4. **Download** and share instantly!
310
+
311
+ ### ⚑ Features
312
+
313
+ - βœ… **Fast:** 2-5 second generation
314
+ - βœ… **Smart:** AI creates contextual humor
315
+ - βœ… **Easy:** Just describe and click
316
+ - βœ… **Free:** 100% free to use
317
+ - βœ… **No waiting:** Instant results
318
+
319
+ ---
320
+
321
+ <div style='text-align: center; padding: 25px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
322
+ border-radius: 10px; color: white;'>
323
+ <p style='font-size: 1.2em; margin: 0;'><strong>πŸ€— 100% Free & Open Source</strong></p>
324
+ <p style='margin: 10px 0;'>Built with: HuggingFace Inference API β€’ ImgFlip API β€’ Gradio</p>
325
+ <p style='margin: 10px 0;'>⭐ Star this Space if you find it useful!</p>
326
+ <p style='margin: 0; font-size: 0.9em;'><em>Free tier has rate limits - be patient between generations</em></p>
327
+ </div>
328
+ """)
329
+
330
+ # Event handler
331
  btn.click(
332
  fn=lambda i, t, m: create_meme(i, t, MODELS[m]),
333
  inputs=[idea, template, model],
334
  outputs=[output_img, output_status]
335
  )
336
 
337
+ # Launch
338
  if __name__ == "__main__":
339
+ demo.launch(show_error=True)