MySafeCode commited on
Commit
7ac7ae9
·
verified ·
1 Parent(s): 7698cc1

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +27 -16
  2. app.py +218 -138
  3. requirements.txt +3 -3
README.md CHANGED
@@ -4,7 +4,7 @@ emoji: 🎨
4
  colorFrom: purple
5
  colorTo: pink
6
  sdk: gradio
7
- sdk_version: 4.12.0
8
  app_file: app.py
9
  pinned: false
10
  license: mit
@@ -12,33 +12,44 @@ license: mit
12
 
13
  # 🎨 Pixazo Image Generator
14
 
15
- Generate stunning AI images using Pixazo's FLUX-1 Schnell model.
16
 
17
  ## ✨ Features
18
 
19
  - 🖼️ Generate multiple images at once
20
- - 🎭 Various style presets
21
- - ⚡ Adjustable quality vs speed
22
- - 🔒 Secure API key handling
23
  - 📱 Responsive design
 
24
 
25
- ## 🔧 Setup
26
 
27
- 1. Get your API key from [Pixazo](https://pixazo.ai)
28
- 2. Add it to Hugging Face Space secrets:
29
  - Go to **Settings → Repository secrets**
30
  - Add: `PIXAZO_API_KEY = your_key_here`
31
- 3. The app will automatically restart
32
 
33
- ## 🚀 Usage Tips
 
 
 
 
34
 
35
  - Be descriptive in your prompts
36
- - Start with 4 steps for quick testing
37
  - Use seeds for reproducible results
38
- - Try different style presets
 
 
 
 
 
 
 
39
 
40
- ## 📞 API Response Format
41
 
42
- The Pixazo API returns:
43
- ```json
44
- {"output": "https://image-url-here.png"}
 
 
4
  colorFrom: purple
5
  colorTo: pink
6
  sdk: gradio
7
+ sdk_version: 6.2.0
8
  app_file: app.py
9
  pinned: false
10
  license: mit
 
12
 
13
  # 🎨 Pixazo Image Generator
14
 
15
+ Generate AI images using Pixazo's FLUX-1 Schnell model.
16
 
17
  ## ✨ Features
18
 
19
  - 🖼️ Generate multiple images at once
20
+ - 🎭 Various style presets (cyberpunk, fantasy, anime, etc.)
21
+ - ⚡ Adjustable quality settings
22
+ - 🔒 Secure API key handling via Hugging Face secrets
23
  - 📱 Responsive design
24
+ - 🔄 Real-time progress updates
25
 
26
+ ## 🚀 Quick Start
27
 
28
+ 1. **Set your API key:**
 
29
  - Go to **Settings → Repository secrets**
30
  - Add: `PIXAZO_API_KEY = your_key_here`
 
31
 
32
+ 2. **Restart the Space** (from Settings page)
33
+
34
+ 3. **Start generating images!**
35
+
36
+ ## 🎯 Usage Tips
37
 
38
  - Be descriptive in your prompts
39
+ - Start with 4 steps for quick results
40
  - Use seeds for reproducible results
41
+ - Try different style presets for varied effects
42
+
43
+ ## 🔧 Technical Details
44
+
45
+ - **API Format:** `{"output": "IMAGE_URL"}`
46
+ - **Framework:** Gradio 6.2.0
47
+ - **Image Processing:** PIL/Pillow
48
+ - **HTTP Client:** Requests
49
 
50
+ ## 📞 Support
51
 
52
+ If you encounter issues:
53
+ 1. Check your API key is correctly set
54
+ 2. Verify the prompt follows guidelines
55
+ 3. Check the "Detailed Response" section for API errors
app.py CHANGED
@@ -5,7 +5,6 @@ import os
5
  from PIL import Image
6
  import io
7
  import time
8
- import base64
9
  from datetime import datetime
10
 
11
  # Get API key from Hugging Face secrets
@@ -83,14 +82,15 @@ def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
83
  return image, {
84
  "success": True,
85
  "status_code": 200,
86
- "image_url": image_url[:100] + "..." if len(image_url) > 100 else image_url,
87
  "image_size": f"{image.size[0]}x{image.size[1]}",
 
88
  "timestamp": datetime.now().isoformat()
89
  }
90
  else:
91
  return None, {
92
  "error": f"Failed to download image: HTTP {img_response.status_code}",
93
- "image_url": image_url[:100] + "..." if len(image_url) > 100 else image_url,
94
  "download_status": img_response.status_code,
95
  "timestamp": datetime.now().isoformat()
96
  }
@@ -98,7 +98,7 @@ def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
98
  except Exception as e:
99
  return None, {
100
  "error": f"Error downloading image: {str(e)}",
101
- "image_url": image_url[:100] + "..." if len(image_url) > 100 else image_url,
102
  "timestamp": datetime.now().isoformat()
103
  }
104
  else:
@@ -137,9 +137,9 @@ def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
137
  "timestamp": datetime.now().isoformat()
138
  }
139
 
140
- # Generate images
141
- def generate_images(prompt, num_steps, seed, height, width, style_preset,
142
- num_images, guidance_scale):
143
 
144
  images = []
145
  all_results = []
@@ -163,12 +163,16 @@ def generate_images(prompt, num_steps, seed, height, width, style_preset,
163
 
164
  all_results.append(result)
165
 
166
- # Update status
167
- yield [
168
- images if images else None,
169
- f"Progress: {i+1}/{num_images} images",
170
- json.dumps(result, indent=2)
171
- ]
 
 
 
 
172
 
173
  # Small delay between requests
174
  if i < num_images - 1:
@@ -177,194 +181,270 @@ def generate_images(prompt, num_steps, seed, height, width, style_preset,
177
  except Exception as e:
178
  error_result = {"error": str(e), "image_index": i, "timestamp": datetime.now().isoformat()}
179
  all_results.append(error_result)
180
- yield [
181
- images if images else None,
182
- f"Error on image {i+1}: {str(e)[:50]}",
183
- json.dumps(error_result, indent=2)
184
- ]
185
  break
186
 
187
- # Prepare final output
188
  success_count = len(images)
189
 
190
  if success_count == 0:
191
- status = f"❌ No images generated ({success_count}/{num_images} successful)"
192
- final_images = None
193
  elif success_count < num_images:
194
- status = f"⚠️ Partial success: {success_count}/{num_images} images"
195
- final_images = images
196
  else:
197
- status = f"🎉 Success! All {success_count} images generated"
198
- final_images = images
199
 
200
  summary = {
201
- "total_attempts": num_images,
202
- "successful": success_count,
203
- "failed": num_images - success_count,
204
- "timestamp": datetime.now().isoformat(),
 
 
205
  "parameters": {
206
- "prompt_length": len(prompt),
207
  "steps": num_steps,
208
- "size": f"{width}x{height}",
 
209
  "style": style_preset,
210
- "guidance": guidance_scale
 
211
  }
212
  }
213
 
214
- yield [final_images, status, json.dumps(summary, indent=2)]
 
 
 
 
215
 
216
- # Create Gradio interface
217
  with gr.Blocks(
218
  title="Pixazo Image Generator",
219
- theme=gr.themes.Soft()
 
 
 
 
 
 
 
 
 
220
  ) as demo:
221
 
222
  # Header
223
  gr.Markdown("""
224
- # 🎨 Pixazo Image Generator
225
-
226
- Generate images using Pixazo's FLUX-1 Schnell AI model
 
227
  """)
228
 
229
  # API Status
230
  api_key = get_api_key()
231
  if api_key:
232
- gr.Markdown("### API Key: Configured")
 
 
 
 
233
  else:
234
- gr.Markdown("""
235
- ### API Key: Not Configured
236
-
237
- **To set up:**
238
- 1. Go to Space Settings → Repository secrets
239
- 2. Add: `PIXAZO_API_KEY` = your API key
240
- 3. Click "Restart this Space"
241
- """)
 
 
242
 
243
  with gr.Row():
244
- with gr.Column(scale=1):
245
- # Input Section
246
- with gr.Group():
247
  prompt = gr.Textbox(
248
- label="Prompt",
249
- placeholder="Describe the image you want to generate...",
250
  lines=3,
251
- value="A beautiful sunset over mountains"
252
- )
253
-
254
- with gr.Row():
255
- style_preset = gr.Dropdown(
256
- label="Style Preset",
257
- choices=[
258
- "none", "cyberpunk", "fantasy", "anime", "photographic",
259
- "digital-art", "comic", "3d-model", "pixel-art"
260
- ],
261
- value="none"
262
  )
263
 
264
- guidance_scale = gr.Slider(
265
- label="Guidance Scale",
266
- minimum=1.0,
267
- maximum=20.0,
268
- value=7.5,
269
- step=0.5
270
- )
271
-
272
- with gr.Row():
273
- num_steps = gr.Slider(
274
- label="Number of Steps",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275
  minimum=1,
276
- maximum=50,
277
- value=4,
278
  step=1
279
  )
280
-
281
- seed = gr.Number(
282
- label="Seed",
283
- value=42,
284
- minimum=0,
285
- maximum=999999
286
- )
287
 
288
  with gr.Row():
289
- width = gr.Slider(
290
- label="Width",
291
- minimum=256,
292
- maximum=1024,
293
- value=512,
294
- step=64
295
- )
296
-
297
- height = gr.Slider(
298
- label="Height",
299
- minimum=256,
300
- maximum=1024,
301
- value=512,
302
- step=64
303
- )
304
-
305
- num_images = gr.Slider(
306
- label="Number of Images",
307
- minimum=1,
308
- maximum=4,
309
- value=1,
310
- step=1
311
- )
312
-
313
- generate_btn = gr.Button("Generate Images", variant="primary")
314
 
315
- # Examples
316
- gr.Examples(
317
- examples=[
318
- ["A cyberpunk cityscape with flying cars and neon lights at night", 4, 123, 512, 512, "cyberpunk", 1, 7.5],
319
- ["A magical dragon in a fantasy landscape, cinematic lighting", 4, 456, 512, 512, "fantasy", 1, 7.5],
320
- ["Cute anime character with magical powers", 4, 789, 512, 512, "anime", 1, 7.5],
321
- ["Photorealistic portrait of an astronaut", 6, 999, 768, 512, "photographic", 1, 8.0]
322
- ],
323
- inputs=[prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale],
324
- label="Try these examples:"
325
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
 
327
- with gr.Column(scale=2):
328
- # Output Section
329
  status = gr.Textbox(
330
  label="Status",
331
- value="Ready to generate..."
 
332
  )
333
 
334
  gallery = gr.Gallery(
335
  label="Generated Images",
336
  columns=2,
337
- height="auto"
 
 
 
338
  )
339
 
340
- # Response viewer
341
- with gr.Accordion("API Response", open=False):
342
  json_output = gr.JSON(
343
- label="Response"
 
344
  )
345
 
346
  # Footer
347
  gr.Markdown("""
348
  ---
349
- **Note:** The Pixazo API returns `{"output": "IMAGE_URL"}`, and the app downloads the image from that URL.
350
-
351
- Make sure to set `PIXAZO_API_KEY` in your Space secrets for the app to work.
 
352
  """)
353
 
354
- # Connect button to function
355
- generate_btn.click(
356
- fn=generate_images,
357
- inputs=[prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale],
358
- outputs=[gallery, status, json_output]
359
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
 
361
  # Launch the app
362
  if __name__ == "__main__":
363
- print("Starting Pixazo Image Generator...")
364
- print(f"API Key configured: {'Yes' if get_api_key() else 'No'}")
 
 
 
365
 
366
  demo.launch(
367
  server_name="0.0.0.0",
368
  server_port=7860,
369
- share=False
 
370
  )
 
5
  from PIL import Image
6
  import io
7
  import time
 
8
  from datetime import datetime
9
 
10
  # Get API key from Hugging Face secrets
 
82
  return image, {
83
  "success": True,
84
  "status_code": 200,
85
+ "image_url_preview": image_url[:80] + "..." if len(image_url) > 80 else image_url,
86
  "image_size": f"{image.size[0]}x{image.size[1]}",
87
+ "image_format": image.format if hasattr(image, 'format') else "Unknown",
88
  "timestamp": datetime.now().isoformat()
89
  }
90
  else:
91
  return None, {
92
  "error": f"Failed to download image: HTTP {img_response.status_code}",
93
+ "image_url": image_url[:80] + "..." if len(image_url) > 80 else image_url,
94
  "download_status": img_response.status_code,
95
  "timestamp": datetime.now().isoformat()
96
  }
 
98
  except Exception as e:
99
  return None, {
100
  "error": f"Error downloading image: {str(e)}",
101
+ "image_url": image_url[:80] + "..." if len(image_url) > 80 else image_url,
102
  "timestamp": datetime.now().isoformat()
103
  }
104
  else:
 
137
  "timestamp": datetime.now().isoformat()
138
  }
139
 
140
+ # Generate images with streaming updates
141
+ def generate_images_stream(prompt, num_steps, seed, height, width, style_preset,
142
+ num_images, guidance_scale):
143
 
144
  images = []
145
  all_results = []
 
163
 
164
  all_results.append(result)
165
 
166
+ # Yield intermediate results for streaming
167
+ status_text = f"Generated {i+1}/{num_images} images"
168
+ if "error" in result:
169
+ status_text = f"Error on image {i+1}: {result['error'][:50]}..."
170
+
171
+ yield {
172
+ gallery: images if images else None,
173
+ status: status_text,
174
+ json_output: result
175
+ }
176
 
177
  # Small delay between requests
178
  if i < num_images - 1:
 
181
  except Exception as e:
182
  error_result = {"error": str(e), "image_index": i, "timestamp": datetime.now().isoformat()}
183
  all_results.append(error_result)
184
+ yield {
185
+ gallery: images if images else None,
186
+ status: f"Exception on image {i+1}: {str(e)[:50]}",
187
+ json_output: error_result
188
+ }
189
  break
190
 
191
+ # Final summary
192
  success_count = len(images)
193
 
194
  if success_count == 0:
195
+ final_status = f"❌ No images generated ({success_count}/{num_images} successful)"
 
196
  elif success_count < num_images:
197
+ final_status = f"⚠️ Partial success: {success_count}/{num_images} images"
 
198
  else:
199
+ final_status = f"🎉 Success! All {success_count} images generated"
 
200
 
201
  summary = {
202
+ "summary": {
203
+ "total_attempts": num_images,
204
+ "successful": success_count,
205
+ "failed": num_images - success_count,
206
+ "timestamp": datetime.now().isoformat()
207
+ },
208
  "parameters": {
209
+ "prompt": prompt[:100] + "..." if len(prompt) > 100 else prompt,
210
  "steps": num_steps,
211
+ "seed_used": seed,
212
+ "resolution": f"{width}x{height}",
213
  "style": style_preset,
214
+ "num_images": num_images,
215
+ "guidance_scale": guidance_scale
216
  }
217
  }
218
 
219
+ yield {
220
+ gallery: images if images else None,
221
+ status: final_status,
222
+ json_output: summary
223
+ }
224
 
225
+ # Create the Gradio interface
226
  with gr.Blocks(
227
  title="Pixazo Image Generator",
228
+ theme=gr.themes.Soft(primary_hue="purple", secondary_hue="pink"),
229
+ css="""
230
+ .success { color: #10b981 !important; }
231
+ .error { color: #ef4444 !important; }
232
+ .warning { color: #f59e0b !important; }
233
+ .container {
234
+ max-width: 1200px;
235
+ margin: 0 auto;
236
+ }
237
+ """
238
  ) as demo:
239
 
240
  # Header
241
  gr.Markdown("""
242
+ <div style="text-align: center;">
243
+ <h1>🎨 Pixazo AI Image Generator</h1>
244
+ <p>Create stunning images with FLUX-1 Schnell model</p>
245
+ </div>
246
  """)
247
 
248
  # API Status
249
  api_key = get_api_key()
250
  if api_key:
251
+ status_html = """
252
+ <div style="background: #d1fae5; padding: 10px 15px; border-radius: 8px; border-left: 4px solid #10b981; margin-bottom: 20px;">
253
+ <strong>✅ API Status:</strong> Connected (API key configured)
254
+ </div>
255
+ """
256
  else:
257
+ status_html = """
258
+ <div style="background: #fee2e2; padding: 15px; border-radius: 8px; border-left: 4px solid #ef4444; margin-bottom: 20px;">
259
+ <strong>❌ API Status:</strong> Not Configured
260
+ <p style="margin: 8px 0 0 0; font-size: 0.9em;">
261
+ <strong>Setup:</strong> Go to Space Settings → Repository secrets → Add: <code>PIXAZO_API_KEY</code> = your key
262
+ </p>
263
+ </div>
264
+ """
265
+
266
+ gr.HTML(status_html)
267
 
268
  with gr.Row():
269
+ # Left column - Inputs
270
+ with gr.Column(scale=1, min_width=400):
271
+ with gr.Group(label="Generation Settings"):
272
  prompt = gr.Textbox(
273
+ label="Image Prompt",
274
+ placeholder="Describe what you want to generate...",
275
  lines=3,
276
+ max_lines=5
 
 
 
 
 
 
 
 
 
 
277
  )
278
 
279
+ with gr.Row():
280
+ style_preset = gr.Dropdown(
281
+ label="Style Preset",
282
+ choices=[
283
+ "none", "cyberpunk", "fantasy", "anime", "photographic",
284
+ "digital-art", "comic", "3d-model", "pixel-art",
285
+ "isometric", "watercolor", "oil-painting"
286
+ ],
287
+ value="none",
288
+ scale=2
289
+ )
290
+
291
+ guidance_scale = gr.Slider(
292
+ label="Guidance",
293
+ minimum=1.0,
294
+ maximum=20.0,
295
+ value=7.5,
296
+ step=0.5,
297
+ scale=1
298
+ )
299
+
300
+ with gr.Row():
301
+ num_steps = gr.Slider(
302
+ label="Steps",
303
+ minimum=1,
304
+ maximum=50,
305
+ value=4,
306
+ step=1,
307
+ scale=1
308
+ )
309
+
310
+ seed = gr.Number(
311
+ label="Seed",
312
+ value=42,
313
+ minimum=0,
314
+ maximum=999999,
315
+ scale=1
316
+ )
317
+
318
+ with gr.Row():
319
+ width = gr.Slider(
320
+ label="Width",
321
+ minimum=256,
322
+ maximum=1024,
323
+ value=512,
324
+ step=64,
325
+ scale=1
326
+ )
327
+
328
+ height = gr.Slider(
329
+ label="Height",
330
+ minimum=256,
331
+ maximum=1024,
332
+ value=512,
333
+ step=64,
334
+ scale=1
335
+ )
336
+
337
+ num_images = gr.Slider(
338
+ label="Number of Images",
339
  minimum=1,
340
+ maximum=8,
341
+ value=1,
342
  step=1
343
  )
 
 
 
 
 
 
 
344
 
345
  with gr.Row():
346
+ generate_btn = gr.Button("✨ Generate Images", variant="primary", scale=2)
347
+ clear_btn = gr.Button("🗑️ Clear", variant="secondary", scale=1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
 
349
+ # Quick examples
350
+ with gr.Accordion("💡 Example Prompts", open=False):
351
+ examples = [
352
+ ("Cyberpunk city at night with neon lights and flying cars", "cyberpunk"),
353
+ ("Majestic dragon on a mountain peak, fantasy art", "fantasy"),
354
+ ("Cute anime cat in a magical forest", "anime"),
355
+ ("Photorealistic portrait of an astronaut on Mars", "photographic"),
356
+ ("Isometric office scene with plants and computers", "isometric"),
357
+ ]
358
+
359
+ for example_prompt, example_style in examples:
360
+ with gr.Row():
361
+ gr.Textbox(
362
+ value=example_prompt,
363
+ show_label=False,
364
+ interactive=False,
365
+ scale=3
366
+ )
367
+ gr.Button(
368
+ "Use",
369
+ size="sm",
370
+ scale=1
371
+ ).click(
372
+ lambda p=example_prompt, s=example_style: (p, s),
373
+ outputs=[prompt, style_preset]
374
+ )
375
 
376
+ # Right column - Outputs
377
+ with gr.Column(scale=2, min_width=600):
378
  status = gr.Textbox(
379
  label="Status",
380
+ value="Ready to generate images...",
381
+ interactive=False
382
  )
383
 
384
  gallery = gr.Gallery(
385
  label="Generated Images",
386
  columns=2,
387
+ height="auto",
388
+ object_fit="contain",
389
+ show_label=True,
390
+ preview=True
391
  )
392
 
393
+ with gr.Accordion("📊 Detailed Response", open=False):
 
394
  json_output = gr.JSON(
395
+ label="API Response",
396
+ container=True
397
  )
398
 
399
  # Footer
400
  gr.Markdown("""
401
  ---
402
+ <div style="text-align: center; color: #666; font-size: 0.9em; margin-top: 20px;">
403
+ <p><strong>API Response Format:</strong> <code>{"output": "IMAGE_URL"}</code></p>
404
+ <p>Built with Gradio Powered by Pixazo FLUX-1 Schnell</p>
405
+ </div>
406
  """)
407
 
408
+ # Event handlers
409
+ @generate_btn.click(inputs=[prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale])
410
+ def on_generate(prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale):
411
+ if not prompt.strip():
412
+ return {
413
+ status: "❌ Please enter a prompt first",
414
+ gallery: None,
415
+ json_output: {"error": "No prompt provided"}
416
+ }
417
+
418
+ # Show initial status
419
+ yield {
420
+ status: f"🚀 Starting generation of {num_images} image(s)...",
421
+ gallery: None,
422
+ json_output: {"status": "starting", "num_images": num_images}
423
+ }
424
+
425
+ # Stream generation results
426
+ for update in generate_images_stream(prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale):
427
+ yield update
428
+
429
+ @clear_btn.click()
430
+ def on_clear():
431
+ return {
432
+ status: "Ready to generate images...",
433
+ gallery: None,
434
+ json_output: None
435
+ }
436
 
437
  # Launch the app
438
  if __name__ == "__main__":
439
+ print("=" * 60)
440
+ print("🚀 Pixazo Image Generator")
441
+ print(f"📦 Gradio Version: {gr.__version__}")
442
+ print(f"🔑 API Key Configured: {'Yes' if get_api_key() else 'No'}")
443
+ print("=" * 60)
444
 
445
  demo.launch(
446
  server_name="0.0.0.0",
447
  server_port=7860,
448
+ share=False,
449
+ show_api=False
450
  )
requirements.txt CHANGED
@@ -1,3 +1,3 @@
1
- gradio>=3.41.0,<4.0.0
2
- pillow>=10.0.0
3
- requests>=2.31.0
 
1
+ gradio==6.2.0
2
+ pillow==10.4.0
3
+ requests==2.32.3