seawolf2357 commited on
Commit
063cf14
·
verified ·
1 Parent(s): ce762ad

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +27 -608
app.py CHANGED
@@ -1,616 +1,35 @@
1
- # ===== CRITICAL: Import spaces FIRST before any CUDA operations =====
2
- try:
3
- import spaces
4
- HF_SPACES = True
5
- except ImportError:
6
- # If running locally, create a dummy decorator
7
- def spaces_gpu_decorator(duration=60):
8
- def decorator(func):
9
- return func
10
- return decorator
11
- spaces = type('spaces', (), {'GPU': spaces_gpu_decorator})()
12
- HF_SPACES = False
13
- print("Warning: Running without Hugging Face Spaces GPU allocation")
14
-
15
- # ===== Now import other libraries =====
16
- import random
17
  import os
18
- import uuid
19
- from datetime import datetime
20
-
21
- import gradio as gr
22
- import numpy as np
23
- import torch
24
- from diffusers import StableDiffusionXLPipeline
25
- from diffusers import EulerAncestralDiscreteScheduler
26
- from compel import Compel, ReturnedEmbeddingsType
27
- from PIL import Image
28
-
29
- # ===== Style presets =====
30
- STYLE_PRESETS = {
31
- "None": "",
32
- "Realistic Photo": "photorealistic, 8k, ultra-detailed, cinematic lighting, realistic skin texture",
33
- "Oil Painting": "oil painting, rich brush strokes, canvas texture, baroque lighting",
34
- "Comic Book": "comic book style, bold ink outlines, cel shading, vibrant colors",
35
- "Watercolor": "watercolor illustration, soft gradients, splatter effect, pastel palette",
36
- }
37
-
38
- # ===== Random prompt examples =====
39
- prompt_examples = [
40
- "The shy college girl, with glasses and a tight plaid skirt, nervously approaches her professor",
41
- "Her skirt rose a little higher with each gentle push, a soft blush of blush spreading across her cheeks as she felt the satisfying warmth of his breath on her cheek.",
42
- "a girl in a school uniform having her skirt pulled up by a boy, and then being fucked",
43
- "Moody mature anime scene of two lovers fuck under neon rain, sensual atmosphere",
44
- "Moody mature anime scene of two lovers kissing under neon rain, sensual atmosphere",
45
- "The girl sits on the boy's lap by the window, his hands resting on her waist. She is unbuttoning his shirt, her expression focused and intense.",
46
- "A girl with long, black hair is sleeping on her desk in the classroom. Her skirt has ridden up, revealing her thighs, and a trail of drool escapes her slightly parted lips.",
47
- "The waves rolled gently, a slow, sweet kiss of the lip, a slow, slow build of anticipation as their toes bumped gently – a slow, sweet kiss of the lip, a promise of more to come.",
48
- "Her elegant silk gown swayed gracefully as she approached him, the delicate fabric brushing against her legs. A warm blush spread across her cheeks as she felt his breath on her face.",
49
- "Her white blouse and light cotton skirt rose a little higher with each gentle push, a soft blush spreading across her cheeks as she felt the satisfying warmth of his breath on her cheek.",
50
- "A woman in a business suit having her skirt lifted by a man, and then being sexually assaulted.",
51
- "The older woman sits on the man's lap by the fireplace, his hands resting on her hips. She is unbuttoning his vest, her expression focused and intense. He takes control of the situation as she finishes unbuttoning his shirt, pushing her onto her back and begins to have sex with her.",
52
- "There is a woman with long black hair. Her face features alluring eyes and full lips, with a slender figure adorned in black lace lingerie. She lies on the bed, loosening her lingerie strap with one hand while seductively glancing downward.",
53
- "In a dimly lit room, the same woman teases with her dark, flowing hair, now covering her voluptuous breasts, while a black garter belt accentuates her thighs. She sits on the sofa, leaning back, lifting one leg to expose her most private areas through the sheer lingerie.",
54
- "A woman with glasses, lying on the bed in just her bra, spreads her legs wide, revealing all! She wears a sultry expression, gazing directly at the viewer with her brown eyes, her short black hair cascading over the pillow. Her slim figure, accentuated by the lacy lingerie, exudes a seductive aura.",
55
- "A soft focus on the girl's face, eyes closed, biting her lip, as her roommate performs oral pleasure, the experienced woman's hair cascading between her thighs.",
56
- "A woman in a blue hanbok sits on a wooden floor, her legs folded beneath her, gazing out of a window, the sunlight highlighting the graceful lines of her clothing.",
57
- "The couple, immersed in a wooden outdoor bath, share an intimate moment, her wet kimono clinging to her curves, his hands exploring her body beneath the water's surface.",
58
- "A steamy shower scene, the twins embrace under the warm water, their soapy hands gliding over each other's curves, their passion intensifying as they explore uncharted territories.",
59
- "The teacher, with a firm grip, pins the student against the blackboard, her skirt hiked up, exposing her delicate lace panties. Their heavy breathing echoes in the quiet room as they share an intense, intimate moment.",
60
- "After hours, the girl sits on top of the teacher's lap, riding him on the classroom floor, her hair cascading over her face as she moves with increasing intensity, their bodies glistening with sweat.",
61
- "In the dimly lit dorm room, the roommates lay entangled in a passionate embrace, their naked bodies glistening with sweat, as the experienced woman teaches her lover the art of kissing and touching.",
62
- "The once-innocent student, now confident, takes charge, straddling her lover on the couch, their bare skin illuminated by the warm glow of the sunset through the window.",
63
- "A close-up of the secretary's hand unzipping her boss's dress shirt, her fingers gently caressing his chest, their eyes locked in a heated embrace in the supply closet.",
64
- "The secretary, in a tight pencil skirt and silk blouse, leans back on the boss's desk, her legs wrapped around his waist, her blouse unbuttoned, revealing her lace bra, as he passionately kisses her, his hands exploring her body.",
65
- "On the living room couch, one twin sits astride her sister's lap, their lips locked in a passionate kiss, their hands tangled in each other's hair, unraveling a new level of intimacy.",
66
- "In a dimly lit chamber, the dominant woman, dressed in a leather corset and thigh-high boots, stands tall, her hand gripping her submissive partner's hair, his eyes closed in submission as she instructs him to please her.",
67
- "The dominant, in a sheer lace bodysuit, sits on a throne-like chair, her legs spread, as the submissive, on his knees, worships her with his tongue, his hands bound behind his back.",
68
- "A traditional Japanese onsen, with steam rising, a young woman in a colorful kimono kneels on a tatami mat, her back to the viewer, as her male partner, also in a kimono, gently unties her obi, revealing her bare back.",
69
- "In a serene outdoor setting, the woman, in a vibrant summer kimono, sits on a bench, her legs slightly spread, her partner kneeling before her, his hands gently caressing her exposed thigh.",
70
- ]
71
-
72
- # ===== Save directory =====
73
- SAVE_DIR = "saved_images"
74
- if not os.path.exists(SAVE_DIR):
75
- os.makedirs(SAVE_DIR, exist_ok=True)
76
-
77
- # ===== Device & model loading =====
78
- device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
79
- print(f"Using device: {device}")
80
-
81
- # Add error handling for model loading
82
- try:
83
- # Make sure to use torch.float16 consistently throughout the pipeline
84
- pipeline = StableDiffusionXLPipeline.from_pretrained(
85
- "votepurchase/pornmasterPro_noobV3VAE",
86
- torch_dtype=torch.float16,
87
- variant="fp16", # Explicitly use fp16 variant
88
- use_safetensors=True # Use safetensors if available
89
- )
90
-
91
- pipeline.scheduler = EulerAncestralDiscreteScheduler.from_config(pipeline.scheduler.config)
92
- pipeline.to(device)
93
-
94
- # Force all components to use the same dtype
95
- pipeline.text_encoder.to(torch.float16)
96
- pipeline.text_encoder_2.to(torch.float16)
97
- pipeline.vae.to(torch.float16)
98
- pipeline.unet.to(torch.float16)
99
-
100
- # Initialize Compel for long prompt processing
101
- compel = Compel(
102
- tokenizer=[pipeline.tokenizer, pipeline.tokenizer_2],
103
- text_encoder=[pipeline.text_encoder, pipeline.text_encoder_2],
104
- returned_embeddings_type=ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED,
105
- requires_pooled=[False, True],
106
- truncate_long_prompts=False
107
- )
108
-
109
- print("Model loaded successfully")
110
- except Exception as e:
111
- print(f"Error loading model: {e}")
112
- pipeline = None
113
- compel = None
114
-
115
- MAX_SEED = np.iinfo(np.int32).max
116
- MAX_IMAGE_SIZE = 1216
117
 
