diwash-barla1 commited on
Commit
a67e1df
·
verified ·
1 Parent(s): e484878

Update comfy_engine.py

Browse files
Files changed (1) hide show
  1. comfy_engine.py +118 -55
comfy_engine.py CHANGED
@@ -68,78 +68,141 @@ def complete_task(task_id, video_url=None, error=None):
68
  save_history(data)
69
 
70
  # ==========================================
71
- # CORE ENGINE LOGIC
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  # ==========================================
73
- def inject_params(req: dict) -> dict:
74
- p = json.loads(json.dumps(WORKFLOW_TEMPLATE))
75
- p["89"]["inputs"]["text"] = req.get("prompt", "")
76
- ratio = req.get("aspect_ratio", "16:9")
77
- quality = req.get("quality", "480p")
78
- width, height = RESOLUTIONS.get(quality, {}).get(ratio, (848, 480))
79
- p["74"]["inputs"]["width"] = width
80
- p["74"]["inputs"]["height"] = height
81
- p["74"]["inputs"]["length"] = req.get("frames", 81)
82
- p["88"]["inputs"]["fps"] = req.get("fps", 16)
83
-
84
- # ❌ यहाँ से मैंने steps और cfg वाली दोनों लाइनें डिलीट कर दी हैं!
85
- # अब यह कोड सीधा workflow.json की मास्टर सेटिंग्स उठाएगा।
86
- return p
87
-
88
- def extract_video_url(history: dict, token: str) -> str:
89
- outputs = history.get("outputs", {})
90
- for _, node_out in outputs.items():
91
- for key in ("videos", "images", "files"):
92
- if key in node_out and node_out[key]:
93
- it = node_out[key][0]
94
- q = urlencode(it)
95
- return f"/api/video?{q}&token={token}"
96
- raise RuntimeError("Video not found")
97
-
98
- async def queue_prompt(req: dict):
99
- token = str(uuid.uuid4())
100
- client_id = str(uuid.uuid4())
101
- prompt_data = inject_params(req)
102
-
103
- async with httpx.AsyncClient() as client:
104
- resp = await client.post(f"http://{COMFY_HOST}/prompt?token={token}",
105
- json={"prompt": prompt_data, "client_id": client_id},
106
- timeout=30.0)
107
- prompt_id = resp.json().get("prompt_id")
108
- if not prompt_id: raise Exception("Failed to queue on AMD Server")
109
-
110
- return prompt_id, client_id, token, len(prompt_data)
111
-
112
- # 🚀 THE BACKGROUND WATCHER (यह फोन बंद होने पर भी चलता रहेगा)
113
  async def background_watcher(task_id, client_id, token, total_nodes):
114
  seen = set()
115
  start_t = time.time()
116
  progress_fake = 0
117
  ws_url = f"ws://{COMFY_HOST}/ws?clientId={client_id}&token={token}"
118
-
 
119
  try:
120
- async with websockets.connect(ws_url, ping_interval=20) as ws:
 
121
  while True:
122
  msg_raw = await ws.recv()
 
123
  if isinstance(msg_raw, (bytes, bytearray)):
124
  if progress_fake < 95 and (time.time() - start_t) > 2:
125
  progress_fake = min(95, progress_fake + 1)
126
- update_task_progress(task_id, progress_fake) # लाइव प्रोग्रेस सेव
127
  continue
128
-
129
  msg = json.loads(msg_raw)
130
- if msg.get("type") == "executing":
 
 
 
 
 
131
  node = msg.get("data", {}).get("node")
132
- if node is None: break # रेंडरिंग ख़तम
 
 
133
  if node not in seen:
134
  seen.add(node)
