feat(ml): auto-commit con 7 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-24 02:52:51 +02:00
parent f686b338d6
commit ff41f4f053
7 changed files with 724 additions and 0 deletions
+135
View File
@@ -0,0 +1,135 @@
"""Gestiona la cola y el historial de un servidor ComfyUI via su API HTTP.
Funcion impura: hace red (HTTP GET/POST). Solo stdlib (urllib, json).
Completa lo que comfyui_interrupt_queue no cubre. interrupt_queue corta el prompt
en ejecucion; esta funcion expone las cuatro operaciones restantes de la cola:
- "status": GET /queue -> cuantos prompts se ejecutan ahora (queue_running) y
cuantos estan encolados pendientes (queue_pending).
- "clear": POST /queue {"clear": true} -> vacia los pendientes de golpe.
- "delete": POST /queue {"delete": [prompt_id]} -> borra un prompt concreto de la
cola de pendientes (requiere prompt_id).
- "history": GET /history -> numero de prompts ya ejecutados que el servidor
recuerda (history_count).
NO lanza excepcion en fallo de red: degrada a {ok: False, error}.
"""
import json
import urllib.error
import urllib.request
def comfyui_queue_manage(
action: str,
*,
server: str = "127.0.0.1:8188",
prompt_id: str | None = None,
) -> dict:
"""Opera la cola/historial de ComfyUI: status, clear, delete o history.
Args:
action: operacion a realizar. Una de:
- "status": lee el estado de la cola.
- "clear": vacia los prompts pendientes (POST /queue {"clear": true}).
- "delete": borra un prompt concreto (POST /queue {"delete": [id]});
requiere prompt_id.
- "history": cuenta los prompts en el historial (GET /history).
server: host:port del servidor ComfyUI sin esquema (default
"127.0.0.1:8188"). keyword-only.
prompt_id: id del prompt a borrar; obligatorio solo para action="delete".
keyword-only.
Returns:
dict con:
- ok (bool): True si la operacion se completo sin error.
- action (str): la accion solicitada (eco).
- queue_running (int): prompts ejecutandose ahora (status/clear/delete).
- queue_pending (int): prompts encolados pendientes (status/clear/delete).
- history_count (int): numero de prompts en el historial (action=history).
- error (str): mensaje de error; cadena vacia si todo OK.
"""
out = {
"ok": False,
"action": action,
"queue_running": 0,
"queue_pending": 0,
"history_count": 0,
"error": "",
}
base = f"http://{server}"
valid = {"status", "clear", "delete", "history"}
if action not in valid:
out["error"] = f"action desconocida: {action!r}; usa una de {sorted(valid)}"
return out
def _read_queue() -> bool:
"""Rellena queue_running/queue_pending desde GET /queue. True si OK."""
try:
with urllib.request.urlopen(f"{base}/queue", timeout=10.0) as resp:
data = json.loads(resp.read())
out["queue_running"] = len(data.get("queue_running", []))
out["queue_pending"] = len(data.get("queue_pending", []))
return True
except urllib.error.URLError as exc:
reason = getattr(exc, "reason", exc)
out["error"] = f"GET /queue fallo: no se pudo conectar a {base}/queue: {reason}"
except json.JSONDecodeError as exc:
out["error"] = f"GET /queue fallo: respuesta no es JSON valido: {exc}"
return False
def _post_queue(body: dict) -> bool:
"""POST /queue con cuerpo JSON. True si el servidor respondio sin error."""
try:
payload = json.dumps(body).encode()
req = urllib.request.Request(
f"{base}/queue",
data=payload,
method="POST",
headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(req, timeout=10.0):
return True
except urllib.error.URLError as exc:
reason = getattr(exc, "reason", exc)
out["error"] = f"POST /queue fallo: no se pudo conectar a {base}/queue: {reason}"
return False
if action == "status":
out["ok"] = _read_queue()
return out
if action == "clear":
if _post_queue({"clear": True}):
out["ok"] = _read_queue()
return out
if action == "delete":
if not prompt_id:
out["error"] = "action='delete' requiere prompt_id"
return out
if _post_queue({"delete": [prompt_id]}):
out["ok"] = _read_queue()
return out
# action == "history"
try:
with urllib.request.urlopen(f"{base}/history", timeout=15.0) as resp:
hist = json.loads(resp.read())
out["history_count"] = len(hist) if isinstance(hist, dict) else 0
out["ok"] = True
except urllib.error.URLError as exc:
reason = getattr(exc, "reason", exc)
out["error"] = f"GET /history fallo: no se pudo conectar a {base}/history: {reason}"
except json.JSONDecodeError as exc:
out["error"] = f"GET /history fallo: respuesta no es JSON valido: {exc}"
return out
if __name__ == "__main__":
import sys
act = sys.argv[1] if len(sys.argv) > 1 else "status"
pid = sys.argv[2] if len(sys.argv) > 2 else None
res = comfyui_queue_manage(act, prompt_id=pid)
print(json.dumps(res, indent=2))