118
- def prepare_prompt(user_prompt: str, style_key: str) -> str:
119
- """Apply style preset to prompt."""
120
- style_suffix = STYLE_PRESETS.get(style_key, "")
121
- if style_suffix:
122
- final_prompt = f"{user_prompt}, {style_suffix}"
123
- else:
124
- final_prompt = user_prompt
125
-
126
- return final_prompt
127
-
128
- def get_random_prompt():
129
- """Get a random prompt from the examples list."""
130
- return random.choice(prompt_examples)
131
-
132
- # ===== Image saving =====
133
- def save_generated_image(image: Image.Image, prompt: str) -> str:
134
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
135
- unique_id = str(uuid.uuid4())[:8]
136
- filename = f"{timestamp}_{unique_id}.png"
137
- filepath = os.path.join(SAVE_DIR, filename)
138
- image.save(filepath)
139
-
140
- # Save metadata
141
- metadata_file = os.path.join(SAVE_DIR, "metadata.txt")
142
- with open(metadata_file, "a", encoding="utf-8") as f:
143
- f.write(f"{filename}|{prompt}|{timestamp}\n")
144
- return filepath
145
-
146
- # ===== Long prompt processing function =====
147
- def process_long_prompt(prompt, negative_prompt=""):
148
- """Simple long prompt processing using Compel"""
149
  try:
