jpjp9292 commited on
Commit
55bedbd
ยท
verified ยท
1 Parent(s): ebe565c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +238 -0
app.py ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import gradio as gr
3
+ import requests
4
+ import time
5
+ import json
6
+ import base64
7
+ import os
8
+ from PIL import Image
9
+ from io import BytesIO
10
+
11
+ class Prodia:
12
+ def __init__(self, api_key, base=None):
13
+ self.base = base or "https://api.prodia.com/v1"
14
+ self.headers = {
15
+ "X-Prodia-Key": api_key
16
+ }
17
+
18
+ def generate(self, params):
19
+ response = self._post(f"{self.base}/sdxl/generate", params)
20
+ return response.json()
21
+
22
+ def get_job(self, job_id):
23
+ response = self._get(f"{self.base}/job/{job_id}")
24
+ return response.json()
25
+
26
+ def wait(self, job):
27
+ job_result = job
28
+
29
+ while job_result['status'] not in ['succeeded', 'failed']:
30
+ time.sleep(0.25)
31
+ job_result = self.get_job(job['job'])
32
+
33
+ return job_result
34
+
35
+ def list_models(self):
36
+ response = self._get(f"{self.base}/sdxl/models")
37
+ return response.json()
38
+
39
+ def list_samplers(self):
40
+ response = self._get(f"{self.base}/sdxl/samplers")
41
+ return response.json()
42
+
43
+ def _post(self, url, params):
44
+ headers = {
45
+ **self.headers,
46
+ "Content-Type": "application/json"
47
+ }
48
+ response = requests.post(url, headers=headers, data=json.dumps(params))
49
+
50
+ if response.status_code != 200:
51
+ raise Exception(f"Bad Prodia Response: {response.status_code}")
52
+
53
+ return response
54
+
55
+ def _get(self, url):
56
+ response = requests.get(url, headers=self.headers)
57
+
58
+ if response.status_code != 200:
59
+ raise Exception(f"Bad Prodia Response: {response.status_code}")
60
+
61
+ return response
62
+
63
+
64
+ def image_to_base64(image_path):
65
+ # Open the image with PIL
66
+ with Image.open(image_path) as image:
67
+ # Convert the image to bytes
68
+ buffered = BytesIO()
69
+ image.save(buffered, format="PNG") # You can change format to PNG if needed
70
+
71
+ # Encode the bytes to base64
72
+ img_str = base64.b64encode(buffered.getvalue())
73
+
74
+ return img_str.decode('utf-8') # Convert bytes to string
75
+
76
+ # Prodia ํด๋ผ์ด์–ธํŠธ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
77
+ prodia_client = Prodia(api_key=os.getenv("PRODIA_API_KEY"))
78
+
79
+ # ๋ชจ๋ธ ๋ชฉ๋ก ์ถ”๊ฐ€
80
+ additional_models = [
81
+ "arcane-diffusion-v3.ckpt",
82
+ "Cyberpunk-Anime-Diffusion.ckpt",
83
+ "mdjrny-v4.ckpt",
84
+ "moDi-v1-pruned.ckpt",
85
+ "PaperCut_v1.ckpt",
86
+ "samdoesarts_style.ckpt",
87
+ "wd-v1-3-float32.ckpt",
88
+ "sd-v1-4.ckpt",
89
+ "v1-5-pruned-emaonly.ckpt",
90
+ "sd-v1-5-inpainting.ckpt",
91
+ "Anything-V3.0-pruned.ckpt",
92
+ "Anything-V3.0.vae.pt",
93
+ "768-v-ema.ckpt",
94
+ "akakura-sn.ckpt",
95
+ "v2-1_768-ema-pruned.ckpt"
96
+ ]
97
+
98
+ # ๊ธฐ์กด ๋ชจ๋ธ ๋ชฉ๋ก์— ์ถ”๊ฐ€
99
+ prodia_models = prodia_client.list_models()
100
+ model_choices = prodia_models + additional_models
101
+
102
+ def flip_text(prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height, seed):
103
+ result = prodia_client.generate({
104
+ "prompt": prompt,
105
+ "negative_prompt": negative_prompt,
106
+ "model": model,
107
+ "steps": steps,
108
+ "sampler": sampler,
109
+ "cfg_scale": cfg_scale,
110
+ "width": width,
111
+ "height": height,
112
+ "seed": seed
113
+ })
114
+
115
+ job = prodia_client.wait(result)
116
+
117
+ return job["imageUrl"]
118
+
119
+ css = """
120
+ #generate {
121
+ height: 100%;
122
+ }
123
+ """
124
+
125
+ with gr.Blocks(css=css) as demo:
126
+
127
+ with gr.Row():
128
+ with gr.Column(scale=6):
129
+ model = gr.Dropdown(
130
+ interactive=True,
131
+ value="sd_xl_base_1.0.safetensors [be9edd61]",
132
+ show_label=True,
133
+ label="Stable Diffusion ์ฒดํฌํฌ์ธํŠธ (๋ชจ๋ธ ์„ ํƒ)",
134
+ choices=model_choices
135
+ )
136
+
137
+ with gr.Column(scale=1):
138
+ gr.Markdown(
139
+ elem_id="powered-by-prodia",
140
+ value="AUTOMATIC1111 Stable Diffusion Web UI for SDXL V1.0.<br>Powered by [Prodia](https://prodia.com)."
141
+ )
142
+
143
+ with gr.Tab("txt2img"):
144
+ with gr.Row():
145
+ with gr.Column(scale=6, min_width=600):
146
+ prompt = gr.Textbox(
147
+ value="space warrior, beautiful, female, ultrarealistic, soft lighting, 8k",
148
+ placeholder="ํ”„๋กฌํ”„ํŠธ (์ƒ์„ฑํ•  ์ด๋ฏธ์ง€์˜ ์„ค๋ช…)",
149
+ show_label=False,
150
+ lines=3
151
+ )
152
+ negative_prompt = gr.Textbox(
153
+ placeholder="๋„ค๊ฑฐํ‹ฐ๋ธŒ ํ”„๋กฌํ”„ํŠธ (์ œ์™ธํ•  ์š”์†Œ๋“ค)",
154
+ show_label=False,
155
+ lines=3,
156
+ value="3d, cartoon, anime, (deformed eyes, nose, ears, nose), bad anatomy, ugly"
157
+ )
158
+ with gr.Column():
159
+ text_button = gr.Button("์ƒ์„ฑ", variant='primary', elem_id="generate")
160
+
161
+ with gr.Row():
162
+ with gr.Column(scale=3):
163
+ with gr.Tab("Generation (์ƒ์„ฑ ์„ค์ •)"):
164
+ with gr.Row():
165
+ with gr.Column(scale=1):
166
+ sampler = gr.Dropdown(
167
+ value="DPM++ 2M Karras",
168
+ show_label=True,
169
+ label="์ƒ˜ํ”Œ๋ง ๋ฐฉ๋ฒ•",
170
+ choices=prodia_client.list_samplers()
171
+ )
172
+
173
+ with gr.Column(scale=1):
174
+ steps = gr.Slider(
175
+ label="์ƒ˜ํ”Œ๋ง ๋‹จ๊ณ„",
176
+ minimum=1,
177
+ maximum=25,
178
+ value=20,
179
+ step=1
180
+ )
181
+
182
+ with gr.Row():
183
+ with gr.Column(scale=1):
184
+ width = gr.Slider(
185
+ label="๋„ˆ๋น„ (ํ”ฝ์…€)",
186
+ minimum=512,
187
+ maximum=1536,
188
+ value=1024,
189
+ step=8
190
+ )
191
+ height = gr.Slider(
192
+ label="๋†’์ด (ํ”ฝ์…€)",
193
+ minimum=512,
194
+ maximum=1536,
195
+ value=1024,
196
+ step=8
197
+ )
198
+ gr.Markdown(
199
+ elem_id="resolution",
200
+ value="*์ตœ๋Œ€ ํ•ด์ƒ๋„: 1MP (1048576 ํ”ฝ์…€)*"
201
+ )
202
+
203
+ with gr.Column(scale=1):
204
+ batch_size = gr.Slider(
205
+ label="๋ฐฐ์น˜ ํฌ๊ธฐ",
206
+ maximum=1,
207
+ value=1
208
+ )
209
+ batch_count = gr.Slider(
210
+ label="๋ฐฐ์น˜ ์ˆ˜",
211
+ maximum=1,
212
+ value=1
213
+ )
214
+
215
+ cfg_scale = gr.Slider(
216
+ label="CFG ์Šค์ผ€์ผ (์ œ์–ด ๊ฐ•๋„)",
217
+ minimum=1,
218
+ maximum=20,
219
+ value=7,
220
+ step=1
221
+ )
222
+ seed = gr.Number(
223
+ label="์‹œ๋“œ (๊ณ ์œ  ๋ฒˆํ˜ธ)",
224
+ value=-1
225
+ )
226
+
227
+ with gr.Column(scale=2):
228
+ image_output = gr.Image(
229
+ value="https://cdn-uploads.huggingface.co/production/uploads/noauth/XWJyh9DhMGXrzyRJk7SfP.png"
230
+ )
231
+
232
+ text_button.click(
233
+ flip_text,
234
+ inputs=[prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height, seed],
235
+ outputs=image_output
236
+ )
237
+
238
+ demo.queue(concurrency_count=24, max_size=32, api_open=False).launch(max_threads=128)