Spaces:
Build error
Build error
AppleBotzz
commited on
Update app.py
Browse files
app.py
CHANGED
@@ -5,6 +5,10 @@ import openai
|
|
5 |
import json
|
6 |
import uuid
|
7 |
import os
|
|
|
|
|
|
|
|
|
8 |
|
9 |
default_urls = ["https://api.anthropic.com", "https://api.openai.com/v1"]
|
10 |
|
@@ -172,6 +176,60 @@ def generate_second_response(endpoint, api_key, model, generated_output, image_m
|
|
172 |
|
173 |
return response_text
|
174 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
# Set up the Gradio interface
|
176 |
with gr.Blocks() as demo:
|
177 |
gr.Markdown("# SillyTavern Character Generator")
|
@@ -179,39 +237,65 @@ with gr.Blocks() as demo:
|
|
179 |
#Text explaining that you can use the API key from the Anthropic API or the OpenAI API
|
180 |
gr.Markdown("You can use the API key from the Anthropic API or the OpenAI API. The API key should start with 'sk-ant-' for Anthropic or 'sk-' for OpenAI.")
|
181 |
gr.Markdown("Please Note: If you use a proxy it must support the OpenAI or Anthropic standard api calls! khanon does, Openrouter based ones usually do not.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
model_dropdown = gr.Dropdown(choices=[], label="Select a model")
|
188 |
-
user_prompt = gr.Textbox(label="User Prompt", value="Make me a card for a panther made of translucent pastel colored goo. Its color never changes once it exists but each 'copy' has a different color. The creature comes out of a small jar, seemingly defying physics with its size. It is the size of a real panther, and as strong as one too. By default its female but is able to change gender. It can even split into multiple copies of itself if needed with no change in its own size or mass. Its outside is normally lightly squishy but solid, but on command it can become viscous like non-newtonian fluids. Be descriptive when describing this character, and make sure to describe all of its features in char_persona just like you do in description. Make sure to describe commonly used features in detail (visual, smell, taste, touch, etc).")
|
189 |
-
generate_button = gr.Button("Generate JSON")
|
190 |
|
191 |
-
with gr.
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
|
196 |
-
|
197 |
-
|
198 |
-
image_model = gr.Dropdown(choices=image_prompter, label="Image Model to prompt for", value="SDXL")
|
199 |
-
generate_button_2 = gr.Button("Generate SDXL Prompt")
|
200 |
|
201 |
-
|
202 |
-
|
|
|
|
|
|
|
|
|
|
|
203 |
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
|
212 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
|
214 |
-
|
215 |
-
generate_button_2.click(generate_second_response, inputs=[endpoint, api_key, model_dropdown, generated_output, image_model], outputs=generated_output_2)
|
216 |
|
217 |
demo.launch()
|
|
|
5 |
import json
|
6 |
import uuid
|
7 |
import os
|
8 |
+
import base64
|
9 |
+
from PIL import Image
|
10 |
+
from PIL.PngImagePlugin import PngInfo
|
11 |
+
from io import BytesIO
|
12 |
|
13 |
default_urls = ["https://api.anthropic.com", "https://api.openai.com/v1"]
|
14 |
|
|
|
176 |
|
177 |
return response_text
|
178 |
|
179 |
+
def inject_json_to_png(image, json_data):
|
180 |
+
if isinstance(json_data, str):
|
181 |
+
json_data = json.loads(json_data)
|
182 |
+
|
183 |
+
img = Image.open(image)
|
184 |
+
|
185 |
+
# Calculate the aspect ratio of the original image
|
186 |
+
width, height = img.size
|
187 |
+
aspect_ratio = width / height
|
188 |
+
|
189 |
+
# Calculate the cropping dimensions based on the aspect ratio
|
190 |
+
if aspect_ratio > 400 / 600:
|
191 |
+
# Image is wider than 400x600, crop the sides
|
192 |
+
new_width = int(height * 400 / 600)
|
193 |
+
left = (width - new_width) // 2
|
194 |
+
right = left + new_width
|
195 |
+
top = 0
|
196 |
+
bottom = height
|
197 |
+
else:
|
198 |
+
# Image is taller than 400x600, crop the top and bottom
|
199 |
+
new_height = int(width * 600 / 400)
|
200 |
+
left = 0
|
201 |
+
right = width
|
202 |
+
top = (height - new_height) // 2
|
203 |
+
bottom = top + new_height
|
204 |
+
|
205 |
+
# Perform cropping
|
206 |
+
img = img.crop((left, top, right, bottom))
|
207 |
+
|
208 |
+
# Resize the cropped image to 400x600 pixels
|
209 |
+
img = img.resize((400, 600), Image.LANCZOS)
|
210 |
+
|
211 |
+
# Convert the JSON data to bytes
|
212 |
+
json_bytes = json.dumps(json_data).encode('utf-8')
|
213 |
+
|
214 |
+
# Create a new PNG image with the JSON data injected into the tEXT chunk
|
215 |
+
output = BytesIO()
|
216 |
+
img.save(output, format='PNG')
|
217 |
+
output.seek(0)
|
218 |
+
|
219 |
+
# Add the tEXT chunk with the tag 'chara'
|
220 |
+
metadata = PngInfo()
|
221 |
+
metadata.add_text("chara", base64.b64encode(json_bytes))
|
222 |
+
|
223 |
+
# Save the modified PNG image to a BytesIO object
|
224 |
+
output = BytesIO()
|
225 |
+
create_unique_id = str(uuid.uuid4())
|
226 |
+
if json_data['name']:
|
227 |
+
filename = f"{json_data['name']}_{create_unique_id}.png"
|
228 |
+
img_folder = __file__.replace("app.py", f"outputs/")
|
229 |
+
img.save(f"{img_folder}/{filename}", format='PNG', pnginfo=metadata)
|
230 |
+
|
231 |
+
return f"{img_folder}/{filename}"
|
232 |
+
|
233 |
# Set up the Gradio interface
|
234 |
with gr.Blocks() as demo:
|
235 |
gr.Markdown("# SillyTavern Character Generator")
|
|
|
237 |
#Text explaining that you can use the API key from the Anthropic API or the OpenAI API
|
238 |
gr.Markdown("You can use the API key from the Anthropic API or the OpenAI API. The API key should start with 'sk-ant-' for Anthropic or 'sk-' for OpenAI.")
|
239 |
gr.Markdown("Please Note: If you use a proxy it must support the OpenAI or Anthropic standard api calls! khanon does, Openrouter based ones usually do not.")
|
240 |
+
with gr.Tab("JSON Generate"):
|
241 |
+
with gr.Row():
|
242 |
+
with gr.Column():
|
243 |
+
endpoint = gr.Textbox(label="Endpoint", value="https://api.anthropic.com")
|
244 |
+
api_key = gr.Textbox(label="API Key", type="password", placeholder="sk-ant-api03-... or sk-...")
|
245 |
+
model_dropdown = gr.Dropdown(choices=[], label="Select a model")
|
246 |
+
user_prompt = gr.Textbox(label="User Prompt", value="Make me a card for a panther made of translucent pastel colored goo. Its color never changes once it exists but each 'copy' has a different color. The creature comes out of a small jar, seemingly defying physics with its size. It is the size of a real panther, and as strong as one too. By default its female but is able to change gender. It can even split into multiple copies of itself if needed with no change in its own size or mass. Its outside is normally lightly squishy but solid, but on command it can become viscous like non-newtonian fluids. Be descriptive when describing this character, and make sure to describe all of its features in char_persona just like you do in description. Make sure to describe commonly used features in detail (visual, smell, taste, touch, etc).")
|
247 |
+
generate_button = gr.Button("Generate JSON")
|
248 |
|
249 |
+
with gr.Column():
|
250 |
+
generated_output = gr.Textbox(label="Generated Output")
|
251 |
+
json_output = gr.Textbox(label="JSON Output")
|
252 |
+
json_download = gr.File(label="Download JSON")
|
|
|
|
|
|
|
253 |
|
254 |
+
with gr.Row():
|
255 |
+
with gr.Column():
|
256 |
+
image_model = gr.Dropdown(choices=image_prompter, label="Image Model to prompt for", value="SDXL")
|
257 |
+
generate_button_2 = gr.Button("Generate SDXL Prompt")
|
258 |
|
259 |
+
with gr.Column():
|
260 |
+
generated_output_2 = gr.Textbox(label="Generated SDXL Prompt")
|
|
|
|
|
261 |
|
262 |
+
def update_models(api_key):
|
263 |
+
if api_key.startswith("sk-ant-"):
|
264 |
+
return gr.Dropdown(choices=claude_models), gr.Textbox(label="Endpoint", value="https://api.anthropic.com")
|
265 |
+
elif api_key.startswith("sk-"):
|
266 |
+
return gr.Dropdown(choices=openai_models), gr.Textbox(label="Endpoint", value="https://api.openai.com/v1")
|
267 |
+
else:
|
268 |
+
return gr.Dropdown(choices=both_models), gr.Textbox(label="Endpoint", value="https://api.anthropic.com")
|
269 |
|
270 |
+
api_key.change(update_models, inputs=api_key, outputs=[model_dropdown, endpoint])
|
271 |
+
|
272 |
+
generate_button.click(generate_response, inputs=[endpoint, api_key, model_dropdown, user_prompt], outputs=[generated_output, json_output, json_download])
|
273 |
+
generate_button_2.click(generate_second_response, inputs=[endpoint, api_key, model_dropdown, generated_output, image_model], outputs=generated_output_2)
|
274 |
+
with gr.Tab("PNG Inject"):
|
275 |
+
gr.Markdown("# PNG Inject")
|
276 |
+
gr.Markdown("Upload a PNG image and inject JSON content into the PNG. PNG gets resized to 400x600 Center Crop.")
|
277 |
+
|
278 |
+
with gr.Row():
|
279 |
+
with gr.Column():
|
280 |
+
image_input = gr.Image(type="filepath", label="Upload PNG Image")
|
281 |
+
json_input = gr.Textbox(label="JSON Data")
|
282 |
+
json_file_input = gr.File(label="Or Upload JSON File", file_types=[".json"])
|
283 |
+
inject_button = gr.Button("Inject JSON and Download PNG")
|
284 |
+
|
285 |
+
with gr.Column():
|
286 |
+
injected_image_output = gr.File(label="Download Injected PNG")
|
287 |
|
288 |
+
def inject_json(image, json_data, json_file):
|
289 |
+
if json_file:
|
290 |
+
jsonc = open(json_file,)
|
291 |
+
json_data = json.load(jsonc)
|
292 |
+
if image is None:
|
293 |
+
return None
|
294 |
+
if json_data is None:
|
295 |
+
return None
|
296 |
+
injected_image = inject_json_to_png(image, json_data)
|
297 |
+
return injected_image
|
298 |
|
299 |
+
inject_button.click(inject_json, inputs=[image_input, json_input, json_file_input], outputs=injected_image_output)
|
|
|
300 |
|
301 |
demo.launch()
|