150
- conditioning, pooled = compel([prompt, negative_prompt])
151
- return conditioning, pooled
152
- except Exception as e:
153
- print(f"Long prompt processing failed: {e}, falling back to standard processing")
154
- return None, None
155
-
156
- # ===== Diffusion call =====
157
- def run_pipeline(prompt: str, negative_prompt: str, seed: int, width: int, height: int, guidance_scale: float, num_steps: int):
158
- if pipeline is None:
159
- raise ValueError("Model pipeline not loaded")
160
-
161
- generator = torch.Generator(device=device).manual_seed(int(seed))
162
-
163
- # Check if prompt is long
164
- use_long_prompt = len(prompt.split()) > 60 or len(prompt) > 300
165
-
166
- try:
167
- # Try long prompt processing first if prompt is long
168
- if use_long_prompt and compel is not None:
169
- print("Using long prompt processing...")
170
- conditioning, pooled = process_long_prompt(prompt, negative_prompt)
171
-
172
- if conditioning is not None:
173
- result = pipeline(
174
- prompt_embeds=conditioning[0:1],
175
- pooled_prompt_embeds=pooled[0:1],
176
- negative_prompt_embeds=conditioning[1:2],
177
- negative_pooled_prompt_embeds=pooled[1:2],
178
- guidance_scale=guidance_scale,
179
- num_inference_steps=num_steps,
180
- width=width,
181
- height=height,
182
- generator=generator
183
- ).images[0]
184
- return result
185
 
186
- # Fall back to standard processing
187
- result = pipeline(
188
- prompt=prompt,
189
- negative_prompt=negative_prompt,
190
- guidance_scale=guidance_scale,
191
- num_inference_steps=num_steps,
192
- width=width,
193
- height=height,
194
- generator=generator
195
- ).images[0]
196
 
