MySafeCode commited on
Commit
099f061
·
verified ·
1 Parent(s): c7521e1

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +29 -395
  2. requirements.txt +3 -3
app.py CHANGED
@@ -1,28 +1,17 @@
1
  import gradio as gr
2
  import requests
3
- import json
4
  import os
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
11
  def get_api_key():
12
  return os.environ.get("PIXAZO_API_KEY")
13
 
14
- # Call Pixazo API
15
- def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
16
- style_preset=None, guidance_scale=None):
17
-
18
  api_key = get_api_key()
19
-
20
  if not api_key:
21
- return None, {
22
- "error": "API key not configured",
23
- "instructions": "Please set PIXAZO_API_KEY in Hugging Face Space secrets",
24
- "timestamp": datetime.now().isoformat()
25
- }
26
 
27
  url = "https://gateway.pixazo.ai/flux-1-schnell/v1/getData"
28
 
@@ -32,32 +21,15 @@ def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
32
  'Ocp-Apim-Subscription-Key': api_key,
33
  }
34
 
35
- # Prepare request body
36
  body = {
37
  "prompt": prompt,
38
- "num_steps": num_steps,
39
- "height": height,
40
- "width": width,
41
  }
42
 
43
- if seed and seed > 0:
44
- body["seed"] = seed
45
- if style_preset and style_preset != "none":
46
- body["style_preset"] = style_preset
47
- if guidance_scale:
48
- body["guidance_scale"] = guidance_scale
49
-
50
  try:
51
- print(f"🌐 Sending request to Pixazo API...")
52
-
53
- response = requests.post(
54
- url,
55
- headers=headers,
56
- json=body,
57
- timeout=120
58
- )
59
-
60
- print(f"✅ Response status: {response.status_code}")
61
 
62
  if response.status_code == 200:
63
  result = response.json()
@@ -65,380 +37,42 @@ def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
65
  if "output" in result:
66
  image_url = result["output"]
67
 
68
- # Download the image from the URL
69
- try:
70
- print(f"⬇️ Downloading image from URL...")
71
- img_response = requests.get(image_url, timeout=30, headers={
72
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
73
- })
74
-
75
- if img_response.status_code == 200:
76
- image = Image.open(io.BytesIO(img_response.content))
77
-
78
- # Convert to RGB if necessary
79
- if image.mode in ('RGBA', 'LA', 'P'):
80
- image = image.convert('RGB')
81
-
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
- }
97
-
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:
105
- return None, {
106
- "error": "Response missing 'output' field",
107
- "response_keys": list(result.keys()),
108
- "timestamp": datetime.now().isoformat()
109
- }
110
  else:
111
- try:
112
- error_data = response.json()
113
- error_msg = error_data.get("error", str(error_data))
114
- except:
115
- error_msg = response.text[:200] if response.text else "No error message"
116
-
117
- return None, {
118
- "error": f"API returned status {response.status_code}: {error_msg}",
119
- "status_code": response.status_code,
120
- "timestamp": datetime.now().isoformat()
121
- }
122
 
123
- except requests.exceptions.Timeout:
124
- return None, {
125
- "error": "Request timed out after 120 seconds",
126
- "suggestion": "Try reducing image size or number of steps",
127
- "timestamp": datetime.now().isoformat()
128
- }
129
- except requests.exceptions.RequestException as e:
130
- return None, {
131
- "error": f"Network error: {str(e)}",
132
- "timestamp": datetime.now().isoformat()
133
- }
134
  except Exception as e:
135
- return None, {
136
- "error": f"Unexpected error: {str(e)}",
137
- "timestamp": datetime.now().isoformat()
138
- }
139
 
140
- # Create the Gradio interface with correct Gradio 6.x API
141
  with gr.Blocks(title="Pixazo Image Generator") as demo:
 
142
 
