appinitdev commited on
Commit
53c43ed
·
verified ·
1 Parent(s): 4b858f2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -20
app.py CHANGED
@@ -4,11 +4,12 @@ import traceback
4
  import requests
5
  import gradio as gr
6
 
7
- # Configuración de URLs y Variables de Entorno
8
  API_URL = "https://api-inference.huggingface.co/models/joyfox/Qwen-Image-Edit-Cosplay"
9
 
10
- def fusionar_cosplay(imagen_real, imagen_ref):
11
- # Forzamos la lectura del Secret de forma dinámica dentro de la petición
 
12
  hf_token = os.getenv("HF_TOKEN")
13
 
14
  if not hf_token:
@@ -16,16 +17,15 @@ def fusionar_cosplay(imagen_real, imagen_ref):
16
  raise gr.Error("Falta el token HF_TOKEN en el servidor.")
17
 
18
  try:
19
- print("[+] Petición recibida desde Android. Procesando cadenas Base64...")
20
 
21
- # Validamos y aseguramos el prefijo Data URI para el JSON de Qwen
22
  data_uri_real = imagen_real if imagen_real.startswith("data:") else f"data:image/jpeg;base64,{imagen_real}"
23
  data_uri_ref = imagen_ref if imagen_ref.startswith("data:") else f"data:image/jpeg;base64,{imagen_ref}"
24
 
25
- # Prompt optimizado monolingüe para evitar fallos de contexto en Qwen
26
- prompt_texto = "把图2中动漫人物中的发型,服饰和装扮道具迁移到图1的真实人物,图1真实人物保持高度人脸一致性"
27
 
28
- # Payload JSON para la API de Inferencia Serverless
29
  json_payload = {
30
  "inputs": {
31
  "text": prompt_texto,
@@ -41,37 +41,41 @@ def fusionar_cosplay(imagen_real, imagen_ref):
41
  "Content-Type": "application/json"
42
  }
43
 
44
- print("[+] Enviando petición a la API de Inferencia de Hugging Face...")
45
  respuesta = requests.post(API_URL, headers=headers, json=json_payload, timeout=110)
46
- print(f"[+] Respuesta recibida. Código de estado: {respuesta.status_code}")
47
 
48
  if respuesta.status_code == 200:
49
  content_type = respuesta.headers.get("content-type", "").lower()
50
-
51
  if "application/json" in content_type:
52
  return respuesta.json()
53
  else:
 
54
  imagen_procesada_base64 = base64.b64encode(respuesta.content).decode("utf-8")
55
- return {"data": f"data:image/jpeg;base64,{imagen_procesada_base64}"}
56
  else:
57
- print(f"[-] Error de la API de Inferencia: {respuesta.text}")
58
  raise gr.Error(f"HF API Error: {respuesta.status_code}")
59
 
60
  except Exception as e:
61
- print("\n================= CRASH EN EL PROXY =================")
62
  traceback.print_exc()
63
  print("=====================================================\n")
64
  raise gr.Error(f"Crash interno: {str(e)}")
65
 
66
- # Creamos una interfaz nativa limpia.
67
- # Esto le dice a Gradio 6 que cree automáticamente un endpoint HTTP POST estándar en /api/predict
68
  demo = gr.Interface(
69
- fn=fusionar_cosplay,
70
- inputs=[gr.Textbox(label="Imagen Real"), gr.Textbox(label="Imagen Referencia")],
71
- outputs=gr.JSON(label="Resultado"),
 
 
 
72
  api_name="predict"
73
  )
74
 
75
- # Arrancamos apagando el SSR experimental para evitar el proxy intermedio de Node.js
 
76
  if __name__ == "__main__":
77
  demo.launch(ssr_mode=False)
 
4
  import requests
5
  import gradio as gr
6
 
7
+ # URL del modelo en el ecosistema Serverless de Hugging Face
8
  API_URL = "https://api-inference.huggingface.co/models/joyfox/Qwen-Image-Edit-Cosplay"
9
 
10
+ def fusionar_cosplay_bridge(imagen_real, imagen_ref):
11
+ # 🌟 CRÍTICO: Leemos el Secret dentro de la función para asegurar que
12
+ # esté disponible en el hilo de ejecución activo.
13
  hf_token = os.getenv("HF_TOKEN")
14
 
15
  if not hf_token:
 
17
  raise gr.Error("Falta el token HF_TOKEN en el servidor.")
18
 
19
  try:
20
+ print("[+] Petición recibida. Validando cadenas de entrada...")
21
 
22
+ # Sanitizamos los Strings Base64 agregando el prefijo Data URI requerido por Qwen
23
  data_uri_real = imagen_real if imagen_real.startswith("data:") else f"data:image/jpeg;base64,{imagen_real}"
24
  data_uri_ref = imagen_ref if imagen_ref.startswith("data:") else f"data:image/jpeg;base64,{imagen_ref}"
25
 
26
+ # Prompt optimizado puramente en caracteres originales para evitar problemas de codificación UTF-8
27
+ prompt_texto = "把图2中动漫人物中的发型,服饰和装扮道具迁移到图1 de 真实人物,图1真实人物保持高度人脸一致性"
28
 
 
29
  json_payload = {
30
  "inputs": {
31
  "text": prompt_texto,
 
41
  "Content-Type": "application/json"
42
  }
43
 
44
+ print("[+] Enviando payload a la API de Inferencia...")
45
  respuesta = requests.post(API_URL, headers=headers, json=json_payload, timeout=110)
46
+ print(f"[+] Respuesta del modelo recibida con código: {respuesta.status_code}")
47
 
48
  if respuesta.status_code == 200:
49
  content_type = respuesta.headers.get("content-type", "").lower()
 
50
  if "application/json" in content_type:
51
  return respuesta.json()
52
  else:
53
+ # Si la API retorna los bytes crudos de la imagen, la convertimos a Data URI estándar
54
  imagen_procesada_base64 = base64.b64encode(respuesta.content).decode("utf-8")
55
+ return {"data": [f"data:image/jpeg;base64,{imagen_procesada_base64}"]}
56
  else:
57
+ print(f"[-] Error de Hugging Face API: {respuesta.text}")
58
  raise gr.Error(f"HF API Error: {respuesta.status_code}")
59
 
60
  except Exception as e:
61
+ print("\n================= CRASH EN EL PUENTE =================")
62
  traceback.print_exc()
63
  print("=====================================================\n")
64
  raise gr.Error(f"Crash interno: {str(e)}")
65
 
66
+ # Usamos la clase Interface nativa. Al asignarle api_name="predict",
67
+ # Gradio mapea automáticamente un endpoint POST HTTP puro en la ruta /api/predict
68
  demo = gr.Interface(
69
+ fn=fusionar_cosplay_bridge,
70
+ inputs=[
71
+ gr.Textbox(label="Imagen Real Base64"),
72
+ gr.Textbox(label="Imagen Referencia Base64")
73
+ ],
74
+ outputs=gr.JSON(label="Resultado JSON"),
75
  api_name="predict"
76
  )
77
 
78
+ # 🌟 Deshabilitamos el Server-Side Rendering (SSR) experimental de Gradio 6
79
+ # para que no interfiera con llamadas de red crudas hechas desde Ktor (Android).
80
  if __name__ == "__main__":
81
  demo.launch(ssr_mode=False)