DigiP-AI commited on
Commit
fbb6477
·
verified ·
1 Parent(s): e7baf57

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +251 -0
app.py ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import io
3
+ import random
4
+ import time
5
+ import json
6
+ import base64
7
+ import requests
8
+ import os
9
+ from mistralai import Mistral
10
+ from PIL import Image
11
+ from io import BytesIO
12
+ from deep_translator import GoogleTranslator
13
+ from datetime import datetime
14
+ from theme import theme
15
+ from fastapi import FastAPI
16
+
17
+ app = FastAPI()
18
+
19
+ API_URL = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-3.5-large"
20
+ API_TOKEN = os.getenv("HF_READ_TOKEN")
21
+ headers = {"Authorization": f"Bearer {API_TOKEN}"}
22
+ timeout = 100
23
+
24
+ api_key = os.getenv("MISTRAL_API_KEY")
25
+ Mistralclient = Mistral(api_key=api_key)
26
+
27
+ def flip_image(x):
28
+ return np.fliplr(x)
29
+
30
+ def clear():
31
+ return None
32
+
33
+
34
+ # Function to query the API and return the generated image
35
+ def query(prompt, is_negative=False, steps=35, cfg_scale=7, sampler="DPM++ 2M Karras", seed=-1, strength=0.7, width=896, height=1152):
36
+ if prompt == "" or prompt is None:
37
+ return None
38
+
39
+ key = random.randint(0, 999)
40
+
41
+ API_TOKEN = random.choice([os.getenv("HF_READ_TOKEN")])
42
+ headers = {"Authorization": f"Bearer {API_TOKEN}"}
43
+
44
+ # Translate the prompt from Russian to English if necessary
45
+ prompt = GoogleTranslator(source='ru', target='en').translate(prompt)
46
+ print(f'\033[1mGeneration {key} translation:\033[0m {prompt}')
47
+
48
+ # Add some extra flair to the prompt
49
+ prompt = f"{prompt} | ultra detail, ultra elaboration, ultra quality, perfect."
50
+ print(f'\033[1mGeneration {key}:\033[0m {prompt}')
51
+
52
+ # Prepare the payload for the API call, including width and height
53
+ payload = {
54
+ "inputs": prompt,
55
+ "is_negative": is_negative,
56
+ "steps": steps,
57
+ "cfg_scale": cfg_scale,
58
+ "seed": seed if seed != -1 else random.randint(1, 1000000000),
59
+ "strength": strength,
60
+ "parameters": {
61
+ "width": width, # Pass the width to the API
62
+ "height": height # Pass the height to the API
63
+ }
64
+ }
65
+
66
+ # Send the request to the API and handle the response
67
+ response = requests.post(API_URL, headers=headers, json=payload, timeout=timeout)
68
+ if response.status_code != 200:
69
+ print(f"Error: Failed to get image. Response status: {response.status_code}")
70
+ print(f"Response content: {response.text}")
71
+ if response.status_code == 503:
72
+ raise gr.Error(f"{response.status_code} : The model is being loaded")
73
+ raise gr.Error(f"{response.status_code}")
74
+
75
+ try:
76
+ # Convert the response content into an image
77
+ image_bytes = response.content
78
+ image = Image.open(io.BytesIO(image_bytes))
79
+ print(f'\033[1mGeneration {key} completed!\033[0m ({prompt})')
80
+ return image
81
+ except Exception as e:
82
+ print(f"Error when trying to open the image: {e}")
83
+ return None
84
+
85
+ examples = [
86
+ "a beautiful woman with blonde hair and blue eyes",
87
+ "a beautiful woman with brown hair and grey eyes",
88
+ "a beautiful woman with black hair and brown eyes",
89
+ ]
90
+
91
+ def encode_image(image_path):
92
+ """Encode the image to base64."""
93
+ try:
94
+ # Open the image file
95
+ image = Image.open(image_path).convert("RGB")
96
+
97
+ # Resize the image to a height of 512 while maintaining the aspect ratio
98
+ base_height = 512
99
+ h_percent = (base_height / float(image.size[1]))
100
+ w_size = int((float(image.size[0]) * float(h_percent)))
101
+ image = image.resize((w_size, base_height), Image.LANCZOS)
102
+
103
+ # Convert the image to a byte stream
104
+ buffered = BytesIO()
105
+ image.save(buffered, format="JPEG")
106
+ img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
107
+
108
+ return img_str
109
+ except FileNotFoundError:
110
+ print(f"Error: The file {image_path} was not found.")
111
+ return None
112
+ except Exception as e: # Add generic exception handling
113
+ print(f"Error: {e}")
114
+ return None
115
+
116
+ def feifeichat(image):
117
+ try:
118
+ model = "pixtral-large-2411"
119
+ # Define the messages for the chat
120
+ base64_image = encode_image(image)
121
+ messages = [{
122
+ "role":
123
+ "user",
124
+ "content": [
125
+ {
126
+ "type": "text",
127
+ "text": "Please provide a detailed description of this photo"
128
+ },
129
+ {
130
+ "type": "image_url",
131
+ "image_url": f"data:image/jpeg;base64,{base64_image}"
132
+ },
133
+ ],
134
+ "stream": False,
135
+ }]
136
+
137
+ partial_message = ""
138
+ for chunk in Mistralclient.chat.stream(model=model, messages=messages):
139
+ if chunk.data.choices[0].delta.content is not None:
140
+ partial_message = partial_message + chunk.data.choices[
141
+ 0].delta.content
142
+ yield partial_message
143
+ except Exception as e: # 添加通用异常处理
144
+ print(f"Error: {e}")
145
+ return "Please upload a photo"
146
+
147
+ # CSS to style the app
148
+ css = """
149
+ .gradio-container {background-color: MediumAquaMarine}
150
+ footer{display:none !important}
151
+ #app-container {
152
+ max-width: 930px;
153
+ margin-left: auto;
154
+ margin-right: auto;
155
+ }
156
+ """
157
+
158
+ # Build the Gradio UI with Blocks
159
+ with gr.Blocks(theme=theme, css=css) as app:
160
+ # Add a title to the app
161
+ gr.HTML("<center><h1>🎨 Stable Diffusion 3.5 Large + 🇬🇧</h1></center>")
162
+ with gr.Tab(label="Image To Flux Prompt"):
163
+ with gr.Row():
164
+ with gr.Column(scale=4):
165
+ input_img = gr.Image(label="Input Picture",height=320, type="filepath")
166
+
167
+ with gr.Column(scale=3):
168
+ output_text = gr.Textbox(label="Flux Prompt", lines=2, scale=6, show_copy_button = True)
169
+ submit_btn = gr.Button(value="Generate Pompt", scale=4, variant='primary')
170
+ clear_prompt =gr.Button("Clear 🗑️",variant="primary", elem_id="clear_button")
171
+ clear_prompt.click(lambda: (None, None), None, [input_img, output_text], queue=False, show_api=False)
172
+
173
+ submit_btn.click(feifeichat, [input_img], [output_text])
174
+
175
+ with gr.Tab(label="Generate Image"):
176
+ with gr.Row():
177
+ with gr.Column(scale=4):
178
+ with gr.Row():
179
+ img_output = gr.Image(type="pil", label="Image Output", show_share_button=False, format="png", elem_id="gallery")
180
+ with gr.Row():
181
+ text_prompt = gr.Textbox(label="Image Prompt ✍️", placeholder="Enter prompt...", lines=2, scale=6, show_copy_button = True, elem_id="prompt-text-input")
182
+ text_button = gr.Button("Generate Image",scale=1, variant='primary', elem_id="gen-button")
183
+ clear_prompt =gr.Button("Clear 🗑️",variant="primary", elem_id="clear_button")
184
+ clear_prompt.click(lambda: (None, None), None, [text_prompt, img_output], queue=False, show_api=False)
185
+ with gr.Accordion("Advanced Options", open=True):
186
+ with gr.Column(scale=1):
187
+ negative_prompt = gr.Textbox(label="Negative Prompt", placeholder="What should not be in the image", value="( (((hands:-1.25))), physical-defects:2, unhealthy-deformed-joints:2, unhealthy-hands:2, out of frame, (((bad face))), (bad-image-v2-39000:1.3), (((out of frame))), deformed body features, (((poor facial details))), (poorly drawn face:1.3), jpeg artifacts, (missing arms:1.1), (missing legs:1.1), (extra arms:1.2), (extra legs:1.2), [asymmetrical features], warped expressions, distorted eyes ", lines=6, elem_id="negative-prompt-text-input")
188
+ width = gr.Slider(
189
+ label="Width",
190
+ minimum=512,
191
+ maximum=1280,
192
+ step=8,
193
+ value=896,
194
+ )
195
+ height = gr.Slider(
196
+ label="Height",
197
+ minimum=512,
198
+ maximum=1280,
199
+ step=8,
200
+ value=1152,
201
+ )
202
+ method = gr.Dropdown(label="Sampling method", value="DPM++ 2M Karras", choices=["DPM++ 2M Karras", "DPM++ 2S a Karras", "DPM2 a Karras", "DPM2 Karras", "DPM++ SDE Karras", "DEIS", "LMS", "DPM Adaptive", "DPM++ 2M", "DPM2 Ancestral", "DPM++ S", "DPM++ SDE", "DDPM", "DPM Fast", "dpmpp_2s_ancestral", "Euler", "Euler CFG PP", "Euler a", "Euler Ancestral", "Euler+beta", "Heun", "Heun PP2", "DDIM", "LMS Karras", "PLMS", "UniPC", "UniPC BH2"])
203
+ steps = gr.Slider(
204
+ label="Sampling steps",
205
+ minimum=1,
206
+ maximum=100,
207
+ step=1,
208
+ value=24,
209
+ )
210
+ cfg = gr.Slider(
211
+ label="CFG Scale",
212
+ minimum=3.5,
213
+ maximum=7,
214
+ step=0.1,
215
+ value=3.5,
216
+ )
217
+ strength = gr.Slider(label="Strength", value=90, minimum=0, maximum=100, step=10)
218
+ seed = gr.Slider(label="Seed", value=-1, minimum=-1, maximum=1000000000, step=1)
219
+
220
+ gr.Examples(
221
+ examples = examples,
222
+ inputs = [text_prompt],
223
+ )
224
+ # Bind the button to the query function with the added width and height inputs
225
+ text_button.click(query, inputs=[text_prompt, negative_prompt, steps, cfg, method, seed, strength, width, height], outputs=img_output)
226
+
227
+ with gr.Tab("ℹ️ Tips"):
228
+ with gr.Row():
229
+ with gr.Column():
230
+ gr.Markdown(
231
+ """
232
+ <div style="max-width: 650px; margin: 2rem auto; padding: 1rem; border-radius: 10px; background-color: #f0f0f0;">
233
+ <h2 style="float: left; font-size: 1.5rem; margin-bottom: 1rem;">How to Use</h2>
234
+ <ol style="padding-left: 1.5rem;">
235
+ <li>Add an image to generate a prompt, this is optional.</li>
236
+ <li>If using an image to prompt, copy the prompt and paste into the prompt on tab 2</li>
237
+ <li>Enter a detailed description of the image you want to create.</li>
238
+ <li>Adjust advanced settings if desired (tap to expand).</li>
239
+ <li>Tap "Generate Image" and wait for your creation!</li>
240
+ </ol>
241
+ <p style="margin-top: 1rem; font-style: italic;">Tip: Be specific in your description for best results!</p>
242
+ <p style="margin-top: 1rem; font-style: italic;">*Note: Some LoRA models will not work every time (not sure why), refresh the page and try again</p>
243
+ <p style="margin-top: 1rem; font-style: italic;">*I'm still playing around to try to sort the issue, feel free to let me know if you find a fix</p>
244
+ </div>
245
+ """
246
+ )
247
+
248
+ app.queue(default_concurrency_limit=200, max_size=200) # <-- Sets up a queue with default parameters
249
+ if __name__ == "__main__":
250
+ app.launch(show_api=False, share=False)
251
+