143
- # Custom CSS
144
- demo.css = """
145
- .success { color: #10b981 !important; }
146
- .error { color: #ef4444 !important; }
147
- .warning { color: #f59e0b !important; }
148
- .api-status {
149
- padding: 12px 16px;
150
- border-radius: 8px;
151
- margin-bottom: 20px;
152
- }
153
- .api-status-success {
154
- background: #d1fae5;
155
- border-left: 4px solid #10b981;
156
- }
157
- .api-status-error {
158
- background: #fee2e2;
159
- border-left: 4px solid #ef4444;
160
- }
161
- .example-prompt {
162
- cursor: pointer;
163
- padding: 10px;
164
- border-radius: 6px;
165
- margin: 5px 0;
166
- background: #f8fafc;
167
- border: 1px solid #e2e8f0;
168
- }
169
- .example-prompt:hover {
170
- background: #e2e8f0;
171
- }
172
- """
173
-
174
- # Header
175
- gr.Markdown("""
176
- # 🎨 Pixazo AI Image Generator
177
-
178
- Create stunning images with FLUX-1 Schnell model
179
- """)
180
-
181
- # API Status
182
  api_key = get_api_key()
183
  if api_key:
184
- gr.Markdown("""
185
- <div class="api-status api-status-success">
186
- <strong>✅ API Status:</strong> Connected (API key configured)
187
- </div>
188
- """)
189
  else:
190
- gr.Markdown("""
191
- <div class="api-status api-status-error">
192
- <strong>❌ API Status:</strong> Not Configured
193
- <p style="margin: 8px 0 0 0; font-size: 0.9em;">
194
- <strong>Setup:</strong> Go to Space Settings → Repository secrets → Add: <code>PIXAZO_API_KEY</code> = your key
195
- </p>
196
- </div>
197
- """)
198
 
199
  with gr.Row():
200
- # Left column - Inputs
201
- with gr.Column(scale=1, min_width=400):
202
- # Generation Settings group
203
- with gr.Group():
204
- gr.Markdown("### 🎨 Generation Settings")
205
-
206
- prompt = gr.Textbox(
207
- label="Image Prompt",
208
- placeholder="Describe what you want to generate...",
209
- lines=3,
210
- max_lines=5
211
- )
212
-
213
- with gr.Row():
214
- style_preset = gr.Dropdown(
215
- label="Style Preset",
216
- choices=[
217
- "none", "cyberpunk", "fantasy", "anime", "photographic",
218
- "digital-art", "comic", "3d-model", "pixel-art",
219
- "isometric", "watercolor", "oil-painting"
220
- ],
221
- value="none",
222
- scale=2
223
- )
224
-
225
- guidance_scale = gr.Slider(
226
- label="Guidance Scale",
227
- minimum=1.0,
228
- maximum=20.0,
229
- value=7.5,
230
- step=0.5,
231
- scale=1
232
- )
233
-
234
- with gr.Row():
235
- num_steps = gr.Slider(
236
- label="Number of Steps",
237
- minimum=1,
238
- maximum=50,
239
- value=4,
240
- step=1,
241
- scale=1
242
- )
243
-
244
- seed = gr.Number(
245
- label="Seed",
246
- value=42,
247
- minimum=0,
248
- maximum=999999,
249
- scale=1
250
- )
251
-
252
- with gr.Row():
253
- width = gr.Slider(
254
- label="Width",
255
- minimum=256,
256
- maximum=1024,
257
- value=512,
258
- step=64,
259
- scale=1
260
- )
261
-
262
- height = gr.Slider(
263
- label="Height",
264
- minimum=256,
265
- maximum=1024,
266
- value=512,
267
- step=64,
268
- scale=1
269
- )
270
-
271
- num_images = gr.Slider(
272
- label="Number of Images",
273
- minimum=1,
274
- maximum=8,
275
- value=1,
276
- step=1
277
- )
278
-
279
- with gr.Row():
280
- generate_btn = gr.Button("✨ Generate Images", variant="primary", scale=2)
281
- clear_btn = gr.Button("🗑️ Clear", variant="secondary", scale=1)
282
-
283
- # Quick examples
284
- with gr.Accordion("💡 Example Prompts", open=False):
285
- examples = [
286
- ("Cyberpunk city at night with neon lights and flying cars", "cyberpunk"),
287
- ("Majestic dragon on a mountain peak, fantasy art", "fantasy"),
288
- ("Cute anime cat in a magical forest", "anime"),
289
- ("Photorealistic portrait of an astronaut on Mars", "photographic"),
290
- ("Isometric office scene with plants and computers", "isometric"),
291
- ]
292
-
293
- for example_prompt, example_style in examples:
294
- with gr.Row():
295
- prompt_text = gr.Textbox(
296
- value=example_prompt,
297
- show_label=False,
298
- interactive=False,
299
- scale=3
300
- )
301
- use_btn = gr.Button("Use", size="sm", scale=1)
302
-
303
- def use_example(p=example_prompt, s=example_style):
304
- return p, s
305
-
306
- use_btn.click(
307
- use_example,
308
- outputs=[prompt, style_preset]
309
- )
310
 
