ivanoctaviogaitansantos commited on
Commit
9fac1a2
·
verified ·
1 Parent(s): b4c05f8

Actualizar app.py

Browse files
Files changed (1) hide show
  1. app.py +163 -26
app.py CHANGED
@@ -2,33 +2,167 @@ import gradio as gr
2
  import requests
3
  import json
4
  import os
5
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  API_KEY = os.getenv("SAMBANOVA_API_KEY")
7
  API_URL = "https://api.sambanova.ai/v1/chat/completions"
8
-
9
  headers = {
10
  "Authorization": f"Bearer {API_KEY}",
11
  "Content-Type": "application/json",
12
  }
13
 
14
- def query_sambanova_with_image(user_message, image_base64, chat_history):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  messages = [{"role": "system", "content": "Eres un asistente útil"}]
16
- for user_msg, ai_msg in chat_history:
17
  messages.append({"role": "user", "content": [{"type": "text", "text": user_msg}]})
18
  messages.append({"role": "assistant", "content": ai_msg})
19
 
20
- # Construir contenido del mensaje con texto e imagen
21
- user_content = [
22
- {"type": "text", "text": user_message}
23
- ]
24
- if image_base64:
25
- user_content.append({
26
- "type": "image_url",
27
- "image_url": {
28
- "url": image_base64
29
- }
30
- })
31
-
32
  messages.append({"role": "user", "content": user_content})
33
 
