BetaGen commited on
Commit
4c4d4ab
Β·
verified Β·
1 Parent(s): 3e49819

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +337 -6
app.py CHANGED
@@ -1,6 +1,337 @@
1
- gradio==4.44.0
2
- huggingface-hub==0.24.6
3
- Pillow==10.4.0
4
- python-dotenv==1.0.1
5
- requests==2.32.3
6
- numpy==1.26.4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ gimport gradio as gr
2
+ import os
3
+ from huggingface_hub import InferenceClient
4
+ from PIL import Image
5
+ import requests
6
+ from io import BytesIO
7
+ import time
8
+ from datetime import datetime
9
+
10
+ # Custom CSS for a modern, attractive interface
11
+ custom_css = """
12
+ .gradio-container {
13
+ font-family: 'Inter', sans-serif;
14
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
15
+ min-height: 100vh;
16
+ }
17
+
18
+ .container {
19
+ max-width: 1200px !important;
20
+ margin: auto;
21
+ padding: 20px;
22
+ }
23
+
24
+ #title {
25
+ text-align: center;
26
+ color: white;
27
+ font-size: 3em;
28
+ font-weight: 800;
29
+ margin-bottom: 10px;
30
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
31
+ letter-spacing: -1px;
32
+ }
33
+
34
+ #subtitle {
35
+ text-align: center;
36
+ color: rgba(255,255,255,0.9);
37
+ font-size: 1.2em;
38
+ margin-bottom: 30px;
39
+ font-weight: 400;
40
+ }
41
+
42
+ .input-container {
43
+ background: rgba(255,255,255,0.95);
44
+ border-radius: 20px;
45
+ padding: 30px;
46
+ box-shadow: 0 20px 60px rgba(0,0,0,0.3);
47
+ backdrop-filter: blur(10px);
48
+ margin-bottom: 30px;
49
+ }
50
+
51
+ .output-container {
52
+ background: rgba(255,255,255,0.95);
53
+ border-radius: 20px;
54
+ padding: 30px;
55
+ box-shadow: 0 20px 60px rgba(0,0,0,0.3);
56
+ backdrop-filter: blur(10px);
57
+ }
58
+
59
+ .generate-btn {
60
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
61
+ color: white !important;
62
+ font-size: 1.2em !important;
63
+ font-weight: 600 !important;
64
+ padding: 15px 40px !important;
65
+ border-radius: 10px !important;
66
+ border: none !important;
67
+ cursor: pointer !important;
68
+ transition: transform 0.2s !important;
69
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4) !important;
70
+ }
71
+
72
+ .generate-btn:hover {
73
+ transform: translateY(-2px) !important;
74
+ box-shadow: 0 6px 20px rgba(102, 126, 234, 0.5) !important;
75
+ }
76
+
77
+ .prompt-ideas {
78
+ display: flex;
79
+ flex-wrap: wrap;
80
+ gap: 10px;
81
+ margin-top: 15px;
82
+ }
83
+
84
+ .prompt-tag {
85
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
86
+ color: white;
87
+ padding: 8px 15px;
88
+ border-radius: 20px;
89
+ font-size: 0.9em;
90
+ cursor: pointer;
91
+ transition: transform 0.2s;
92
+ }
93
+
94
+ .prompt-tag:hover {
95
+ transform: scale(1.05);
96
+ }
97
+
98
+ footer {
99
+ display: none !important;
100
+ }
101
+
102
+ .progress-bar {
103
+ background: linear-gradient(90deg, #667eea, #764ba2, #667eea) !important;
104
+ background-size: 200% 100% !important;
105
+ animation: shimmer 2s infinite !important;
106
+ }
107
+
108
+ @keyframes shimmer {
109
+ 0% { background-position: 0% 50%; }
110
+ 100% { background-position: 200% 50%; }
111
+ }
112
+ """
113
+
114
+ # Initialize the Hugging Face client
115
+ def init_client():
116
+ token = os.environ.get('HF_TOKEN')
117
+ if not token:
118
+ # Fallback for demo purposes - replace with your token
119
+ # IMPORTANT: In production, always use environment variables
120
+ token = "HF_TOKEN" # Replace with new token
121
+
122
+ return InferenceClient(
123
+ provider="auto",
124
+ api_key=token,
125
+ )
126
+
127
+ # Sample prompts for inspiration
128
+ SAMPLE_PROMPTS = [
129
+ "πŸŒƒ Cyberpunk city at night with neon lights",
130
+ "🌸 Japanese garden in cherry blossom season",
131
+ "πŸ”οΈ Majestic mountain landscape at sunset",
132
+ "πŸš€ Futuristic space station orbiting Earth",
133
+ "πŸ§™β€β™‚οΈ Wizard's tower in a magical forest",
134
+ "πŸ–οΈ Tropical beach with crystal clear water",
135
+ "🎨 Abstract colorful art explosion",
136
+ "πŸ›οΈ Ancient Greek temple at golden hour",
137
+ "🌌 Galaxy with vibrant nebula colors",
138
+ "πŸ¦‹ Macro shot of butterfly on flower"
139
+ ]
140
+
141
+ def generate_image(prompt, style_preset, negative_prompt, num_steps, guidance_scale, progress=gr.Progress()):
142
+ """Generate image using Hugging Face Inference API"""
143
+
144
+ if not prompt:
145
+ return None, "⚠️ Please enter a prompt to generate an image."
146
+
147
+ try:
148
+ progress(0, desc="🎨 Initializing AI model...")
149
+ client = init_client()
150
+
151
+ # Add style to prompt if selected
152
+ enhanced_prompt = prompt
153
+ if style_preset != "None":
154
+ style_additions = {
155
+ "Photorealistic": "photorealistic, highly detailed, professional photography, 8k resolution",
156
+ "Artistic": "artistic, painterly, creative, expressive brushstrokes",
157
+ "Anime": "anime style, manga art, japanese animation, vibrant colors",
158
+ "Digital Art": "digital art, concept art, highly detailed, artstation trending",
159
+ "Oil Painting": "oil painting, classical art, museum quality, masterpiece",
160
+ "Watercolor": "watercolor painting, soft colors, artistic, flowing",
161
+ "3D Render": "3d render, octane render, unreal engine, ray tracing",
162
+ "Vintage": "vintage style, retro, nostalgic, old photograph aesthetic"
163
+ }
164
+ enhanced_prompt = f"{prompt}, {style_additions[style_preset]}"
165
+
166
+ progress(0.3, desc="πŸš€ Sending request to AI...")
167
+
168
+ # Generate the image
169
+ start_time = time.time()
170
+
171
+ # Note: The InferenceClient doesn't support all parameters directly
172
+ # Using the model's default settings
173
+ image = client.text_to_image(
174
+ enhanced_prompt,
175
+ model="Shakker-Labs/AWPortrait-QW",
176
+ )
177
+
178
+ generation_time = time.time() - start_time
179
+
180
+ progress(0.9, desc="✨ Finalizing your creation...")
181
+
182
+ # Add timestamp to image metadata
183
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
184
+
185
+ success_message = f"""
186
+ βœ… **Image generated successfully!**
187
+
188
+ πŸ“ **Prompt used:** {enhanced_prompt}
189
+ ⏱️ **Generation time:** {generation_time:.2f} seconds
190
+ πŸ• **Created at:** {timestamp}
191
+ 🎨 **Model:** Shakker-Labs/AWPortrait-QW
192
+ """
193
+
194
+ progress(1.0, desc="βœ… Complete!")
195
+
196
+ return image, success_message
197
+
198
+ except Exception as e:
199
+ error_message = f"""
200
+ ❌ **Error generating image:**
201
+ {str(e)}
202
+
203
+ **Troubleshooting tips:**
204
+ - Check if your HF_TOKEN is valid
205
+ - Ensure you have internet connection
206
+ - Try a simpler prompt
207
+ - Check if the model is available
208
+ """
209
+ return None, error_message
210
+
211
+ def use_sample_prompt(prompt):
212
+ """Extract the actual prompt from the sample (remove emoji)"""
213
+ return prompt.split(' ', 1)[1] if ' ' in prompt else prompt
214
+
215
+ # Create the Gradio interface
216
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as app:
217
+ # Header
218
+ gr.HTML("""
219
+ <div id="title">🎨 AI Image Generator</div>
220
+ <div id="subtitle">Transform your ideas into stunning visuals with AI</div>
221
+ """)
222
+
223
+ with gr.Row():
224
+ with gr.Column(scale=1, elem_classes="input-container"):
225
+ gr.Markdown("### πŸ–ΌοΈ Create Your Masterpiece")
226
+
227
+ # Main prompt input
228
+ prompt_input = gr.Textbox(
229
+ label="Enter your prompt",
230
+ placeholder="Describe what you want to see...",
231
+ lines=3,
232
+ elem_id="prompt-input"
233
+ )
234
+
235
+ # Style presets
236
+ style_preset = gr.Dropdown(
237
+ label="🎨 Style Preset",
238
+ choices=["None", "Photorealistic", "Artistic", "Anime", "Digital Art",
239
+ "Oil Painting", "Watercolor", "3D Render", "Vintage"],
240
+ value="None"
241
+ )
242
+
243
+ # Advanced settings (collapsible)
244
+ with gr.Accordion("βš™οΈ Advanced Settings", open=False):
245
+ negative_prompt = gr.Textbox(
246
+ label="Negative Prompt",
247
+ placeholder="What you don't want in the image...",
248
+ lines=2
249
+ )
250
+
251
+ with gr.Row():
252
+ num_steps = gr.Slider(
253
+ label="Inference Steps",
254
+ minimum=10,
255
+ maximum=50,
256
+ value=30,
257
+ step=5
258
+ )
259
+
260
+ guidance_scale = gr.Slider(
261
+ label="Guidance Scale",
262
+ minimum=1,
263
+ maximum=20,
264
+ value=7.5,
265
+ step=0.5
266
+ )
267
+
268
+ # Sample prompts section
269
+ gr.Markdown("### πŸ’‘ Need Inspiration?")
270
+ sample_prompts = gr.Dropdown(
271
+ label="Choose a sample prompt",
272
+ choices=SAMPLE_PROMPTS,
273
+ interactive=True
274
+ )
275
+
276
+ # Generate button
277
+ generate_btn = gr.Button(
278
+ "πŸš€ Generate Image",
279
+ elem_classes="generate-btn",
280
+ variant="primary"
281
+ )
282
+
283
+ with gr.Column(scale=1, elem_classes="output-container"):
284
+ gr.Markdown("### πŸ–ΌοΈ Generated Image")
285
+
286
+ # Output image
287
+ output_image = gr.Image(
288
+ label="Your Creation",
289
+ type="pil",
290
+ elem_id="output-image"
291
+ )
292
+
293
+ # Status/Info output
294
+ output_status = gr.Markdown(
295
+ value="Ready to generate your first image! 🎨"
296
+ )
297
+
298
+ # Footer with tips
299
+ gr.HTML("""
300
+ <div style="text-align: center; margin-top: 40px; color: white; opacity: 0.9;">
301
+ <h3>πŸ’‘ Pro Tips for Better Results</h3>
302
+ <p>β€’ Be specific and descriptive in your prompts</p>
303
+ <p>β€’ Include details about lighting, mood, and style</p>
304
+ <p>β€’ Experiment with different style presets</p>
305
+ <p>β€’ Use negative prompts to exclude unwanted elements</p>
306
+ </div>
307
+ """)
308
+
309
+ # Event handlers
310
+ sample_prompts.change(
311
+ fn=use_sample_prompt,
312
+ inputs=[sample_prompts],
313
+ outputs=[prompt_input]
314
+ )
315
+
316
+ generate_btn.click(
317
+ fn=generate_image,
318
+ inputs=[prompt_input, style_preset, negative_prompt, num_steps, guidance_scale],
319
+ outputs=[output_image, output_status]
320
+ )
321
+
322
+ # Also allow generation by pressing Enter in the prompt field
323
+ prompt_input.submit(
324
+ fn=generate_image,
325
+ inputs=[prompt_input, style_preset, negative_prompt, num_steps, guidance_scale],
326
+ outputs=[output_image, output_status]
327
+ )
328
+
329
+ # Launch the app
330
+ if __name__ == "__main__":
331
+ app.launch(
332
+ share=True,
333
+ show_error=True,
334
+ server_name="0.0.0.0",
335
+ server_port=7860,
336
+ favicon_path=None
337
+ )