311
- # Right column - Outputs
312
- with gr.Column(scale=2, min_width=600):
313
- status = gr.Textbox(
314
- label="Status",
315
- value="Ready to generate images...",
316
- interactive=False
317
- )
318
-
319
- gallery = gr.Gallery(
320
- label="Generated Images",
321
- columns=2,
322
- height="auto",
323
- object_fit="contain",
324
- show_label=True,
325
- preview=True
326
- )
327
-
328
- with gr.Accordion("📊 Detailed Response", open=False):
329
- json_output = gr.JSON(
330
- label="API Response",
331
- container=True
332
- )
333
-
334
- # Footer
335
- gr.Markdown("""
336
- ---
337
- <div style="text-align: center; color: #666; font-size: 0.9em; margin-top: 20px;">
338
- <p><strong>API Response Format:</strong> <code>{"output": "IMAGE_URL"}</code></p>
339
- <p>Built with Gradio • Powered by Pixazo FLUX-1 Schnell</p>
340
- </div>
341
- """)
342
 
343
- # Event handlers
344
- def on_generate(prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale):
345
- if not prompt.strip():
346
- yield "❌ Please enter a prompt first", None, {"error": "No prompt provided"}
347
- return
348
-
349
- images = []
350
- all_results = []
351
-
352
- yield "🚀 Starting generation...", None, {"status": "starting"}
353
-
354
- for i in range(num_images):
355
- try:
356
- current_seed = seed + i if seed > 0 else 0
357
-
358
- image, result = call_pixazo_api(
359
- prompt=prompt,
360
- num_steps=num_steps,
361
- seed=current_seed,
362
- height=height,
363
- width=width,
364
- style_preset=style_preset,
365
- guidance_scale=guidance_scale
366
- )
367
-
368
- if image:
369
- images.append(image)
370
-
371
- all_results.append(result)
372
-
373
- status_text = f"Generated {i+1}/{num_images} images"
374
- if "error" in result:
375
- status_text = f"Image {i+1} error: {result['error'][:50]}..."
376
-
377
- yield status_text, images if images else None, result
378
-
379
- if i < num_images - 1:
380
- time.sleep(1)
381
-
382
- except Exception as e:
383
- error_result = {"error": str(e), "image_index": i}
384
- all_results.append(error_result)
385
- yield f"Exception on image {i+1}: {str(e)[:50]}", images if images else None, error_result
386
- break
387
-
388
- # Final summary
389
- success_count = len(images)
390
-
391
- if success_count == 0:
392
- final_status = f"❌ No images generated ({success_count}/{num_images} successful)"
393
- elif success_count < num_images:
394
- final_status = f"⚠️ Partial success: {success_count}/{num_images} images"
395
- else:
396
- final_status = f"🎉 Success! All {success_count} images generated"
397
-
398
- summary = {
399
- "summary": {
400
- "total_attempts": num_images,
401
- "successful": success_count,
402
- "failed": num_images - success_count
403
- },
404
- "parameters": {
405
- "prompt_length": len(prompt),
406
- "steps": num_steps,
407
- "resolution": f"{width}x{height}",
408
- "style": style_preset
409
- }
410
- }
411
-
412
- yield final_status, images if images else None, summary
413
-
414
- def on_clear():
415
- return "Ready to generate images...", None, None
416
-
417
- # Connect buttons
418
- generate_btn.click(
419
- fn=on_generate,
420
- inputs=[prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale],
421
- outputs=[status, gallery, json_output]
422
- )
423
-
424
- clear_btn.click(
425
- fn=on_clear,
426
- outputs=[status, gallery, json_output]
427
- )
428
 
