Yussifweb3 commited on
Commit
eacc19f
·
verified ·
1 Parent(s): 3fdcd1b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +405 -16
app.py CHANGED
@@ -1,16 +1,405 @@
1
- ```
2
- import { Client } from "@gradio/client";
3
-
4
- const client = await Client.connect("black-forest-labs/FLUX.1-dev");
5
- const result = await client.predict("/infer", {
6
- prompt: "Hello!!",
7
- seed: 0,
8
- randomize_seed: true,
9
- width: 256,
10
- height: 256,
11
- guidance_scale: 1,
12
- num_inference_steps: 1,
13
- });
14
-
15
- console.log(result.data); usse this instead
16
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AI Image Generator</title>
7
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/gradio-client/1.0.0/index.js"></script>
8
+ <style>
9
+ :root {
10
+ --primary-color: #6366f1;
11
+ --secondary-color: #4338ca;
12
+ --background-color: #f9fafb;
13
+ --text-color: #1f2937;
14
+ }
15
+
16
+ * {
17
+ margin: 0;
18
+ padding: 0;
19
+ box-sizing: border-box;
20
+ font-family: system-ui, -apple-system, sans-serif;
21
+ }
22
+
23
+ body {
24
+ background-color: var(--background-color);
25
+ color: var(--text-color);
26
+ min-height: 100vh;
27
+ padding: 2rem;
28
+ line-height: 1.5;
29
+ }
30
+
31
+ .container {
32
+ max-width: 800px;
33
+ margin: 0 auto;
34
+ }
35
+
36
+ header {
37
+ text-align: center;
38
+ margin-bottom: 3rem;
39
+ }
40
+
41
+ h1 {
42
+ font-size: 2.5rem;
43
+ margin-bottom: 1rem;
44
+ color: var(--primary-color);
45
+ }
46
+
47
+ .description {
48
+ color: #6b7280;
49
+ font-size: 1.1rem;
50
+ margin-bottom: 0.5rem;
51
+ }
52
+
53
+ .generator-form {
54
+ background: white;
55
+ padding: 2rem;
56
+ border-radius: 1rem;
57
+ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
58
+ margin-bottom: 2rem;
59
+ }
60
+
61
+ .form-group {
62
+ margin-bottom: 1.5rem;
63
+ }
64
+
65
+ label {
66
+ display: block;
67
+ margin-bottom: 0.5rem;
68
+ font-weight: 500;
69
+ }
70
+
71
+ textarea, input[type="number"] {
72
+ width: 100%;
73
+ padding: 0.75rem;
74
+ border: 1px solid #e5e7eb;
75
+ border-radius: 0.5rem;
76
+ font-size: 1rem;
77
+ }
78
+
79
+ textarea {
80
+ min-height: 100px;
81
+ resize: vertical;
82
+ }
83
+
84
+ .controls {
85
+ display: grid;
86
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
87
+ gap: 1rem;
88
+ margin-top: 1rem;
89
+ }
90
+
91
+ .advanced-options {
92
+ display: grid;
93
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
94
+ gap: 1rem;
95
+ margin-top: 1rem;
96
+ padding-top: 1rem;
97
+ border-top: 1px solid #e5e7eb;
98
+ }
99
+
100
+ button {
101
+ background-color: var(--primary-color);
102
+ color: white;
103
+ padding: 0.75rem 1.5rem;
104
+ border: none;
105
+ border-radius: 0.5rem;
106
+ font-size: 1rem;
107
+ font-weight: 500;
108
+ cursor: pointer;
109
+ transition: all 0.2s;
110
+ }
111
+
112
+ button:hover {
113
+ background-color: var(--secondary-color);
114
+ transform: translateY(-1px);
115
+ }
116
+
117
+ button:disabled {
118
+ background-color: #9ca3af;
119
+ cursor: not-allowed;
120
+ }
121
+
122
+ #clearBtn {
123
+ background-color: #ef4444;
124
+ }
125
+
126
+ #clearBtn:hover {
127
+ background-color: #dc2626;
128
+ }
129
+
130
+ .loading {
131
+ display: none;
132
+ text-align: center;
133
+ margin: 2rem 0;
134
+ padding: 2rem;
135
+ background: white;
136
+ border-radius: 1rem;
137
+ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
138
+ }
139
+
140
+ .loading-spinner {
141
+ border: 4px solid #f3f3f3;
142
+ border-top: 4px solid var(--primary-color);
143
+ border-radius: 50%;
144
+ width: 40px;
145
+ height: 40px;
146
+ animation: spin 1s linear infinite;
147
+ margin: 0 auto 1rem;
148
+ }
149
+
150
+ @keyframes spin {
151
+ 0% { transform: rotate(0deg); }
152
+ 100% { transform: rotate(360deg); }
153
+ }
154
+
155
+ .result {
156
+ display: none;
157
+ text-align: center;
158
+ background: white;
159
+ padding: 2rem;
160
+ border-radius: 1rem;
161
+ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
162
+ }
163
+
164
+ .result img {
165
+ max-width: 100%;
166
+ border-radius: 0.5rem;
167
+ margin-bottom: 1rem;
168
+ }
169
+
170
+ .download-btn {
171
+ background-color: #059669;
172
+ }
173
+
174
+ .download-btn:hover {
175
+ background-color: #047857;
176
+ }
177
+
178
+ .error {
179
+ display: none;
180
+ background-color: #fee2e2;
181
+ color: #991b1b;
182
+ padding: 1rem;
183
+ border-radius: 0.5rem;
184
+ margin-top: 1rem;
185
+ text-align: center;
186
+ }
187
+
188
+ #examples {
189
+ display: grid;
190
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
191
+ gap: 1rem;
192
+ margin-top: 2rem;
193
+ }
194
+
195
+ .example-prompt {
196
+ background: white;
197
+ padding: 1rem;
198
+ border-radius: 0.5rem;
199
+ cursor: pointer;
200
+ transition: all 0.2s;
201
+ }
202
+
203
+ .example-prompt:hover {
204
+ transform: translateY(-2px);
205
+ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
206
+ }
207
+ </style>
208
+ </head>
209
+ <body>
210
+ <div class="container">
211
+ <header>
212
+ <h1>AI Image Generator</h1>
213
+ <p class="description">Create unique images using FLUX.1-dev model</p>
214
+ <p class="description">Powered by Black Forest Labs</p>
215
+ </header>
216
+
217
+ <main>
218
+ <form class="generator-form" id="generatorForm">
219
+ <div class="form-group">
220
+ <label for="prompt">Describe your image:</label>
221
+ <textarea
222
+ id="prompt"
223
+ placeholder="A serene landscape with mountains and a lake at sunset..."
224
+ required
225
+ ></textarea>
226
+ </div>
227
+
228
+ <div class="advanced-options">
229
+ <div class="form-group">
230
+ <label for="width">Width:</label>
231
+ <input type="number" id="width" value="256" min="64" max="1024" step="64">
232
+ </div>
233
+ <div class="form-group">
234
+ <label for="height">Height:</label>
235
+ <input type="number" id="height" value="256" min="64" max="1024" step="64">
236
+ </div>
237
+ <div class="form-group">
238
+ <label for="guidance">Guidance Scale:</label>
239
+ <input type="number" id="guidance" value="1" min="1" max="20" step="0.1">
240
+ </div>
241
+ <div class="form-group">
242
+ <label for="steps">Inference Steps:</label>
243
+ <input type="number" id="steps" value="1" min="1" max="50">
244
+ </div>
245
+ </div>
246
+
247
+ <div class="controls">
248
+ <button type="submit" id="generateBtn">Generate Image</button>
249
+ <button type="button" id="clearBtn">Clear</button>
250
+ </div>
251
+ </form>
252
+
253
+ <div id="examples">
254
+ <div class="example-prompt">
255
+ "A magical forest at twilight with glowing mushrooms"
256
+ </div>
257
+ <div class="example-prompt">
258
+ "A futuristic cityscape with flying cars"
259
+ </div>
260
+ <div class="example-prompt">
261
+ "A cozy cafe interior with steam rising from coffee cups"
262
+ </div>
263
+ </div>
264
+
265
+ <div class="loading" id="loading">
266
+ <div class="loading-spinner"></div>
267
+ <p>Creating your masterpiece... This may take a few moments.</p>
268
+ </div>
269
+
270
+ <div class="error" id="error">
271
+ <p>An error occurred while generating the image. Please try again.</p>
272
+ <p id="errorDetails"></p>
273
+ </div>
274
+
275
+ <div class="result" id="result">
276
+ <img id="generatedImage" alt="Generated image">
277
+ <button class="download-btn" id="downloadBtn">Download Image</button>
278
+ </div>
279
+ </main>
280
+ </div>
281
+
282
+ <script>
283
+ let client = null;
284
+
285
+ async function initClient() {
286
+ try {
287
+ client = await gradioClient.Client.connect("black-forest-labs/FLUX.1-dev");
288
+ console.log('FLUX.1-dev client initialized successfully');
289
+ } catch (err) {
290
+ console.error('Error initializing client:', err);
291
+ showError('Failed to initialize the image generator. Please refresh the page.');
292
+ }
293
+ }
294
+
295
+ // Initialize when the page loads
296
+ window.addEventListener('DOMContentLoaded', initClient);
297
+
298
+ const form = document.getElementById('generatorForm');
299
+ const generateBtn = document.getElementById('generateBtn');
300
+ const clearBtn = document.getElementById('clearBtn');
301
+ const loading = document.getElementById('loading');
302
+ const result = document.getElementById('result');
303
+ const error = document.getElementById('error');
304
+ const errorDetails = document.getElementById('errorDetails');
305
+ const generatedImage = document.getElementById('generatedImage');
306
+ const downloadBtn = document.getElementById('downloadBtn');
307
+ const promptInput = document.getElementById('prompt');
308
+ const examples = document.querySelectorAll('.example-prompt');
309
+
310
+ // Get advanced options inputs
311
+ const widthInput = document.getElementById('width');
312
+ const heightInput = document.getElementById('height');
313
+ const guidanceInput = document.getElementById('guidance');
314
+ const stepsInput = document.getElementById('steps');
315
+
316
+ function showError(message) {
317
+ error.style.display = 'block';
318
+ errorDetails.textContent = message;
319
+ loading.style.display = 'none';
320
+ generateBtn.disabled = false;
321
+ }
322
+
323
+ function clearAll() {
324
+ promptInput.value = '';
325
+ result.style.display = 'none';
326
+ error.style.display = 'none';
327
+ loading.style.display = 'none';
328
+ generateBtn.disabled = false;
329
+ // Reset advanced options to defaults
330
+ widthInput.value = '256';
331
+ heightInput.value = '256';
332
+ guidanceInput.value = '1';
333
+ stepsInput.value = '1';
334
+ }
335
+
336
+ examples.forEach(example => {
337
+ example.addEventListener('click', () => {
338
+ promptInput.value = example.textContent.trim().replace(/"/g, '');
339
+ promptInput.focus();
340
+ });
341
+ });
342
+
343
+ clearBtn.addEventListener('click', clearAll);
344
+
345
+ downloadBtn.addEventListener('click', () => {
346
+ const link = document.createElement('a');
347
+ link.download = 'generated-image.png';
348
+ link.href = generatedImage.src;
349
+ link.click();
350
+ });
351
+
352
+ form.addEventListener('submit', async (e) => {
353
+ e.preventDefault();
354
+
355
+ const prompt = promptInput.value.trim();
356
+
357
+ if (!prompt) {
358
+ showError('Please enter a description for your image.');
359
+ return;
360
+ }
361
+
362
+ if (!client) {
363
+ showError('Image generator is not properly initialized. Please refresh the page.');
364
+ return;
365
+ }
366
+
367
+ // Hide any previous results or errors
368
+ result.style.display = 'none';
369
+ error.style.display = 'none';
370
+
371
+ // Show loading state
372
+ loading.style.display = 'block';
373
+ generateBtn.disabled = true;
374
+
375
+ try {
376
+ const params = {
377
+ prompt: prompt,
378
+ seed: 0,
379
+ randomize_seed: true,
380
+ width: parseInt(widthInput.value),
381
+ height: parseInt(heightInput.value),
382
+ guidance_scale: parseFloat(guidanceInput.value),
383
+ num_inference_steps: parseInt(stepsInput.value)
384
+ };
385
+
386
+ const output = await client.predict("/infer", params);
387
+
388
+ if (output && output.data) {
389
+ generatedImage.src = output.data;
390
+ result.style.display = 'block';
391
+ } else {
392
+ throw new Error('Invalid response from image generator');
393
+ }
394
+ } catch (err) {
395
+ console.error('Error:', err);
396
+ showError('Failed to generate image. Please try again.' +
397
+ (err.message ? ` Error: ${err.message}` : ''));
398
+ } finally {
399
+ loading.style.display = 'none';
400
+ generateBtn.disabled = false;
401
+ }
402
+ });
403
+ </script>
404
+ </body>
405
+ </html>