MySafeCode commited on
Commit
355be71
·
verified ·
1 Parent(s): 10321f8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +391 -31
app.py CHANGED
@@ -1,42 +1,402 @@
1
- import os
2
- from flask import Flask, request, jsonify
3
- from flask_cors import CORS
4
  import requests
 
 
 
 
 
 
 
5
 
6
- app = Flask(__name__)
7
- CORS(app) # Enable CORS for all routes
8
-
9
- # Load API key from Hugging Face secrets
10
- API_KEY = os.environ.get("PIXAZO_API_KEY")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
- @app.route('/api/generate', methods=['POST'])
13
- def generate_image():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  try:
15
- if not API_KEY:
16
- return jsonify({"error": "API key not configured"}), 500
17
-
18
- # Get data from frontend
19
- data = request.json
20
-
21
- # Call Pixazo API
22
- headers = {
23
- 'Content-Type': 'application/json',
24
- 'Cache-Control': 'no-cache',
25
- 'Ocp-Apim-Subscription-Key': API_KEY,
26
- }
27
 
28
  response = requests.post(
29
- 'https://gateway.pixazo.ai/flux-1-schnell/v1/getData',
30
- json=data,
31
- headers=headers,
32
- timeout=30
33
  )
34
 
35
- # Return the response from Pixazo
36
- return jsonify(response.json()), response.status_code
 
 
 
 
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  except Exception as e:
39
- return jsonify({"error": str(e)}), 500
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- if __name__ == '__main__':
42
- app.run(host='0.0.0.0', port=7860)
 
 
 
 
 
 
1
+ import gradio as gr
 
 
2
  import requests
3
+ import json
4
+ import os
5
+ import time
6
+ from PIL import Image
7
+ import io
8
+ import base64
9
+ import numpy as np
10
 
11
+ # Get API key from Hugging Face secrets
12
+ def get_api_key():
13
+ # Try multiple environment variable names
14
+ api_key = os.environ.get("PIXAZO_API_KEY") or \
15
+ os.environ.get("PIXAZO_KEY") or \
16
+ os.environ.get("API_KEY")
17
+
18
+ if not api_key:
19
+ # For local testing, you can set it in .env file
20
+ # In production on HF Spaces, it should be in secrets
21
+ print("Warning: API key not found in environment variables")
22
+ print("Please set PIXAZO_API_KEY in Hugging Face Space secrets")
23
+
24
+ # Try reading from a local file for development (never commit this!)
25
+ try:
26
+ with open("api_key.txt", "r") as f:
27
+ api_key = f.read().strip()
28
+ print("Using API key from local file (development only)")
29
+ except:
30
+ pass
31
+
32
+ return api_key
33
 
34
+ # Call Pixazo API
35
+ def call_pixazo_api(prompt, num_steps=4, seed=None, height=512, width=512,
36
+ style_preset=None, guidance_scale=None):
37
+
38
+ api_key = get_api_key()
39
+
40
+ if not api_key:
41
+ raise gr.Error("API key not configured. Please set PIXAZO_API_KEY in Hugging Face secrets.")
42
+
43
+ url = "https://gateway.pixazo.ai/flux-1-schnell/v1/getData"
44
+
45
+ headers = {
46
+ 'Content-Type': 'application/json',
47
+ 'Cache-Control': 'no-cache',
48
+ 'Ocp-Apim-Subscription-Key': api_key,
49
+ }
50
+
51
+ # Prepare request body
52
+ body = {
53
+ "prompt": prompt,
54
+ "num_steps": num_steps,
55
+ "height": height,
56
+ "width": width,
57
+ }
58
+
59
+ if seed and seed > 0:
60
+ body["seed"] = seed
61
+ if style_preset and style_preset != "none":
62
+ body["style_preset"] = style_preset
63
+ if guidance_scale:
64
+ body["guidance_scale"] = guidance_scale
65
+
66
  try:
67
+ print(f"Sending request to Pixazo API with prompt: {prompt[:50]}...")
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  response = requests.post(
70
+ url,
71
+ headers=headers,
72
+ json=body,
73
+ timeout=120 # Increase timeout for image generation
74
  )
75
 
76
+ print(f"Response status code: {response.status_code}")
77
+
78
+ if response.status_code != 200:
79
+ error_msg = f"API Error {response.status_code}: {response.text}"
80
+ print(error_msg)
81
+ raise gr.Error(f"API returned error: {response.status_code}")
82
 
83
+ result = response.json()
84
+ print("API call successful")
85
+
86
+ # Handle different response formats
87
+ # Check for base64 image data
88
+ if "images" in result and isinstance(result["images"], list) and len(result["images"]) > 0:
89
+ image_data = result["images"][0]
90
+
91
+ # If it's base64 encoded
92
+ if isinstance(image_data, str) and image_data.startswith("data:image"):
93
+ # Extract base64 from data URL
94
+ image_data = image_data.split(",")[1]
95
+
96
+ # Decode base64 to image
97
+ try:
98
+ image_bytes = base64.b64decode(image_data)
99
+ image = Image.open(io.BytesIO(image_bytes))
100
+ return image, result
101
+ except Exception as e:
102
+ print(f"Error decoding base64 image: {e}")
103
+
104
+ # If no image in response, return info message
105
+ return None, result
106
+
107
+ except requests.exceptions.Timeout:
108
+ raise gr.Error("Request timed out. The API might be busy. Please try again.")
109
+ except requests.exceptions.RequestException as e:
110
+ raise gr.Error(f"Network error: {str(e)}")
111
  except Exception as e:
112
+ raise gr.Error(f"Unexpected error: {str(e)}")
113
+
114
+ # Batch generate images
115
+ def generate_images(prompt, num_steps, seed, height, width, style_preset,
116
+ num_images, guidance_scale):
117
+
118
+ images = []
119
+ results = []
120
+
121
+ for i in range(num_images):
122
+ try:
123
+ # Use different seed for each image if seed is provided
124
+ current_seed = seed + i if seed > 0 else 0
125
+
126
+ image, result = call_pixazo_api(
127
+ prompt=prompt,
128
+ num_steps=num_steps,
129
+ seed=current_seed,
130
+ height=height,
131
+ width=width,
132
+ style_preset=style_preset,
133
+ guidance_scale=guidance_scale
134
+ )
135
+
136
+ if image:
137
+ images.append(image)
138
+ results.append(result)
139
+
140
+ # Update progress
141
+ yield [gr.Gallery(value=images, visible=True),
142
+ f"Generated {i+1}/{num_images} images...",
143
+ json.dumps(results[-1], indent=2)]
144
+
145
+ # Small delay between requests
146
+ if i < num_images - 1:
147
+ time.sleep(1)
148
+
149
+ except Exception as e:
150
+ yield [gr.Gallery(value=images, visible=True),
151
+ f"Error on image {i+1}: {str(e)}",
152
+ json.dumps({"error": str(e)}, indent=2)]
153
+ break
154
+
155
+ if not images:
156
+ yield [gr.Gallery(visible=False),
157
+ "No images were generated successfully.",
158
+ json.dumps(results, indent=2)]
159
+ else:
160
+ yield [gr.Gallery(value=images, visible=True),
161
+ f"Successfully generated {len(images)} image(s)!",
162
+ json.dumps(results, indent=2)]
163
+
164
+ # Example prompts
165
+ example_prompts = [
166
+ ["A sleek futuristic car racing through a neon-lit cyberpunk city at night, with rain reflections and holographic advertisements", 4, 42, 512, 512, "cyberpunk", 1, 7.5],
167
+ ["A majestic dragon perched on a mountain peak overlooking a fantasy landscape with floating islands, sunset lighting", 4, 123, 512, 512, "fantasy", 1, 7.5],
168
+ ["A cute anime character with pink hair and magical powers in a cherry blossom garden, studio ghibli style", 4, 456, 512, 512, "anime", 1, 7.5],
169
+ ["A photorealistic portrait of an astronaut on Mars with detailed spacesuit and red planet landscape", 4, 789, 512, 512, "photographic", 1, 7.5],
170
+ ]
171
+
172
+ # Create Gradio interface
173
+ def create_interface():
174
+ with gr.Blocks(theme=gr.themes.Soft(), title="Pixazo Image Generator") as demo:
175
+ gr.Markdown("""
176
+ # 🎨 Pixazo FLUX-1 Schnell Image Generator
177
+ Generate stunning AI images using Pixazo's FLUX-1 Schnell model
178
+ """)
179
+
180
+ # API Status Check
181
+ api_key_status = "✅ Configured" if get_api_key() else "❌ Not Configured"
182
+ gr.Markdown(f"### API Key Status: {api_key_status}")
183
+
184
+ if not get_api_key():
185
+ gr.Markdown("""
186
+ ⚠️ **Setup Required**:
187
+ 1. Go to your Space Settings → Repository secrets
188
+ 2. Add a new secret: **Key**: `PIXAZO_API_KEY`, **Value**: your API key
189
+ 3. Restart the Space
190
+ """)
191
+
192
+ with gr.Row():
193
+ with gr.Column(scale=2):
194
+ # Input Section
195
+ with gr.Group():
196
+ prompt = gr.Textbox(
197
+ label="Prompt",
198
+ placeholder="Describe the image you want to generate...",
199
+ lines=3,
200
+ max_lines=6
201
+ )
202
+
203
+ with gr.Row():
204
+ style_preset = gr.Dropdown(
205
+ label="Style Preset",
206
+ choices=["none", "cyberpunk", "fantasy", "anime", "photographic",
207
+ "digital-art", "comic", "line-art", "3d-model", "pixel-art"],
208
+ value="none"
209
+ )
210
+
211
+ guidance_scale = gr.Slider(
212
+ label="Guidance Scale",
213
+ minimum=1.0,
214
+ maximum=20.0,
215
+ value=7.5,
216
+ step=0.5
217
+ )
218
+
219
+ with gr.Row():
220
+ num_steps = gr.Slider(
221
+ label="Number of Steps",
222
+ minimum=1,
223
+ maximum=50,
224
+ value=4,
225
+ step=1
226
+ )
227
+
228
+ seed = gr.Number(
229
+ label="Seed (0 for random)",
230
+ value=0,
231
+ minimum=0,
232
+ maximum=999999
233
+ )
234
+
235
+ with gr.Row():
236
+ width = gr.Slider(
237
+ label="Width",
238
+ minimum=256,
239
+ maximum=1024,
240
+ value=512,
241
+ step=64
242
+ )
243
+
244
+ height = gr.Slider(
245
+ label="Height",
246
+ minimum=256,
247
+ maximum=1024,
248
+ value=512,
249
+ step=64
250
+ )
251
+
252
+ num_images = gr.Slider(
253
+ label="Number of Images",
254
+ minimum=1,
255
+ maximum=4,
256
+ value=1,
257
+ step=1
258
+ )
259
+
260
+ generate_btn = gr.Button("✨ Generate Images", variant="primary", size="lg")
261
+
262
+ # Examples
263
+ gr.Examples(
264
+ examples=example_prompts,
265
+ inputs=[prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale],
266
+ label="Try these examples:",
267
+ examples_per_page=4
268
+ )
269
+
270
+ with gr.Column(scale=3):
271
+ # Output Section
272
+ status = gr.Textbox(
273
+ label="Status",
274
+ interactive=False,
275
+ value="Ready to generate..."
276
+ )
277
+
278
+ gallery = gr.Gallery(
279
+ label="Generated Images",
280
+ show_label=True,
281
+ columns=2,
282
+ height="auto",
283
+ visible=False
284
+ )
285
+
286
+ with gr.Accordion("API Response Details", open=False):
287
+ json_output = gr.JSON(
288
+ label="Raw API Response",
289
+ visible=True
290
+ )
291
+
292
+ # Download buttons will be added dynamically
293
+
294
+ # Footer
295
+ gr.Markdown("""
296
+ ---
297
+ ### 📝 Notes:
298
+ - **API Key**: Set `PIXAZO_API_KEY` in Hugging Face Space secrets
299
+ - **Generation Time**: Usually takes 10-30 seconds per image
300
+ - **Image Quality**: Higher steps = better quality but slower generation
301
+ - **Seed**: Use the same seed with same prompt to get consistent results
302
+
303
+ ### ⚙️ Tips:
304
+ - Be descriptive in your prompts for better results
305
+ - Try different style presets for varied artistic effects
306
+ - Adjust guidance scale for prompt adherence (higher = more strict)
307
+ """)
308
+
309
+ # Generation function
310
+ generate_btn.click(
311
+ fn=generate_images,
312
+ inputs=[prompt, num_steps, seed, height, width, style_preset, num_images, guidance_scale],
313
+ outputs=[gallery, status, json_output]
314
+ )
315
+
316
+ # Quick action buttons
317
+ with gr.Row():
318
+ gr.Button("📋 Copy Prompt").click(
319
+ fn=lambda x: x,
320
+ inputs=[prompt],
321
+ outputs=[prompt]
322
+ )
323
+
324
+ clear_btn = gr.Button("🗑️ Clear All")
325
+ clear_btn.click(
326
+ fn=lambda: [None, "Ready to generate...", None, None],
327
+ outputs=[gallery, status, json_output, prompt]
328
+ )
329
+
330
+ return demo
331
+
332
+ # Alternative simple interface
333
+ def create_simple_interface():
334
+ with gr.Blocks(title="Pixazo - Simple Generator") as demo:
335
+ gr.Markdown("# 🖼️ Simple Pixazo Generator")
336
+
337
+ with gr.Row():
338
+ with gr.Column():
339
+ prompt = gr.Textbox(label="Prompt", lines=3)
340
+ btn = gr.Button("Generate", variant="primary")
341
+
342
+ with gr.Column():
343
+ output = gr.Image(label="Generated Image")
344
+ status = gr.Textbox(label="Status", interactive=False)
345
+
346
+ def simple_generate(prompt_text):
347
+ if not prompt_text.strip():
348
+ return None, "Please enter a prompt"
349
+
350
+ api_key = get_api_key()
351
+ if not api_key:
352
+ return None, "API key not configured"
353
+
354
+ try:
355
+ image, result = call_pixazo_api(
356
+ prompt=prompt_text,
357
+ num_steps=4,
358
+ height=512,
359
+ width=512
360
+ )
361
+
362
+ if image:
363
+ return image, "Generation successful!"
364
+ else:
365
+ return None, f"API Response: {json.dumps(result, indent=2)[:200]}..."
366
+
367
+ except Exception as e:
368
+ return None, f"Error: {str(e)}"
369
+
370
+ btn.click(
371
+ fn=simple_generate,
372
+ inputs=[prompt],
373
+ outputs=[output, status]
374
+ )
375
+
376
+ return demo
377
+
378
+ # Main function
379
+ def main():
380
+ # Choose which interface to use
381
+ interface_choice = "advanced" # Change to "simple" for simpler version
382
+
383
+ if interface_choice == "advanced":
384
+ demo = create_interface()
385
+ else:
386
+ demo = create_simple_interface()
387
+
388
+ # Launch with appropriate settings for Hugging Face Spaces
389
+ demo.launch(
390
+ server_name="0.0.0.0",
391
+ server_port=7860,
392
+ share=False,
393
+ debug=False
394
+ )
395
 
396
+ if __name__ == "__main__":
397
+ # Check if running on Hugging Face Spaces
398
+ if os.environ.get("SPACE_ID"):
399
+ print("Running on Hugging Face Spaces")
400
+ print(f"Space ID: {os.environ.get('SPACE_ID')}")
401
+
402
+ main()