429
- # Launch the app
430
  if __name__ == "__main__":
431
- print("=" * 60)
432
- print("🚀 Pixazo Image Generator")
433
- print(f"📦 Gradio Version: {gr.__version__}")
434
- print(f"🔑 API Key Configured: {'Yes' if get_api_key() else 'No'}")
435
- print("=" * 60)
436
-
437
- demo.launch(
438
- server_name="0.0.0.0",
439
- server_port=7860,
440
- share=False,
441
- show_api=False,
442
- theme=gr.themes.Soft(primary_hue="purple", secondary_hue="pink"),
443
- css=demo.css if hasattr(demo, 'css') else ""
444
- )
 
1
  import gradio as gr
2
  import requests
 
3
  import os
4
  from PIL import Image
5
  import io
 
6
  from datetime import datetime
7
 
 
8
  def get_api_key():
9
  return os.environ.get("PIXAZO_API_KEY")
10
 
11
+ def generate_image(prompt):
 
 
 
12
  api_key = get_api_key()
 
13
  if not api_key:
14
+ return None, "❌ API key not set"
 
 
 
 
15
 
16
  url = "https://gateway.pixazo.ai/flux-1-schnell/v1/getData"
17
 
 
21
  'Ocp-Apim-Subscription-Key': api_key,
22
  }
23
 
 
24
  body = {
25
  "prompt": prompt,
26
+ "num_steps": 4,
27
+ "height": 512,
28
+ "width": 512,
29
  }
30
 
 
 
 
 
 
 
 
31
  try:
32
+ response = requests.post(url, headers=headers, json=body, timeout=60)
 
 
 
 
 
 
 
 
 
33
 
34
  if response.status_code == 200:
35
  result = response.json()
 
37
  if "output" in result:
38
  image_url = result["output"]
39
 
40
+ img_response = requests.get(image_url, timeout=30)
41
+ if img_response.status_code == 200:
42
+ image = Image.open(io.BytesIO(img_response.content))
43
+ if image.mode in ('RGBA', 'LA', 'P'):
44
+ image = image.convert('RGB')
45
+ return image, "✅ Image generated successfully!"
46
+ else:
47
+ return None, f"❌ Failed to download image: HTTP {img_response.status_code}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  else:
49
+ return None, "❌ No image URL in response"
 
 
 
 
50
  else:
51
+ return None, f"❌ API error: {response.status_code}"
 
 
 
 
 
 
 
 
 
 
52
 
 
 
 
 
 
 
 
 
 
 
 
53
  except Exception as e:
54
+ return None, f"❌ Error: {str(e)}"
 
 
 
55
 
56
+ # Simple interface
57
  with gr.Blocks(title="Pixazo Image Generator") as demo:
58
+ gr.Markdown("# 🎨 Pixazo Image Generator")
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  api_key = get_api_key()
61
  if api_key:
62
+ gr.Markdown("✅ API Key: Configured")
 
 
 
 
63
  else:
64
+ gr.Markdown("❌ API Key: Not configured. Set PIXAZO_API_KEY in secrets.")
 
 
 
 
 
 
 
65
 
66
  with gr.Row():
67
+ with gr.Column():
68
+ prompt = gr.Textbox(label="Prompt", lines=3)
69
+ btn = gr.Button("Generate", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
+ with gr.Column():
72
+ image = gr.Image(label="Generated Image")
73
+ status = gr.Textbox(label="Status", interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
+ btn.click(generate_image, inputs=prompt, outputs=[image, status])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
 
77
  if __name__ == "__main__":
78
+ demo.launch(server_name="0.0.0.0", server_port=7860)
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,3 +1,3 @@
1
- gradio==5.10.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