MySafeCode commited on
Commit
ef77e93
·
verified ·
1 Parent(s): b154d9b

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +26 -22
  2. app.py +323 -252
  3. requirements.txt +2 -3
README.md CHANGED
@@ -1,40 +1,44 @@
1
  ---
2
- ---
3
  title: Pixazo Image Generator
4
  emoji: 🎨
5
  colorFrom: purple
6
  colorTo: pink
7
  sdk: gradio
8
- sdk_version: 4.0.0
9
  app_file: app.py
10
- pinned: true
 
11
  ---
12
 
13
- # Pixazo Image Generator
14
 
15
- Generate AI images using Pixazo's FLUX-1 Schnell model.
16
 
17
- ## Setup
18
 
19
- 1. Get your API key from [Pixazo](https://pixazo.ai)
20
- 2. Add it to Hugging Face Space secrets:
21
- - Go to Space Settings → Repository secrets
22
- - Add new secret: **Key**: `PIXAZO_API_KEY`, **Value**: your key
23
- 3. The app will automatically restart with the key loaded
24
 
25
- ## Features
26
 
27
- - Generate multiple images at once
28
- - Adjustable image size and quality
29
- - Style presets for different art styles
30
- - Seed control for reproducible results
31
- - View raw API responses
32
 
33
- ## Usage Tips
34
 
35
- - Use descriptive prompts for best results
 
 
36
  - Try different style presets
37
- - Adjust guidance scale for prompt adherence
38
- - Use same seed for consistent results
39
 
40
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
1
  ---
 
2
  title: Pixazo Image Generator
3
  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
11
  ---
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"}
app.py CHANGED
@@ -5,12 +5,14 @@ import os
5
  from PIL import Image
6
  import io
7
  import time
 
 
8
 
9
  # Get API key from Hugging Face secrets
10
  def get_api_key():
11
  return os.environ.get("PIXAZO_API_KEY")
12
 
13
- # Call Pixazo API - Now we know the exact response format!
14
  def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
15
  style_preset=None, guidance_scale=None):
16
 
@@ -19,7 +21,8 @@ def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
19
  if not api_key:
20
  return None, {
21
  "error": "API key not configured",
22
- "instructions": "Please set PIXAZO_API_KEY in Hugging Face Space secrets"
 
23
  }
24
 
25
  url = "https://gateway.pixazo.ai/flux-1-schnell/v1/getData"
@@ -47,8 +50,6 @@ def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
47
 
48
  try:
49
  print(f"🌐 Sending request to Pixazo API...")
50
- print(f" Prompt: {prompt[:50]}...")
51
- print(f" Steps: {num_steps}, Size: {width}x{height}")
52
 