197
- return result
198
- except RuntimeError as e:
199
- print(f"Error during generation: {e}")
200
- # Return a blank image with error message
201
- error_img = Image.new('RGB', (width, height), color=(0, 0, 0))
202
- return error_img
203
-
204
- # ===== Gradio inference wrapper =====
205
- @spaces.GPU(duration=60)
206
- def generate_image(
207
- user_prompt: str,
208
- style_key: str,
209
- negative_prompt: str = "nsfw, (low quality, worst quality:1.2), very displeasing, 3d, watermark, signature, ugly, poorly drawn",
210
- seed: int = 42,
211
- randomize_seed: bool = True,
212
- width: int = 1024,
213
- height: int = 1024,
214
- guidance_scale: float = 7.0,
215
- num_inference_steps: int = 28,
216
- progress=None,
217
- ):
218
- try:
219
- if randomize_seed:
220
- seed = random.randint(0, MAX_SEED)
221
-
222
- # Apply style preset
223
- final_prompt = prepare_prompt(user_prompt, style_key)
224
- print(f"Final prompt: {final_prompt}")
225
-
226
- # Generate image
227
- image = run_pipeline(final_prompt, negative_prompt, seed, width, height, guidance_scale, num_inference_steps)
228
-
229
- # Save image
230
- save_generated_image(image, final_prompt)
231
-
232
- return image, seed
233
-
234
- except Exception as e:
235
- print(f"Error generating image: {e}")
236
- # Return a placeholder or error message
237
- error_image = Image.new('RGB', (width, height), color='red')
238
- return error_image, seed
239
-
240
- # ===== Custom CSS (Pastel Gradient Design) =====
241
- custom_css = """
242
- :root {
243
- --color-primary: #A8E6CF;
244
- --color-secondary: #FFD3A5;
245
- --color-accent: #FD9BB8;
246
- --color-purple: #C5A3F0;
247
- --color-blue: #A8D8F0;
248
- --color-warm-gray: #F8F9FA;
249
- --color-dark-gray: #495057;
250
- --background-primary: linear-gradient(135deg, #FFE5F1 0%, #E5F3FF 25%, #F0E5FF 50%, #E5FFE5 75%, #FFF5E5 100%);
251
- --background-accent: linear-gradient(135deg, #FFD3E8 0%, #D3E8FF 50%, #E8D3FF 100%);
252
- --text-primary: #2D3748;
253
- --text-secondary: #718096;
254
- --shadow-soft: 0 4px 20px rgba(168, 230, 207, 0.15);
255
- --shadow-medium: 0 8px 30px rgba(168, 230, 207, 0.25);
256
- --border-radius: 20px;
257
- }
258
-
259
- /* Global background */
260
- footer {visibility: hidden;}
261
- .gradio-container {
262
- background: var(--background-primary) !important;
263
- min-height: 100vh;
264
- font-family: 'Inter', sans-serif;
265
- }
266
-
267
- /* Title styles */
268
- .title {
269
- color: var(--text-primary) !important;
270
- font-size: 3rem !important;
271
- font-weight: 700 !important;
272
- text-align: center;
273
- margin: 2rem 0;
274
- background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-accent) 50%, var(--color-purple) 100%);
275
- -webkit-background-clip: text;
276
- -webkit-text-fill-color: transparent;
277
- background-clip: text;
278
- letter-spacing: -0.02em;
279
- }
280
-
281
- .subtitle {
282
- color: var(--text-secondary) !important;
283
- font-size: 1.2rem !important;
284
- text-align: center;
285
- margin-bottom: 2rem;
286
- font-weight: 400;
287
- }
288
-
289
- /* Simple card styles */
290
- .model-description {
291
- background: linear-gradient(135deg, rgba(255, 255, 255, 0.9) 0%, rgba(248, 187, 208, 0.1) 100%);
292
- border: 1px solid rgba(168, 230, 207, 0.3);
293
- border-radius: var(--border-radius);
294
- padding: 2rem;
295
- margin: 1.5rem 0;
296
- box-shadow: var(--shadow-soft);
297
- backdrop-filter: blur(10px);
298
- -webkit-backdrop-filter: blur(10px);
299
- }
300
-
301
- .model-description p {
302
- color: var(--text-primary) !important;
303
- font-size: 1rem;
304
- line-height: 1.6;
305
- margin: 0;
306
- }
307
-
308
- /* Button styles */
309
- button.primary {
310
- background: var(--background-accent) !important;
311
- color: var(--text-primary) !important;
312
- border: 1px solid var(--color-primary) !important;
313
- border-radius: 15px !important;
314
- box-shadow: var(--shadow-soft) !important;
315
- transition: all 0.3s ease !important;
316
- font-weight: 600 !important;
317
- font-size: 0.95rem !important;
318
- }
319
-
320
- button.primary:hover {
321
- background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-secondary) 100%) !important;
322
- transform: translateY(-2px) !important;
323
- box-shadow: var(--shadow-medium) !important;
324
- }
325
-
326
- /* Random button specific styles */
327
- .random-btn {
328
- background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-purple) 100%) !important;
329
- color: white !important;
330
- border: none !important;
331
- border-radius: 15px !important;
332
- padding: 12px 24px !important;
333
- font-weight: 600 !important;
334
- box-shadow: var(--shadow-soft) !important;
335
- transition: all 0.3s ease !important;
336
- }
337
-
338
- .random-btn:hover {
339
- transform: translateY(-2px) !important;
340
- box-shadow: var(--shadow-medium) !important;
341
- background: linear-gradient(135deg, var(--color-purple) 0%, var(--color-blue) 100%) !important;
342
- }
343
-
344
- /* Input container */
345
- .input-container {
346
- background: linear-gradient(135deg, rgba(255, 255, 255, 0.9) 0%, rgba(168, 230, 207, 0.1) 100%);
347
- border: 1px solid rgba(168, 230, 207, 0.3);
348
- border-radius: var(--border-radius);
349
- padding: 1.5rem;
350
- margin-bottom: 1.5rem;
351
- box-shadow: var(--shadow-soft);
352
- backdrop-filter: blur(10px);
353
- -webkit-backdrop-filter: blur(10px);
354
- }
355
-
356
- /* Advanced settings */
357
- .advanced-settings {
358
- background: linear-gradient(135deg, rgba(255, 255, 255, 0.8) 0%, rgba(197, 163, 240, 0.1) 100%);
359
- border: 1px solid rgba(168, 216, 240, 0.3);
360
- border-radius: var(--border-radius);
361
- padding: 1.5rem;
362
- margin-top: 1rem;
363
- box-shadow: var(--shadow-soft);
364
- backdrop-filter: blur(8px);
365
- -webkit-backdrop-filter: blur(8px);
366
- }
367
-
368
- /* Style preset section */
369
- .style-preset-section {
370
- background: linear-gradient(135deg, rgba(255, 211, 232, 0.3) 0%, rgba(211, 232, 255, 0.3) 100%);
371
- border: 1px solid rgba(168, 230, 207, 0.3);
372
- border-radius: var(--border-radius);
373
- padding: 1.2rem;
374
- margin-top: 1rem;
375
- box-shadow: var(--shadow-soft);
376
- }
377
-
378
- /* Prompt input styles */
379
- .large-prompt textarea {
380
- min-height: 120px !important;
381
- font-size: 15px !important;
382
- line-height: 1.5 !important;
383
- background: rgba(255, 255, 255, 0.9) !important;
384
- border: 2px solid rgba(168, 230, 207, 0.4) !important;
385
- border-radius: 15px !important;
386
- color: var(--text-primary) !important;
387
- transition: all 0.3s ease !important;
388
- padding: 1rem !important;
389
- }
390
-
391
- .large-prompt textarea:focus {
392
- border-color: var(--color-primary) !important;
393
- box-shadow: 0 0 0 3px rgba(168, 230, 207, 0.2) !important;
394
- outline: none !important;
395
- }
396
-
397
- .large-prompt textarea::placeholder {
398
- color: var(--text-secondary) !important;
399
- font-style: italic;
400
- }
401
-
402
- /* Generate button */
403
- .small-generate-btn {
404
- max-width: 140px !important;
405
- height: 48px !important;
406
- font-size: 15px !important;
407
- padding: 12px 24px !important;
408
- border-radius: 15px !important;
409
- font-weight: 600 !important;
410
- }
411
-
412
- /* Labels */
413
- label {
414
- color: var(--text-primary) !important;
415
- font-weight: 600 !important;
416
- font-size: 0.95rem !important;
417
- }
418
-
419
- /* Info text */
420
- .gr-info, .gr-textbox-info {
421
- color: var(--text-secondary) !important;
422
- font-size: 0.85rem !important;
423
- line-height: 1.4 !important;
424
- }
425
-
426
- /* Form elements */
427
- input[type="radio"], input[type="checkbox"] {
428
- accent-color: var(--color-primary) !important;
429
- }
430
-
431
- input[type="range"] {
432
- accent-color: var(--color-primary) !important;
433
- }
434
-
435
- /* Result image container */
436
- .image-container {
437
- border-radius: var(--border-radius) !important;
438
- overflow: hidden !important;
439
- box-shadow: var(--shadow-medium) !important;
440
- background: rgba(255, 255, 255, 0.9) !important;
441
- border: 1px solid rgba(168, 230, 207, 0.2) !important;
442
- }
443
-
444
- /* Slider containers */
445
- .gr-slider {
446
- margin: 0.5rem 0 !important;
447
- }
448
-
449
- /* Accordion styles */
450
- .gr-accordion {
451
- border: 1px solid rgba(168, 230, 207, 0.3) !important;
452
- border-radius: var(--border-radius) !important;
453
- background: rgba(255, 255, 255, 0.8) !important;
454
- }
455
-
456
- .gr-accordion-header {
457
- background: var(--background-accent) !important;
458
- color: var(--text-primary) !important;
459
- font-weight: 600 !important;
460
- border-radius: var(--border-radius) var(--border-radius) 0 0 !important;
461
- }
462
-
463
- /* Smooth animations */
464
- .model-description, .input-container, .style-preset-section {
465
- animation: fadeInUp 0.4s ease-out;
466
- }
467
-
468
- @keyframes fadeInUp {
469
- from {
470
- opacity: 0;
471
- transform: translateY(20px);
472
- }
473
- to {
474
- opacity: 1;
475
- transform: translateY(0);
476
- }
477
- }
478
-
479
- /* Improved text readability */
480
- * {
481
- -webkit-font-smoothing: antialiased;
482
- -moz-osx-font-smoothing: grayscale;
483
- }
484
-
485
- /* Dropdown and select styles */
486
- select, .gr-dropdown {
487
- background: rgba(255, 255, 255, 0.9) !important;
488
- border: 1px solid rgba(168, 230, 207, 0.3) !important;
489
- border-radius: 10px !important;
490
- color: var(--text-primary) !important;
491
- }
492
-
493
- /* Checkbox and radio button improvements */
494
- .gr-checkbox, .gr-radio {
495
- background: transparent !important;
496
- }
497
-
498
- /* Overall container margin adjustment */
499
- .gr-container {
500
- max-width: 1200px !important;
501
- margin: 0 auto !important;
502
- padding: 2rem 1rem !important;
503
- }
504
-
505
- /* Mobile responsive */
506
- @media (max-width: 768px) {
507
- .title {
508
- font-size: 2.2rem !important;
509
- }
510
-
511
- .model-description, .input-container, .advanced-settings {
512
- padding: 1rem !important;
513
- margin: 1rem 0 !important;
514
- }
515
-
516
- .large-prompt textarea {
517
- min-height: 100px !important;
518
- font-size: 14px !important;
519
- }
520
- }
521
- """
522
-
523
- # ===== Gradio UI =====
524
- def create_interface():
525
- with gr.Blocks(css=custom_css, analytics_enabled=False) as demo:
526
- with gr.Group(elem_classes="model-description"):
527
- gr.HTML("""
528
- <p>
529
- <strong>Adult AI Image Generator</strong><br>
530
- <small style="opacity: 0.8;">High-quality image generation powered by StableDiffusionXL. Supports long prompts and various artistic styles.</small><br><br>
531
- """)
532
-
533
- # ===== Main input =====
534
- with gr.Column():
535
- with gr.Row(elem_classes="input-container"):
536
- with gr.Column(scale=3):
537
- user_prompt = gr.Text(
538
- label="Prompt",
539
- max_lines=5,
540
- value="",
541
- elem_classes="large-prompt",
542
- placeholder="Enter your image description here..."
543
- )
544
- with gr.Column(scale=1):
545
- with gr.Row():
546
- run_button = gr.Button(
547
- "Generate",
548
- variant="primary",
549
- elem_classes="small-generate-btn"
550
- )
551
- with gr.Row():
552
- random_button = gr.Button(
553
- "🎲 Random",
554
- elem_classes="random-btn"
555
- )
556
-
557
- # Style preset section
558
- with gr.Group(elem_classes="style-preset-section"):
559
- style_select = gr.Radio(
560
- label="🎨 Style Preset",
561
- choices=list(STYLE_PRESETS.keys()),
562
- value="None",
563
- interactive=True
564
- )
565
-
566
- result_image = gr.Image(label="Generated Image")
567
- seed_output = gr.Number(label="Seed")
568
-
569
- # ===== Advanced settings =====
570
- with gr.Accordion("Advanced Settings", open=False, elem_classes="advanced-settings"):
571
- negative_prompt = gr.Text(
572
- label="Negative prompt",
573
- max_lines=1,
574
- placeholder="Enter a negative prompt",
575
- value="nsfw, (low quality, worst quality:1.2), very displeasing, 3d, watermark, signature, ugly, poorly drawn"
576
- )
577
-
578
- seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=42)
579
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
580
- with gr.Row():
581
- width = gr.Slider(label="Width", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024)
582
- height = gr.Slider(label="Height", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024)
583
- with gr.Row():
584
- guidance_scale = gr.Slider(label="Guidance scale", minimum=0.0, maximum=20.0, step=0.1, value=7.0)
585
- num_inference_steps = gr.Slider(label="Inference steps", minimum=1, maximum=50, step=1, value=28)
586
-
587
- # ===== Events =====
588
- run_button.click(
589
- fn=generate_image,
590
- inputs=[
591
- user_prompt,
592
- style_select,
593
- negative_prompt,
594
- seed,
595
- randomize_seed,
596
- width,
597
- height,
598
- guidance_scale,
599
- num_inference_steps,
600
- ],
601
- outputs=[result_image, seed_output],
602
- )
603
 
