zgrafic commited on
Commit
1a9fba2
·
verified ·
1 Parent(s): e920b88

Upload 2 files

Browse files
Files changed (2) hide show
  1. bot.py +53 -5
  2. requirements.txt +1 -0
bot.py CHANGED
@@ -7,6 +7,7 @@ Corre como una tarea en segundo plano dentro del mismo servidor FastAPI
7
  """
8
  import os
9
  import io
 
10
  from PIL import Image
11
  import json
12
  import uuid
@@ -16,6 +17,7 @@ from datetime import date, datetime, timezone
16
  import httpx
17
  import firebase_admin
18
  from firebase_admin import credentials, firestore
 
19
  from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, LabeledPrice
20
  from telegram.request import HTTPXRequest
21
  from telegram.ext import (
@@ -24,11 +26,12 @@ from telegram.ext import (
24
  )
25
 
26
  BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "")
 
27
 
28
  REMOVE_BG_URL = "https://zgrafic-remove-bg-api.hf.space/remove-bg"
29
  ENHANCE_URL = "https://zgrafic-remove-bg-api.hf.space/enhance"
30
  VECTORIZE_URL = "https://zgrafic-remove-bg-api.hf.space/vectorize"
31
- VECTORIZE_AI_URL = "https://zgrafic-enhance-photo-api.hf.space/vectorize-ai"
32
 
33
  FREE_USES_PER_DAY = 10
34
  STARS_PER_IMAGE = 10
@@ -330,6 +333,45 @@ async def on_successful_payment(update: Update, context: ContextTypes.DEFAULT_TY
330
  await process_and_send(context, job["chat_id"], job["file_id"], job["mode"])
331
 
332
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
  async def post_with_wakeup(context: ContextTypes.DEFAULT_TYPE, chat_id: int, url: str, files: dict, data: dict, mode: str):
334
  """Manda el pedido al servidor, reintentando con paciencia si está