53
  response = requests.post(
54
  url,
@@ -61,94 +62,103 @@ def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
61
 
62
  if response.status_code == 200:
63
  result = response.json()
64
- print(f"📦 Response format: {list(result.keys())}")
65
 
66
- # ✅ Now we know the exact format: {"output": "<IMAGE_URL>"}
67
  if "output" in result:
68
  image_url = result["output"]
69
- print(f"🖼️ Image URL received: {image_url[:80]}...")
70
 
71
  # Download the image from the URL
72
  try:
73
  print(f"⬇️ Downloading image from URL...")
74
- img_response = requests.get(image_url, timeout=30)
 
 
75
 
76
  if img_response.status_code == 200:
77
  image = Image.open(io.BytesIO(img_response.content))
78
- print(f"✅ Image downloaded successfully: {image.size[0]}x{image.size[1]}")
79
 
80
- return image, {
 
 
 
 
 
81
  "success": True,
82
  "status_code": 200,
83
  "image_url": image_url,
84
- "response_summary": {
85
- "keys": list(result.keys()),
86
- "url_length": len(image_url)
87
- }
88
  }
 
 
 
 
 
 
 
 
 
89
  else:
90
  return None, {
91
  "error": f"Failed to download image: HTTP {img_response.status_code}",
92
  "image_url": image_url,
93
- "download_status": img_response.status_code
 
94
  }
95
 
96
  except Exception as e:
97
  return None, {
98
  "error": f"Error downloading image: {str(e)}",
99
  "image_url": image_url,
100
- "response": result
101
  }
102
  else:
103
  return None, {
104
  "error": "Response missing 'output' field",
105
- "response": result,
106
- "expected_format": '{"output": "IMAGE_URL"}'
107
  }
108
  else:
109
- # Handle non-200 responses
110
  try:
111
  error_data = response.json()
 
112
  except:
113
- error_data = {"text": response.text[:500]}
114
 
115
  return None, {
116
- "error": f"API returned status {response.status_code}",
117
  "status_code": response.status_code,
118
- "response": error_data
119
  }
120
 
121
  except requests.exceptions.Timeout:
122
  return None, {
123
  "error": "Request timed out after 120 seconds",
124
- "suggestion": "Try reducing image size or number of steps"
 
125
  }
126
  except requests.exceptions.RequestException as e:
127
  return None, {
128
- "error": f"Network error: {str(e)}"
 
129
  }
130
  except Exception as e:
131
  return None, {
132
- "error": f"Unexpected error: {str(e)}"
 
133
  }
134
 
135
- # Batch generate images
136
  def generate_images(prompt, num_steps, seed, height, width, style_preset,
137
- num_images, guidance_scale):
138
 
139
  images = []
140
  all_results = []
141
 
142
- for i in range(num_images):
143
  try:
144
- # Use different seed for each image if seed is provided
145
  current_seed = seed + i if seed > 0 else 0
146
 
147
- print(f"\n{'='*50}")
148
- print(f"Generating image {i+1}/{num_images}")
149
- print(f"Seed: {current_seed}")
150
- print(f"{'='*50}")
151
-
152
  image, result = call_pixazo_api(
153
  prompt=prompt,
154
  num_steps=num_steps,
@@ -161,182 +171,214 @@ def generate_images(prompt, num_steps, seed, height, width, style_preset,
161
 
162
  if image:
163
  images.append(image)
164
- print(f"✅ Image {i+1} generated successfully!")
165
  else:
166
- print(f"❌ Image {i+1} failed: {result.get('error', 'Unknown error')}")
167
 
168
  all_results.append(result)
169
 
170
- # Update progress
171
- if image:
172
- status_msg = f"✅ Generated {i+1}/{num_images} images"
173
- else:
174
- error_msg = result.get('error', 'Unknown error')
175
- status_msg = f"❌ Image {i+1} failed: {error_msg[:50]}..."
176
-
177
- yield [gr.Gallery(value=images, visible=bool(images)),
178
- status_msg,
179
- json.dumps(result, indent=2)]
180
-
181
  # Small delay between requests
182
  if i < num_images - 1:
183
- time.sleep(2)
184
 
185
  except Exception as e:
186
- error_result = {"error": str(e), "image_index": i}
187
  all_results.append(error_result)
188
- yield [gr.Gallery(value=images, visible=bool(images)),
189
- f"⚠️ Exception on image {i+1}: {str(e)[:50]}",
190
- json.dumps(error_result, indent=2)]
191
  break
192
 
193
- # Final summary
194
  success_count = len(images)
195
- total_count = num_images
196
 
197
  if success_count == 0:
198
- yield [gr.Gallery(visible=False),
199
- f"❌ No images generated ({success_count}/{total_count} successful)",
200
- json.dumps({
201
- "summary": "All generations failed",
202
- "total_attempts": total_count,
203
- "successful": success_count,
204
- "failed": total_count,
205
- "detailed_results": all_results
206
- }, indent=2)]
207
- elif success_count < total_count:
208
- yield [gr.Gallery(value=images, visible=True),
209
- f"⚠️ Partial success: {success_count}/{total_count} images",
210
- json.dumps({
211
- "summary": "Partial success",
212
- "total_attempts": total_count,
213
- "successful": success_count,
214
- "failed": total_count - success_count,
215
- "detailed_results": all_results
216
- }, indent=2)]
217
  else:
218
- yield [gr.Gallery(value=images, visible=True),
219
- f"🎉 Success! All {success_count} images generated",
220
- json.dumps({
221
- "summary": "Complete success",
222
- "total_attempts": total_count,
223
- "successful": success_count,
224
- "failed": 0,
225
- "sample_image_url": all_results[0].get("image_url", "N/A") if all_results else "N/A"
226
- }, indent=2)]
 
 
 
 
 
 
 
 
 
 
 
227
 
228
- # Create Gradio interface
229
  def create_interface():
230
- with gr.Blocks(theme=gr.themes.Soft(), title="Pixazo Image Generator") as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  gr.Markdown("""
232
- # 🎨 Pixazo FLUX-1 Schnell Image Generator
233
- *Now with correct response format handling!*
234
 
235
- **Response Format Confirmed:** `{"output": "IMAGE_URL"}`
236
  """)
237
 
238
- # API Status Check
239
  api_key = get_api_key()
240
  if api_key:
241
- gr.Markdown(f"### API Key: Configured ({len(api_key)} characters)")
 
 
 
 
 
242
  else:
243
- gr.Markdown("### API Key: Not configured")
244
- gr.Markdown("""
245
- **Setup Required:**
246
- 1. Go to Space Settings → Repository secrets
247
- 2. Add secret: **Key**: `PIXAZO_API_KEY`, **Value**: your API key
248
- 3. The app will automatically reload
249
- """)
 
 
 
 
 
 
250
 
251
  with gr.Row():
252
- with gr.Column(scale=2):
253
  # Input Section
254
  with gr.Group():
255
  prompt = gr.Textbox(
256
- label="Prompt",
257
  placeholder="Describe the image you want to generate...",
258
  lines=3,
259
- value="A sleek futuristic car racing through a neon-lit cyberpunk city at night"
 
 
260
  )
261
 
262
  with gr.Row():
263
- style_preset = gr.Dropdown(
264
- label="Style Preset",
265
- choices=["none", "cyberpunk", "fantasy", "anime", "photographic",
266
- "digital-art", "comic", "3d-model", "pixel-art", "isometric"],
267
- value="none"
268
- )
 
 
 
 
 
269
 
270
- guidance_scale = gr.Slider(
271
- label="Guidance Scale",
272
- minimum=1.0,
273
- maximum=20.0,
274
- value=7.5,
275
- step=0.5
276
- )
 
 
277
 
278
  with gr.Row():
279
- num_steps = gr.Slider(
280
- label="Number of Steps",
281
- minimum=1,
282
- maximum=50,
283
- value=4,
284
- step=1,
285
- info="Higher = better quality but slower"
286
- )
 
287
 
288
- seed = gr.Number(
289
- label="Seed",
290
- value=42,
291
- info="0 = random, >0 = reproducible"
292
- )
 
293
 
294
  with gr.Row():
295
- width = gr.Slider(
296
- label="Width",
297
- minimum=256,
298
- maximum=1024,
299
- value=512,
300
- step=64
301
- )
 
302
 
303
- height = gr.Slider(
304
- label="Height",
305
- minimum=256,
306
- maximum=1024,
307
- value=512,
308
- step=64
309
- )
 
310
 
311
  num_images = gr.Slider(
312
- label="Number of Images",
313
  minimum=1,
314
- maximum=4,
315
  value=1,
316
  step=1,
317
  info="Generate multiple variations"
318
  )
319
 
320
- generate_btn = gr.Button("✨ Generate Images", variant="primary", size="lg")
 
 
321
 
322
- # Quick examples
323
- gr.Examples(
324
- examples=[
325
- ["A cyberpunk cityscape with flying cars and neon signs, night time, rain", 4, 123, 512, 512, "cyberpunk", 1, 7.5],
326
- ["A magical forest with glowing mushrooms and fairies, soft lighting", 4, 456, 512, 512, "fantasy", 1, 7.5],
327
- ["A cute anime cat wearing a spacesuit on the moon", 4, 789, 512, 512, "anime", 1, 7.5],
328
- ["Photorealistic portrait of an elderly wise man with detailed wrinkles", 6, 999, 768, 512, "photographic", 1, 8.0],
329
- ],
330
- inputs=[prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale],
331
- label="Quick Examples"
332
- )
 
 
 
 
 
 
 
333
 
334
- with gr.Column(scale=3):
335
  # Output Section
336
- status = gr.Textbox(
337
- label="Status",
338
- interactive=False,
339
- value="Ready to generate..."
340
  )
341
 
342
  gallery = gr.Gallery(
@@ -344,120 +386,147 @@ def create_interface():
344
  show_label=True,
345
  columns=2,
346
  height="auto",
347
- visible=False,
348
- object_fit="contain"
 
349
  )
350
 
351
- # Response viewer
352
- with gr.Accordion("📊 API Response Details", open=False):
353
- json_output = gr.JSON(
354
- label="API Response",
355
- container=True
356
- )
357
-
358
- # Debug info
359
- with gr.Accordion("🔍 Debug Information", open=False):
360
- gr.Markdown("""
361
- **Known Response Format:** `{"output": "IMAGE_URL"}`
362
 
363
- **Flow:**
364
- 1. Send request to Pixazo API with prompt and parameters
365
- 2. Receive JSON with image URL in `output` field
366
- 3. Download image from that URL
367
- 4. Display image in gallery
 
368
 
369
- **Troubleshooting:**
370
- - Check the JSON response for errors
371
- - If image fails to download, check the URL in the response
372
- - Make sure your API key is valid
373
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
 
375
- # Generation function
376
- generate_btn.click(
377
- fn=generate_images,
378
- inputs=[prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale],
379
- outputs=[gallery, status, json_output]
380
- )
 
 
 
 
 
 
 
381
 
382
- # Quick test button
383
- with gr.Row():
384
- test_btn = gr.Button("🧪 Test Single Image", variant="secondary")
385
- clear_btn = gr.Button("🗑️ Clear Results", variant="secondary")
 
 
 
 
386
 
387
- def test_single_image():
388
- test_prompt = "A simple test image of a red apple on a table"
389
- image, result = call_pixazo_api(
390
- prompt=test_prompt,
391
- num_steps=2,
392
- height=256,
393
- width=256
 
 
 
 
 
 
 
 
 
 
394
  )
395
 
396
- if image:
397
- return [gr.Gallery(value=[image], visible=True),
398
- "✅ Test successful!",
399
- json.dumps(result, indent=2)]
 
400
  else:
401
- return [gr.Gallery(visible=False),
402
- f"❌ Test failed: {result.get('error', 'Unknown')}",
403
- json.dumps(result, indent=2)]
404
 
405
- test_btn.click(
406
- fn=test_single_image,
407
- outputs=[gallery, status, json_output]
 
408
  )
409
 
 
410
  clear_btn.click(
411
- fn=lambda: [None, "Ready to generate...", None],
412
- outputs=[gallery, status, json_output]
 
 
 
 
413
  )
414
-
415
- return demo
416
-
417
- # Simple interface for quick testing
418
- def create_simple_interface():
419
- with gr.Blocks(title="Pixazo Simple") as demo:
420
- gr.Markdown("# 🖼️ Pixazo Image Generator")
421
 
422
- with gr.Row():
423
- with gr.Column():
424
- prompt = gr.Textbox(label="Prompt", value="A beautiful sunset")
425
- btn = gr.Button("Generate", variant="primary")
426
-
427
- with gr.Column():
428
- output = gr.Image(label="Generated Image")
429
- info = gr.Textbox(label="Info")
430
-
431
- def simple_generate(prompt_text):
432
- if not prompt_text.strip():
433
- return None, "Please enter a prompt"
434
-
435
- api_key = get_api_key()
436
- if not api_key:
437
- return None, "API key not set"
438
-
439
- image, result = call_pixazo_api(
440
- prompt=prompt_text,
441
- num_steps=4,
442
- height=512,
443
- width=512
444
- )
445
-
446
- if image:
447
- return image, f"✅ Generated {image.size[0]}x{image.size[1]} image"
448
- else:
449
- return None, f"❌ Error: {result.get('error', 'Unknown')}"
450
-
451
- btn.click(simple_generate, inputs=[prompt], outputs=[output, info])
452
 
453
  return demo
454
 
 
 
 
 
 
 
 
 
 
 
455
  # Main function
456
  def main():
457
- # Print startup info
458
- print("🚀 Starting Pixazo Image Generator")
459
- print(f"📌 API Key present: {'Yes' if get_api_key() else 'No'}")
460
- print(f"📌 Expected response format: {{'output': 'IMAGE_URL'}}")
 
461
 
462
  # Create and launch interface
463
  demo = create_interface()
@@ -465,7 +534,9 @@ def main():
465
  demo.launch(
466
  server_name="0.0.0.0",
467
  server_port=7860,
468
- share=False
 
 
469
  )
470
 
471
  if __name__ == "__main__":
 
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
12
  def get_api_key():
13
  return os.environ.get("PIXAZO_API_KEY")
14
 
15
+ # Call Pixazo API
16
  def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
17
  style_preset=None, guidance_scale=None):
18
 
 
21
  if not api_key:
22
  return None, {
23
  "error": "API key not configured",
24
+ "instructions": "Please set PIXAZO_API_KEY in Hugging Face Space secrets",
25
+ "timestamp": datetime.now().isoformat()
26
  }
27
 
28
  url = "https://gateway.pixazo.ai/flux-1-schnell/v1/getData"
 
50
 
51
  try:
52
  print(f"🌐 Sending request to Pixazo API...")
 
 
53
 
54
  response = requests.post(
55
  url,
 
62
 
63
  if response.status_code == 200:
64
  result = response.json()
 
65
 
 
66
  if "output" in result:
67
  image_url = result["output"]
 
68
 
69
  # Download the image from the URL
70
  try:
71
  print(f"⬇️ Downloading image from URL...")
72
+ img_response = requests.get(image_url, timeout=30, headers={
73
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
74
+ })
75
 
76
  if img_response.status_code == 200:
77
  image = Image.open(io.BytesIO(img_response.content))
 
78
 
79
+ # Convert to RGB if necessary
80
+ if image.mode in ('RGBA', 'LA', 'P'):
81
+ image = image.convert('RGB')
82
+
83
+ # Create a simplified result
84
+ simplified_result = {
85
  "success": True,
86
  "status_code": 200,
87
  "image_url": image_url,
88
+ "image_size": f"{image.size[0]}x{image.size[1]}",
89
+ "image_mode": image.mode,
90
+ "timestamp": datetime.now().isoformat()
 
91
  }
92
+
93
+ # Add original response keys (excluding potentially large data)
94
+ for key, value in result.items():
95
+ if key != "output" and not isinstance(value, (str, int, float, bool, type(None))) or len(str(value)) > 1000:
96
+ simplified_result[f"original_{key}"] = type(value).__name__
97
+ else:
98
+ simplified_result[f"original_{key}"] = value
99
+
100
+ return image, simplified_result
101
  else:
102
  return None, {
103
  "error": f"Failed to download image: HTTP {img_response.status_code}",
104
  "image_url": image_url,
105
+ "download_status": img_response.status_code,
106
+ "timestamp": datetime.now().isoformat()
107
  }
108
 
109
  except Exception as e:
110
  return None, {
111
  "error": f"Error downloading image: {str(e)}",
112
  "image_url": image_url,
113
+ "timestamp": datetime.now().isoformat()
114
  }
115
  else:
116
  return None, {
117
  "error": "Response missing 'output' field",
118
+ "response_keys": list(result.keys()),
119
+ "timestamp": datetime.now().isoformat()
120
  }
121
  else:
 
122
  try:
123
  error_data = response.json()
124
+ error_msg = error_data.get("error", str(error_data))
125
  except:
126
+ error_msg = response.text[:200] if response.text else "No error message"
127
 
128
  return None, {
129
+ "error": f"API returned status {response.status_code}: {error_msg}",
130
  "status_code": response.status_code,
131
+ "timestamp": datetime.now().isoformat()
132
  }
133
 
134
  except requests.exceptions.Timeout:
135
  return None, {
136
  "error": "Request timed out after 120 seconds",
137
+ "suggestion": "Try reducing image size or number of steps",
138
+ "timestamp": datetime.now().isoformat()
139
  }
140
  except requests.exceptions.RequestException as e:
141
  return None, {
142
+ "error": f"Network error: {str(e)}",
143
+ "timestamp": datetime.now().isoformat()
144
  }
145
  except Exception as e:
146
  return None, {
147
+ "error": f"Unexpected error: {str(e)}",
148
+ "timestamp": datetime.now().isoformat()
149
  }
150
 
151
+ # Generate images with progress
152
  def generate_images(prompt, num_steps, seed, height, width, style_preset,
153
+ num_images, guidance_scale, progress=gr.Progress()):
154
 
155
  images = []
156
  all_results = []
157
 
158
+ for i in progress.tqdm(range(num_images), desc="Generating images"):
159
  try:
 
160
  current_seed = seed + i if seed > 0 else 0
161
 
 
 
 
 
 
162
  image, result = call_pixazo_api(
163
  prompt=prompt,
164
  num_steps=num_steps,
 
171
 
172
  if image:
173
  images.append(image)
174
+ progress((i + 1, num_images), desc=f"✅ Image {i+1}/{num_images} generated")
175
  else:
176
+ progress((i + 1, num_images), desc=f"❌ Image {i+1}/{num_images} failed")
177
 
178
  all_results.append(result)
179
 
 
 
 
 
 
 
 
 
 
 
 
180
  # Small delay between requests
181
  if i < num_images - 1:
182
+ time.sleep(1)
183
 
184
  except Exception as e:
185
+ error_result = {"error": str(e), "image_index": i, "timestamp": datetime.now().isoformat()}
186
  all_results.append(error_result)
187
+ progress((i + 1, num_images), desc=f"⚠️ Image {i+1}/{num_images} error")
 
 
188
  break
189
 
190
+ # Prepare final output
191
  success_count = len(images)
 
192
 
193
  if success_count == 0:
194
+ status = f"❌ No images generated ({success_count}/{num_images} successful)"
195
+ gallery_visible = False
196
+ elif success_count < num_images:
197
+ status = f"⚠️ Partial success: {success_count}/{num_images} images"
198
+ gallery_visible = True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  else:
200
+ status = f"🎉 Success! All {success_count} images generated"
201
+ gallery_visible = True
202
+
203
+ summary = {
204
+ "total_attempts": num_images,
205
+ "successful": success_count,
206
+ "failed": num_images - success_count,
207
+ "timestamp": datetime.now().isoformat(),
208
+ "parameters": {
209
+ "prompt_length": len(prompt),
210
+ "steps": num_steps,
211
+ "size": f"{width}x{height}",
212
+ "style": style_preset,
213
+ "guidance": guidance_scale
214
+ }
215
+ }
216
+
217
+ return (gr.update(value=images, visible=gallery_visible),
218
+ status,
219
+ summary)
220
 
221
+ # Create enhanced interface with latest Gradio features
222
  def create_interface():
223
+ with gr.Blocks(
224
+ theme=gr.themes.Soft(
225
+ primary_hue="purple",
226
+ secondary_hue="pink"
227
+ ),
228
+ title="Pixazo AI Image Generator",
229
+ css="""
230
+ .success { color: #10b981; font-weight: bold; }
231
+ .error { color: #ef4444; font-weight: bold; }
232
+ .warning { color: #f59e0b; font-weight: bold; }
233
+ .info-box {
234
+ background: #f8fafc;
235
+ padding: 15px;
236
+ border-radius: 10px;
237
+ border-left: 4px solid #8b5cf6;
238
+ }
239
+ """
240
+ ) as demo:
241
+
242
+ # Header
243
  gr.Markdown("""
244
+ # 🎨 Pixazo AI Image Generator
 
245
 
246
+ Generate stunning images with FLUX-1 Schnell model
247
  """)
248
 
249
+ # API Status
250
  api_key = get_api_key()
251
  if api_key:
252
+ status_html = """
253
+ <div class="info-box">
254
+ <h3>✅ API Status: Connected</h3>
255
+ <p>Your API key is configured and ready to use.</p>
256
+ </div>
257
+ """
258
  else:
259
+ status_html = """
260
+ <div style="background: #fef2f2; padding: 15px; border-radius: 10px; border-left: 4px solid #ef4444;">
261
+ <h3>❌ API Status: Not Configured</h3>
262
+ <p><strong>Setup Required:</strong></p>
263
+ <ol>
264
+ <li>Go to Space Settings Repository secrets</li>
265
+ <li>Add secret: <code>PIXAZO_API_KEY</code> = your API key</li>
266
+ <li>Click "Restart this Space" at the bottom of settings</li>
267
+ </ol>
268
+ </div>
269
+ """
270
+
271
+ gr.HTML(status_html)
272
 
273
  with gr.Row():
274
+ with gr.Column(scale=1, min_width=400):
275
  # Input Section
276
  with gr.Group():
277
  prompt = gr.Textbox(
278
+ label="🎨 Prompt",
279
  placeholder="Describe the image you want to generate...",
280
  lines=3,
281
+ max_lines=5,
282
+ show_label=True,
283
+ info="Be descriptive for better results"
284
  )
285
 
286
  with gr.Row():
287
+ with gr.Column():
288
+ style_preset = gr.Dropdown(
289
+ label="🎭 Style",
290
+ choices=[
291
+ "none", "cyberpunk", "fantasy", "anime", "photographic",
292
+ "digital-art", "comic", "3d-model", "pixel-art", "isometric",
293
+ "minimalist", "watercolor", "oil-painting", "sketch"
294
+ ],
295
+ value="none",
296
+ info="Optional style preset"
297
+ )
298
 
299
+ with gr.Column():
300
+ guidance_scale = gr.Slider(
301
+ label="🎯 Guidance Scale",
302
+ minimum=1.0,
303
+ maximum=20.0,
304
+ value=7.5,
305
+ step=0.5,
306
+ info="Higher = more prompt adherence"
307
+ )
308
 
309
  with gr.Row():
310
+ with gr.Column():
311
+ num_steps = gr.Slider(
312
+ label="⚡ Steps",
313
+ minimum=1,
314
+ maximum=50,
315
+ value=4,
316
+ step=1,
317
+ info="Quality vs speed trade-off"
318
+ )
319
 
320
+ with gr.Column():
321
+ seed = gr.Number(
322
+ label="🌱 Seed",
323
+ value=42,
324
+ info="0 = random, same seed = same result"
325
+ )
326
 
327
  with gr.Row():
328
+ with gr.Column():
329
+ width = gr.Slider(
330
+ label="📏 Width",
331
+ minimum=256,
332
+ maximum=1024,
333
+ value=512,
334
+ step=64
335
+ )
336
 
337
+ with gr.Column():
338
+ height = gr.Slider(
339
+ label="📐 Height",
340
+ minimum=256,
341
+ maximum=1024,
342
+ value=512,
343
+ step=64
344
+ )
345
 
346
  num_images = gr.Slider(
347
+ label="🖼️ Number of Images",
348
  minimum=1,
349
+ maximum=8,
350
  value=1,
351
  step=1,
352
  info="Generate multiple variations"
353
  )
354
 
355
+ with gr.Row():
356
+ generate_btn = gr.Button("✨ Generate", variant="primary", scale=2)
357
+ clear_btn = gr.Button("🗑️ Clear", variant="secondary")
358
 
359
+ # Examples
360
+ with gr.Accordion("📚 Example Prompts", open=False):
361
+ examples = [
362
+ ["A majestic dragon overlooking a fantasy kingdom at sunset, cinematic lighting", "fantasy"],
363
+ ["Cyberpunk city street with neon signs and flying cars, rainy night", "cyberpunk"],
364
+ ["Cute anime girl with magical powers in a cherry blossom garden", "anime"],
365
+ ["Photorealistic portrait of an astronaut on Mars with detailed reflection in visor", "photographic"],
366
+ ["Isometric view of a cozy cottage in a magical forest", "isometric"],
367
+ ["Watercolor painting of a serene mountain lake at dawn", "watercolor"]
368
+ ]
369
+
370
+ for example_prompt, example_style in examples:
371
+ with gr.Row():
372
+ gr.Textbox(value=example_prompt, show_label=False, interactive=False)
373
+ gr.Button("📋 Use", size="sm").click(
374
+ fn=lambda p=example_prompt, s=example_style: [p, s],
375
+ outputs=[prompt, style_preset]
376
+ )
377
 
378
+ with gr.Column(scale=2, min_width=600):
379
  # Output Section
380
+ status_display = gr.HTML(
381
+ value="<div class='info-box'><h3>Status: Ready</h3><p>Enter a prompt and click Generate</p></div>"
 
 
382
  )
383
 
384
  gallery = gr.Gallery(
 
386
  show_label=True,
387
  columns=2,
388
  height="auto",
389
+ object_fit="cover",
390
+ preview=True,
391
+ visible=False
392
  )
393
 
394
+ # Response and Info
395
+ with gr.Tabs():
396
+ with gr.TabItem("📊 Generation Summary"):
397
+ summary_json = gr.JSON(
398
+ label="Summary",
399
+ container=True
400
+ )
 
 
 
 
401
 
402
+ with gr.TabItem("🔧 Parameters"):
403
+ param_display = gr.JSON(
404
+ label="Current Parameters",
405
+ value={},
406
+ container=True
407
+ )
408
 
409
+ with gr.TabItem("ℹ️ About"):
410
+ gr.Markdown("""
411
+ ### About This App
412
+
413
+ This app uses the **Pixazo FLUX-1 Schnell** AI image generation model.
414
+
415
+ **API Response Format:**
416
+ ```json
417
+ {
418
+ "output": "https://image-url-here.png"
419
+ }
420
+ ```
421
+
422
+ **How it works:**
423
+ 1. Your prompt and settings are sent to Pixazo API
424
+ 2. API returns a JSON with an image URL
425
+ 3. App downloads and displays the image
426
+
427
+ **Tips:**
428
+ - Be descriptive in your prompts
429
+ - Try different styles for varied results
430
+ - Use seeds for reproducible results
431
+ - Start with 4 steps for quick testing
432
+ """)
433
 
434
+ # Event handlers
435
+ def update_param_display(prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale):
436
+ return {
437
+ "prompt": prompt[:100] + "..." if len(prompt) > 100 else prompt,
438
+ "prompt_length": len(prompt),
439
+ "steps": num_steps,
440
+ "seed": seed if seed > 0 else "random",
441
+ "resolution": f"{width}×{height}",
442
+ "style": style_preset,
443
+ "num_images": num_images,
444
+ "guidance_scale": guidance_scale,
445
+ "timestamp": datetime.now().strftime("%H:%M:%S")
446
+ }
447
 
448
+ # Update parameters on input change
449
+ inputs = [prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale]
450
+ for inp in inputs:
451
+ inp.change(
452
+ update_param_display,
453
+ inputs=inputs,
454
+ outputs=param_display
455
+ )
456
 
457
+ # Initialize param display
458
+ demo.load(
459
+ fn=lambda: update_param_display(*[i.value for i in inputs]),
460
+ outputs=param_display
461
+ )
462
+
463
+ # Generate button click
464
+ def on_generate(prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale):
465
+ if not prompt.strip():
466
+ return (
467
+ gr.update(visible=False),
468
+ "<div class='error'><h3>❌ Error</h3><p>Please enter a prompt</p></div>",
469
+ {"error": "No prompt provided"}
470
+ )
471
+
472
+ gallery, status, summary = generate_images(
473
+ prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale
474
  )
475
 
476
+ # Format status HTML
477
+ if "❌" in status:
478
+ status_html = f"<div class='error'><h3>{status}</h3></div>"
479
+ elif "⚠️" in status:
480
+ status_html = f"<div class='warning'><h3>{status}</h3></div>"
481
  else:
482
+ status_html = f"<div class='success'><h3>{status}</h3></div>"
483
+
484
+ return gallery, status_html, summary
485
 
486
+ generate_btn.click(
487
+ fn=on_generate,
488
+ inputs=inputs,
489
+ outputs=[gallery, status_display, summary_json]
490
  )
491
 
492
+ # Clear button
493
  clear_btn.click(
494
+ fn=lambda: [
495
+ gr.update(visible=False),
496
+ "<div class='info-box'><h3>Status: Ready</h3><p>Enter a prompt and click Generate</p></div>",
497
+ {"status": "cleared"}
498
+ ],
499
+ outputs=[gallery, status_display, summary_json]
500
  )
 
 
 
 
 
 
 
501
 
502
+ # Footer
503
+ gr.Markdown("""
504
+ ---
505
+ <div style="text-align: center; color: #666; font-size: 0.9em;">
506
+ <p>Built with Gradio • Powered by Pixazo FLUX-1 Schnell</p>
507
+ <p>API Response Format: <code>{"output": "IMAGE_URL"}</code></p>
508
+ </div>
509
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
510
 
511
  return demo
512
 
513
+ # Simple test function
514
+ def test_connection():
515
+ api_key = get_api_key()
516
+ return {
517
+ "api_key_present": bool(api_key),
518
+ "api_key_length": len(api_key) if api_key else 0,
519
+ "timestamp": datetime.now().isoformat(),
520
+ "gradio_version": gr.__version__
521
+ }
522
+
523
  # Main function
524
  def main():
525
+ print("=" * 60)
526
+ print(f"🚀 Pixazo Image Generator")
527
+ print(f"📦 Gradio Version: {gr.__version__}")
528
+ print(f"🔑 API Key: {'✅ Present' if get_api_key() else '❌ Missing'}")
529
+ print("=" * 60)
530
 
531
  # Create and launch interface
532
  demo = create_interface()
 
534
  demo.launch(
535
  server_name="0.0.0.0",
536
  server_port=7860,
537
+ share=False,
538
+ show_error=True,
539
+ debug=False
540
  )
541
 
542
  if __name__ == "__main__":
requirements.txt CHANGED
@@ -1,4 +1,3 @@
1
- gradio>=4.0
2
  pillow>=10.0.0
3
- requests>=2.31.0
4
- numpy>=1.24.0
 
1
+ gradio>=4.12.0
2
  pillow>=10.0.0
3
+ requests>=2.31.0