604
- # Random button event
605
- random_button.click(
606
- fn=get_random_prompt,
607
- outputs=user_prompt
608
- )
609
-
610
- return demo
 
 
 
611
 
612
- # ===== Application execution =====
613
  if __name__ == "__main__":
614
- demo = create_interface()
615
- demo.queue()
616
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
+ import sys
3
+ import streamlit as st
4
+ from tempfile import NamedTemporaryFile
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
+ def main():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  try:
8
+ # Get the code from secrets
9
+ code = os.environ.get("MAIN_CODE")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ if not code:
12
+ st.error("⚠️ The application code wasn't found in secrets. Please add the MAIN_CODE secret.")
13
+ return
 
 
 
 
 
 
 
14
 
15
+ # Create a temporary Python file
16
+ with NamedTemporaryFile(suffix='.py', delete=False, mode='w') as tmp:
17
+ tmp.write(code)
18
+ tmp_path = tmp.name
19
+
20
+ # Execute the code
21
+ exec(compile(code, tmp_path, 'exec'), globals())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
+ # Clean up the temporary file
24
+ try:
25
+ os.unlink(tmp_path)
26
+ except:
27
+ pass
28
+
29
+ except Exception as e:
30
+ st.error(f"⚠️ Error loading or executing the application: {str(e)}")
31
+ import traceback
32
+ st.code(traceback.format_exc())
33
 
 
34
  if __name__ == "__main__":
35
+ main()