135
- p_real = int((len(seen) / total_nodes) * 100)
136
- progress_fake = max(progress_fake, p_real)
137
- update_task_progress(task_id, progress_fake) # लाइव प्रोग्रेस सेव
138
- except Exception:
139
- pass # अगर कनेक्शन टूटा तो भी कोई बात नहीं, हम हिस्ट्री चेक कर लेंगे!
140
-
141
- # 🎬 फाइनल चेक और सेविंग
142
- await asyncio.sleep(2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  try:
144
  async with httpx.AsyncClient() as client:
145
  h_resp = await client.get(f"http://{COMFY_HOST}/history/{task_id}?token={token}", timeout=30.0)
 
68
  save_history(data)
69
 
70
  # ==========================================
71
+ # 🗄SMART HISTORY MANAGER (Live Tracking)
72
+ # ==========================================
73
+ def load_history():
74
+ if os.path.exists("history.json"):
75
+ try:
76
+ with open("history.json", "r", encoding="utf-8") as f:
77
+ return json.load(f)
78
+ except:
79
+ pass
80
+ return []
81
+
82
+ def save_history(data):
83
+ with open("history.json", "w", encoding="utf-8") as f:
84
+ json.dump(data[:50], f, indent=4) # 50 वीडियोस की लिमिट
85
+
86
+ def init_task(task_id, prompt):
87
+ data = load_history()
88
+ # 👈 फिक्स 1: शुरुआत में इसे 'queued' रखो ताकि UI पर पीला वाला IN QUEUE दिखे
89
+ new_entry = {
90
+ "id": task_id,
91
+ "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
92
+ "prompt": prompt,
93
+ "status": "queued",
94
+ "progress": 0,
95
+ "url": None
96
+ }
97
+ data.insert(0, new_entry)
98
+ save_history(data)
99
+
100
+ # 👈 फिक्स 2: प्रोग्रेस के साथ-साथ स्टेटस भी अपडेट करने का ऑप्शन
101
+ def update_task_progress(task_id, progress, status=None):
102
+ data = load_history()
103
+ for item in data:
104
+ if item["id"] == task_id:
105
+ item["progress"] = progress
106
+ if status:
107
+ item["status"] = status
108
+ break
109
+ save_history(data)
110
+
111
+ def complete_task(task_id, video_url=None, error=None):
112
+ data = load_history()
113
+ for item in data:
114
+ if item["id"] == task_id:
115
+ if error:
116
+ item["status"] = "failed"
117
+ item["error"] = error
118
+ else:
119
+ item["status"] = "done"
120
+ item["progress"] = 100
121
+ item["url"] = video_url
122
+ break
123
+ save_history(data)
124
+
125
+
126
+ # ==========================================
127
+ # 🚀 THE BULLETPROOF BACKGROUND WATCHER
128
  # ==========================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  async def background_watcher(task_id, client_id, token, total_nodes):
130
  seen = set()
131
  start_t = time.time()
132
  progress_fake = 0
133
  ws_url = f"ws://{COMFY_HOST}/ws?clientId={client_id}&token={token}"
134
+
135
+ # 1. WEBSOCKET LOOP (Live Progress के लिए)
136
  try:
137
+ # 👈 टाइमआउट बढ़ा दिया है ताकि जल्दी ना कटे
138
+ async with websockets.connect(ws_url, ping_interval=30, ping_timeout=120) as ws:
139
  while True:
140
  msg_raw = await ws.recv()
141
+
142
  if isinstance(msg_raw, (bytes, bytearray)):
143
  if progress_fake < 95 and (time.time() - start_t) > 2:
144
  progress_fake = min(95, progress_fake + 1)
145
+ update_task_progress(task_id, progress_fake, "processing")
146
  continue
147
+
148
  msg = json.loads(msg_raw)
149
+
150
+ # जब GPU असली रेंडरिंग शुरू करे
151
+ if msg.get("type") == "execution_start":
152
+ update_task_progress(task_id, progress_fake, "processing")
153
+
154
+ elif msg.get("type") == "executing":
155
  node = msg.get("data", {}).get("node")
156
+ if node is None:
157
+ break # रेंडरिंग ख़तम
158
+
159
  if node not in seen:
160
  seen.add(node)
161
+
162
+ p_real = int((len(seen) / total_nodes) * 100)
163
+ progress_fake = max(progress_fake, p_real)
164
+ update_task_progress(task_id, progress_fake, "processing")
165
+
166
+ except Exception as e:
167
+ print(f"⚠️ WS Drop for {task_id}: {e} (Switching to HTTP Polling...)")
168
+ pass # अगर फोन कट भी गया, तो नीचे वाला जासूस संभाल लेगा!
169
+
170
+ # 2. HTTP POLLING FALLBACK (असली ब्रह्मास्त्र)
171
+ # यह तब तक बैकएंड से पूछता रहेगा जब तक वीडियो सच में बन नहीं जाता
172
+ while True:
173
+ try:
174
+ async with httpx.AsyncClient() as client:
175
+ # A. सबसे पहले चेक करो कि वीडियो बनकर हिस्ट्री में आ गया क्या?
176
+ h_resp = await client.get(f"http://{COMFY_HOST}/history/{task_id}?token={token}", timeout=10.0)
177
+ if h_resp.status_code == 200:
178
+ history_data = h_resp.json()
179
+ if task_id in history_data:
180
+ v_url = extract_video_url(history_data[task_id], token)
181
+ complete_task(task_id, video_url=v_url)
182
+ return # काम पूरा, लूप ख़तम!
183
+
184
+ # B. अगर नहीं बना, तो चेक करो कि अभी भी कतार में है क्या?
185
+ q_resp = await client.get(f"http://{COMFY_HOST}/queue?token={token}", timeout=10.0)
186
+ if q_resp.status_code == 200:
187
+ queue_data = q_resp.json()
188
+
189
+ is_running = any(req[1] == task_id for req in queue_data.get("queue_running", []))
190
+ is_pending = any(req[1] == task_id for req in queue_data.get("queue_pending", []))
191
+
192
+ if is_running:
193
+ update_task_progress(task_id, progress_fake, "processing")
194
+ elif is_pending:
195
+ update_task_progress(task_id, progress_fake, "queued")
196
+ else:
197
+ # ना हिस्ट्री में है, ना रनिंग है, ना पेंडिंग है! मतलब सर्वर से क्रैश हो गया।
198
+ complete_task(task_id, error="Task disappeared from ComfyUI server.")
199
+ return
200
+
201
+ except Exception as e:
202
+ print(f"⚠️ Polling failed for {task_id}, retrying... ({e})")
203
+
204
+ # 10 सेकंड आराम करके फिर चेक करेगा
205
+ await asyncio.sleep(10)
206
  try:
207
  async with httpx.AsyncClient() as client:
208
  h_resp = await client.get(f"http://{COMFY_HOST}/history/{task_id}?token={token}", timeout=30.0)