335
  'despertando' (Hugging Face devuelve 429 mientras el contenedor
@@ -407,18 +449,23 @@ async def process_and_send(context: ContextTypes.DEFAULT_TYPE, chat_id: int, fil
407
  resp = await post_with_wakeup(context, chat_id, VECTORIZE_URL, files, {}, "vectorize")
408
  if resp is None:
409
  return False
 
 
 
 
 
 
 
410
 
411
  else:
412
  if mode == "remove":
413
  url = REMOVE_BG_URL
414
- elif mode == "vectorize_ai":
415
- url = VECTORIZE_AI_URL
416
  else:
417
  url = ENHANCE_URL
418
 
419
  files = {"file": ("imagen.jpg", image_bytes, "image/jpeg")}
420
 
421
- if mode in ("remove", "vectorize_ai"):
422
  data = {}
423
  elif mode == "enhance_imagen":
424
  data = {"type": "imagen", "scale": "4"}
@@ -428,11 +475,12 @@ async def process_and_send(context: ContextTypes.DEFAULT_TYPE, chat_id: int, fil
428
  resp = await post_with_wakeup(context, chat_id, url, files, data, mode)
429
  if resp is None:
430
  return False
 
431
 
432
  extension = "svg" if mode in ("vectorize", "vectorize_ai") else "png"
433
  await context.bot.send_document(
434
  chat_id,
435
- document=io.BytesIO(resp.content),
436
  filename=f"resultado.{extension}",
437
  )
438
  return True
 
7
  """
8
  import os
9
  import io
10
+ import tempfile
11
  from PIL import Image
12
  import json
13
  import uuid
 
17
  import httpx
18
  import firebase_admin
19
  from firebase_admin import credentials, firestore
20
+ from gradio_client import Client, handle_file
21
  from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, LabeledPrice
22
  from telegram.request import HTTPXRequest
23
  from telegram.ext import (
 
26
  )
27
 
28
  BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "")
29
+ HF_TOKEN = os.environ.get("HF_TOKEN", "")
30
 
31
  REMOVE_BG_URL = "https://zgrafic-remove-bg-api.hf.space/remove-bg"
32
  ENHANCE_URL = "https://zgrafic-remove-bg-api.hf.space/enhance"
33
  VECTORIZE_URL = "https://zgrafic-remove-bg-api.hf.space/vectorize"
34
+ ZEROGPU_SPACE = "zgrafic/ia" # Vectorizar con IA (HiVG-3B-Base + ZeroGPU)
35
 
36
  FREE_USES_PER_DAY = 10
37
  STARS_PER_IMAGE = 10
 
333
  await process_and_send(context, job["chat_id"], job["file_id"], job["mode"])
334
 
335
 
336
+ _gradio_client = None
337
+
338
+
339
+ def _get_gradio_client():
340
+ global _gradio_client
341
+ if _gradio_client is None:
342
+ _gradio_client = Client(ZEROGPU_SPACE, hf_token=HF_TOKEN or None)
343
+ return _gradio_client
344
+
345
+
346
+ def _call_vectorize_ai_sync(image_bytes: bytes) -> str:
347
+ """Llama al Space de ZeroGPU (Gradio) — es una librería con llamadas
348
+ que bloquean, por eso se corre en un hilo aparte desde afuera."""
349
+ with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
350
+ tmp.write(image_bytes)
351
+ tmp_path = tmp.name
352
+
353
+ client = _get_gradio_client()
354
+ result_path = client.predict(handle_file(tmp_path), api_name="/predict")
355
+
356
+ with open(result_path, "r") as f:
357
+ return f.read()
358
+
359
+
360
+ async def call_vectorize_ai(context: ContextTypes.DEFAULT_TYPE, chat_id: int, image_bytes: bytes):
361
+ """Vectoriza con HiVG-3B-Base, corriendo en el Space de ZeroGPU
362
+ (GPU real, no el servidor de CPU) — devuelve el SVG como texto, o
363
+ None si falló (ya le avisó el motivo a la persona en el chat)."""
364
+ try:
365
+ svg_text = await asyncio.to_thread(_call_vectorize_ai_sync, image_bytes)
366
+ return svg_text
367
+ except Exception as e:
368
+ await context.bot.send_message(
369
+ chat_id,
370
+ f"No se pudo vectorizar con IA ({type(e).__name__}): {e or 'sin detalle'}"
371
+ )
372
+ return None
373
+
374
+
375
  async def post_with_wakeup(context: ContextTypes.DEFAULT_TYPE, chat_id: int, url: str, files: dict, data: dict, mode: str):
376
  """Manda el pedido al servidor, reintentando con paciencia si está
377
  'despertando' (Hugging Face devuelve 429 mientras el contenedor
 
449
  resp = await post_with_wakeup(context, chat_id, VECTORIZE_URL, files, {}, "vectorize")
450
  if resp is None:
451
  return False
452
+ result_bytes = resp.content
453
+
454
+ elif mode == "vectorize_ai":
455
+ svg_text = await call_vectorize_ai(context, chat_id, image_bytes)
456
+ if svg_text is None:
457
+ return False
458
+ result_bytes = svg_text.encode("utf-8")
459
 
460
  else:
461
  if mode == "remove":
462
  url = REMOVE_BG_URL
 
 
463
  else:
464
  url = ENHANCE_URL
465
 
466
  files = {"file": ("imagen.jpg", image_bytes, "image/jpeg")}
467
 
468
+ if mode == "remove":
469
  data = {}
470
  elif mode == "enhance_imagen":
471
  data = {"type": "imagen", "scale": "4"}
 
475
  resp = await post_with_wakeup(context, chat_id, url, files, data, mode)
476
  if resp is None:
477
  return False
478
+ result_bytes = resp.content
479
 
480
  extension = "svg" if mode in ("vectorize", "vectorize_ai") else "png"
481
  await context.bot.send_document(
482
  chat_id,
483
+ document=io.BytesIO(result_bytes),
484
  filename=f"resultado.{extension}",
485
  )
486
  return True
requirements.txt CHANGED
@@ -18,3 +18,4 @@ realesrgan==0.3.0
18
  gfpgan==1.3.8
19
  firebase-admin==6.5.0
20
  vtracer==0.6.15
 
 
18
  gfpgan==1.3.8
19
  firebase-admin==6.5.0
20
  vtracer==0.6.15
21
+ gradio_client