34
  json_data = {
@@ -42,7 +176,6 @@ def query_sambanova_with_image(user_message, image_base64, chat_history):
42
  response.raise_for_status()
43
 
44
  collected_text = ""
45
- updated_history = chat_history.copy()
46
  updated_history.append((user_message, ""))
47
 
48
  for line in response.iter_lines(decode_unicode=True):
@@ -61,27 +194,31 @@ def query_sambanova_with_image(user_message, image_base64, chat_history):
61
  if updated_history:
62
  updated_history[-1] = (updated_history[-1][0], collected_text)
63
 
64
- yield updated_history, updated_history
65
  except json.JSONDecodeError:
66
  continue
67
  except requests.exceptions.RequestException as err:
68
  error_msg = f"Error: {err}"
69
- updated_history = chat_history.copy()
70
  if not updated_history or updated_history[-1][0] != user_message:
71
  updated_history.append((user_message, error_msg))
72
  else:
73
  updated_history[-1] = (updated_history[-1][0], error_msg)
74
- yield updated_history, updated_history
75
 
 
 
76
 
77
  with gr.Blocks() as demo:
78
  chat_history = gr.State([])
79
- chatbot = gr.Chatbot()
80
  msg = gr.Textbox(label="Escribe tu mensaje")
81
- img_input = gr.Textbox(label="Imagen base64 o URL (opcional)", placeholder="Pega aquí la imagen en base64 o URL")
82
- btn = gr.Button("Enviar")
 
 
83
 
84
- btn.click(query_sambanova_with_image, inputs=[msg, img_input, chat_history], outputs=[chatbot, chat_history])
85
- msg.submit(query_sambanova_with_image, inputs=[msg, img_input, chat_history], outputs=[chatbot, chat_history])
86
 
87
- demo.launch()
 
 
2
  import requests
3
  import json
4
  import os
5
+ import random
6
+ from typing import List, Optional
7
+
8
+ # Tu clase generadora de prompts
9
+ class HyperrealisticPromptGenerator:
10
+ def __init__(self):
11
+ self.ROLES = [
12
+ "nurse", "nun", "maid", "flight attendant", "secretary", "teacher", "schoolgirl", "lawyer",
13
+ "doctor", "boudoir model", "fitness model", "elegant judge", "seductive librarian",
14
+ "business executive", "policewoman", "female military officer", "WWII-era secretary",
15
+ "1960s flight attendant", "seductive maid", "mysterious nurse", "captivating schoolgirl"
16
+ ]
17
+ self.AGES = [
18
+ "early 20s youthful vibrance",
19
+ "early 20s fresh and vibrant",
20
+ "mid 20s graceful confidence",
21
+ "mid 20s elegant and fresh",
22
+ "early 20s natural glow"
23
+ ]
24
+ self.HAIR_COLORS = [
25
+ "deep sapphire blue", "silver platinum", "vibrant ruby red", "glossy jet black",
26
+ "luxurious chestnut brown", "emerald green", "vivid amethyst purple",
27
+ "chocolate brown", "honey blonde", "burgundy red"
28
+ ]
29
+ self.EYE_COLORS = [
30
+ "intense brown", "bright sapphire blue", "emerald green", "golden amber",
31
+ "fascinating hazel", "deep violet", "piercing emerald", "mysterious gray",
32
+ "vibrant violet", "intense amber"
33
+ ]
34
+ self.HAIR_STYLES = [
35
+ "long flowing chestnut hair styled in soft waves",
36
+ "sleek straight long black hair",
37
+ "luxurious long blonde curls",
38
+ "elegant updo with loose cascading strands",
39
+ "glossy long brunette hair parted in the middle",
40
+ "voluminous curls",
41
+ "thick braid over the shoulder",
42
+ "loose and silky layers",
43
+ "messy chic bun"
44
+ ]
45
+ self.POSES = [
46
+ "standing with one leg slightly forward, skirt shifting gently to subtly reveal lace thong, view from knees to head",
47
+ "seated on a chair edge, legs crossed, skirt moving slightly, natural sensual expression, low angle from knees",
48
+ "leaning against a desk with hips cocked, skirt riding up, captured from knees to head",
49
+ "walking with natural sway, skirt flowing, viewed contrapicado from knees",
50
+ "adjusting stockings or shoes, skirt slightly lifted revealing thong, viewed low angle knees up"
51
+ ]
52
+ self.SETTINGS = [
53
+ "modern office with elegant decor and warm ambient light",
54
+ "luxury hotel suite with velvet furnishings and city view",
55
+ "classic library with wooden shelves and soft reading lamps",
56
+ "outdoor balcony at sunset with urban skyline",
57
+ "high-end photo studio with professional soft lighting"
58
+ ]
59
+ self.ATMOSPHERES = [
60
+ "soft professional lighting with smooth skin shadows, perfect color balance",
61
+ "warm golden hour sunlight creating rich highlights and depth",
62
+ "moody cinematic lighting with subtle shadow play",
63
+ "gentle romantic candlelight with warm glows",
64
+ "sharp studio flash lighting with balanced illumination"
65
+ ]
66
+ self.TECHNICAL_DETAILS = (
67
+ "Captured in ultra HD 16K (15360×8640) vertical 9:16 full body format. "
68
+ "Canon EOS R5 Cine RAW camera and Canon RF 85mm f/1.2L USM lens at f/1.2 aperture for creamy bokeh and realistic depth of field. "
69
+ "ARRI SkyPanel S360-C with soft shadowless 3:1 lighting ratio. "
70
+ "Advanced Path Tracing, Physically Based Rendering (PBR), Subsurface Scattering (SSS) for lifelike skin translucency, "
71
+ "Ray Tracing for global illumination and reflections. "
72
+ "Photogrammetry-based texture mapping, displacement maps for skin pores, delicate fabric weave and lace micro-details. "
73
+ "Natural, physics-driven hair strand flow. "
74
+ "Composition uses contrapicado low-angle (knee to head) shots emphasizing natural, sensual lingerie reveal."
75
+ )
76
+ self.CONDITION_FIXED = (
77
+ "Wearing elegant thigh-high stockings, no bra, and high stilettos. "
78
+ "Delicately revealing a lace thong in a natural, seductive manner, as if caught candidly. "
79
+ "Age between 20 and 25, radiating youthfulness and fresh allure. "
80
+ "Pose and framing strictly low-angle, knees to head vertical 9:16 aspect ratio, full body filling the frame."
81
+ )
82
+
83
+ def _choose_random(self, options: List[str]) -> str:
84
+ return random.choice(options)
85
+
86
+ def generate_single_prompt(self, role: Optional[str] = None) -> str:
87
+ selected_role = role if role else self._choose_random(self.ROLES)
88
+ age = self._choose_random(self.AGES)
89
+ hair_color = self._choose_random(self.HAIR_COLORS)
90
+ eye_color = self._choose_random(self.EYE_COLORS)
91
+ hair_style = self._choose_random(self.HAIR_STYLES)
92
+ pose = self._choose_random(self.POSES)
93
+ setting = self._choose_random(self.SETTINGS)
94
+ atmosphere = self._choose_random(self.ATMOSPHERES)
95
+ prompt = (
96
+ f"```
97
+ f"Age: {age}\n"
98
+ f"Hair: {hair_style} in {hair_color}\n"
99
+ f"Eyes: {eye_color} with expressive, captivating gaze\n"
100
+ f"Pose: {pose}\n"
101
+ f"Environment: {setting}\n"
102
+ f"Atmosphere: {atmosphere}\n"
103
+ f"Outfit: {self.CONDITION_FIXED}\n\n"
104
+ f"Technical specs:\n{self.TECHNICAL_DETAILS}\n```"
105
+ )
106
+ return prompt
107
+
108
+ def generate_prompt_automatic(self):
109
+ # Simple método para generación automática sin rol pasado
110
+ return self.generate_single_prompt()
111
+
112
+ # Instancia del generador
113
+ gen = HyperrealisticPromptGenerator()
114
+
115
+ # Configuración API SambaNova
116
  API_KEY = os.getenv("SAMBANOVA_API_KEY")
117
  API_URL = "https://api.sambanova.ai/v1/chat/completions"
 
118
  headers = {
119
  "Authorization": f"Bearer {API_KEY}",
120
  "Content-Type": "application/json",
121
  }
122
 
123
+ def analizar_imagen_y_generar_prompt(image_url_or_base64):
124
+ # Se envía la imagen para obtener una descripción en inglés
125
+ messages = [
126
+ {"role": "system", "content": "You are an assistant that describes images in detailed English."},
127
+ {"role": "user", "content": [
128
+ {"type": "image_url", "image_url": {"url": image_url_or_base64}},
129
+ {"type": "text", "text": "Provide a detailed English description of this image to use as a prompt."},
130
+ ]}
131
+ ]
132
+ json_data = {
133
+ "model": "Llama-4-Maverick-17B-128E-Instruct",
134
+ "messages": messages,
135
+ "stream": False,
136
+ }
137
+ try:
138
+ response = requests.post(API_URL, headers=headers, json=json_data)
139
+ response.raise_for_status()
140
+ resp_json = response.json()
141
+ text_resp = resp_json["choices"][0]["message"]["content"]
142
+ prompt = f"``````"
143
+ return prompt
144
+ except Exception as e:
145
+ return f"Error al analizar imagen y generar prompt: {e}"
146
+
147
+ def chat_sambanova(user_message, image_input, auto_mode, chat_history):
148
+ updated_history = chat_history.copy()
149
+
150
+ if auto_mode and image_input:
151
+ # Modo automático: analizar imagen y generar prompt automáticamente
152
+ prompt = analizar_imagen_y_generar_prompt(image_input)
153
+ # Mostrar prompt generado en el chat
154
+ updated_history.append(("IA - Prompt automático generado:", prompt))
155
+ return "", updated_history
156
+
157
+ # Modo chat manual: enviar mensaje a SambaNova API
158
  messages = [{"role": "system", "content": "Eres un asistente útil"}]
159
+ for user_msg, ai_msg in updated_history:
160
  messages.append({"role": "user", "content": [{"type": "text", "text": user_msg}]})
161
  messages.append({"role": "assistant", "content": ai_msg})
162
 
163
+ user_content = [{"type": "text", "text": user_message}]
164
+ if image_input:
165
+ user_content.append({"type": "image_url", "image_url": {"url": image_input}})
 
 
 
 
 
 
 
 
 
166
  messages.append({"role": "user", "content": user_content})
167
 
168
  json_data = {
 
176
  response.raise_for_status()
177
 
178
  collected_text = ""
 
179
  updated_history.append((user_message, ""))
180
 
181
  for line in response.iter_lines(decode_unicode=True):
 
194
  if updated_history:
195
  updated_history[-1] = (updated_history[-1][0], collected_text)
196
 
197
+ yield "", updated_history
198
  except json.JSONDecodeError:
199
  continue
200
  except requests.exceptions.RequestException as err:
201
  error_msg = f"Error: {err}"
 
202
  if not updated_history or updated_history[-1][0] != user_message:
203
  updated_history.append((user_message, error_msg))
204
  else:
205
  updated_history[-1] = (updated_history[-1][0], error_msg)
206
+ yield "", updated_history
207
 
208
+ def generar_prompt_interno():
209
+ return gen.generate_prompt_automatic()
210
 
211
  with gr.Blocks() as demo:
212
  chat_history = gr.State([])
213
+ chatbot = gr.Chatbot(label="Chatbot IA")
214
  msg = gr.Textbox(label="Escribe tu mensaje")
215
+ img_input = gr.Textbox(label="Imagen base64 o URL (opcional)", placeholder="Pega aquí la imagen o URL")
216
+ auto_mode = gr.Checkbox(label="Modo automático (generar prompt auto desde imagen)", value=False)
217
+ btn_send = gr.Button("Enviar mensaje")
218
+ btn_gen_prompt = gr.Button("Generar prompt automático interno")
219
 
220
+ btn_send.click(chat_sambanova, inputs=[msg, img_input, auto_mode, chat_history], outputs=[msg, chatbot, chat_history])
221
+ msg.submit(chat_sambanova, inputs=[msg, img_input, auto_mode, chat_history], outputs=[msg, chatbot, chat_history])
222
 
223
+ btn_gen_prompt.click(lambda: (gen.generate_prompt_
224
+