comfy-env 0.0.55__tar.gz → 0.0.56__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {comfy_env-0.0.55 → comfy_env-0.0.56}/PKG-INFO +1 -1
- {comfy_env-0.0.55 → comfy_env-0.0.56}/pyproject.toml +1 -1
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/isolation.py +12 -5
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/workers/venv.py +55 -31
- {comfy_env-0.0.55 → comfy_env-0.0.56}/.github/workflows/publish.yml +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/.gitignore +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/LICENSE +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/README.md +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/__init__.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/cli.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/decorator.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/env/__init__.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/env/config.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/env/config_file.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/env/cuda_gpu_detection.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/env/manager.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/env/platform/__init__.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/env/platform/base.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/env/platform/darwin.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/env/platform/linux.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/env/platform/windows.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/env/security.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/errors.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/install.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/ipc/__init__.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/ipc/bridge.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/ipc/protocol.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/ipc/tensor.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/ipc/torch_bridge.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/ipc/transport.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/ipc/worker.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/nodes.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/pixi.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/registry.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/resolver.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/stub_imports.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/stubs/__init__.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/stubs/comfy/__init__.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/stubs/comfy/model_management.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/stubs/comfy/utils.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/stubs/folder_paths.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/templates/comfy-env-instructions.txt +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/templates/comfy-env.toml +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/wheel_sources.yml +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/workers/__init__.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/workers/base.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/workers/pool.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/workers/tensor_utils.py +0 -0
- {comfy_env-0.0.55 → comfy_env-0.0.56}/src/comfy_env/workers/torch_mp.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: comfy-env
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.56
|
|
4
4
|
Summary: Environment management for ComfyUI custom nodes - CUDA wheel resolution and process isolation
|
|
5
5
|
Project-URL: Homepage, https://github.com/PozzettiAndrea/comfy-env
|
|
6
6
|
Project-URL: Repository, https://github.com/PozzettiAndrea/comfy-env
|
|
@@ -30,6 +30,9 @@ from functools import wraps
|
|
|
30
30
|
from pathlib import Path
|
|
31
31
|
from typing import Any, Dict, Optional
|
|
32
32
|
|
|
33
|
+
# Debug logging (set COMFY_ENV_DEBUG=1 to enable)
|
|
34
|
+
_DEBUG = os.environ.get("COMFY_ENV_DEBUG", "").lower() in ("1", "true", "yes")
|
|
35
|
+
|
|
33
36
|
# Global worker cache (one per isolated environment)
|
|
34
37
|
_workers: Dict[str, Any] = {}
|
|
35
38
|
_workers_lock = threading.Lock()
|
|
@@ -158,11 +161,13 @@ def _wrap_node_class(
|
|
|
158
161
|
|
|
159
162
|
@wraps(original_method)
|
|
160
163
|
def proxy(self, **kwargs):
|
|
161
|
-
|
|
162
|
-
|
|
164
|
+
if _DEBUG:
|
|
165
|
+
print(f"[comfy-env] PROXY CALLED: {cls.__name__}.{func_name}", flush=True)
|
|
166
|
+
print(f"[comfy-env] kwargs keys: {list(kwargs.keys())}", flush=True)
|
|
163
167
|
|
|
164
168
|
worker = _get_worker(env_name, python_path, working_dir, sys_path)
|
|
165
|
-
|
|
169
|
+
if _DEBUG:
|
|
170
|
+
print(f"[comfy-env] worker alive: {worker.is_alive()}", flush=True)
|
|
166
171
|
|
|
167
172
|
# Clone tensors for IPC if needed
|
|
168
173
|
try:
|
|
@@ -172,7 +177,8 @@ def _wrap_node_class(
|
|
|
172
177
|
except ImportError:
|
|
173
178
|
pass # No torch available, skip cloning
|
|
174
179
|
|
|
175
|
-
|
|
180
|
+
if _DEBUG:
|
|
181
|
+
print(f"[comfy-env] calling worker.call_method...", flush=True)
|
|
176
182
|
result = worker.call_method(
|
|
177
183
|
module_name=module_name,
|
|
178
184
|
class_name=cls.__name__,
|
|
@@ -181,7 +187,8 @@ def _wrap_node_class(
|
|
|
181
187
|
kwargs=kwargs,
|
|
182
188
|
timeout=600.0,
|
|
183
189
|
)
|
|
184
|
-
|
|
190
|
+
if _DEBUG:
|
|
191
|
+
print(f"[comfy-env] call_method returned", flush=True)
|
|
185
192
|
|
|
186
193
|
# Clone result tensors
|
|
187
194
|
try:
|
|
@@ -41,7 +41,10 @@ from pathlib import Path
|
|
|
41
41
|
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|
42
42
|
|
|
43
43
|
from .base import Worker, WorkerError
|
|
44
|
+
from ..pixi import get_pixi_path
|
|
44
45
|
|
|
46
|
+
# Debug logging (set COMFY_ENV_DEBUG=1 to enable)
|
|
47
|
+
_DEBUG = os.environ.get("COMFY_ENV_DEBUG", "").lower() in ("1", "true", "yes")
|
|
45
48
|
|
|
46
49
|
# =============================================================================
|
|
47
50
|
# Socket IPC utilities - cross-platform with TCP fallback
|
|
@@ -614,16 +617,21 @@ from types import SimpleNamespace
|
|
|
614
617
|
# Enable faulthandler to dump traceback on SIGSEGV/SIGABRT/etc
|
|
615
618
|
faulthandler.enable(file=sys.stderr, all_threads=True)
|
|
616
619
|
|
|
620
|
+
# Debug logging (set COMFY_ENV_DEBUG=1 to enable)
|
|
621
|
+
_DEBUG = os.environ.get("COMFY_ENV_DEBUG", "").lower() in ("1", "true", "yes")
|
|
622
|
+
|
|
617
623
|
# Pre-import bpy FIRST to avoid DLL conflicts with numpy/torch/MKL
|
|
618
624
|
# bpy's DLLs must be loaded before other packages load conflicting versions
|
|
619
625
|
try:
|
|
620
626
|
import bpy
|
|
621
|
-
|
|
627
|
+
if _DEBUG:
|
|
628
|
+
print("[worker] Pre-imported bpy successfully", file=sys.stderr, flush=True)
|
|
622
629
|
except ImportError as e:
|
|
623
630
|
# bpy not available in this environment - that's fine
|
|
624
631
|
pass
|
|
625
632
|
except Exception as e:
|
|
626
|
-
|
|
633
|
+
if _DEBUG:
|
|
634
|
+
print(f"[worker] bpy pre-import warning: {e}", file=sys.stderr, flush=True)
|
|
627
635
|
|
|
628
636
|
# Watchdog: dump all thread stacks every 60 seconds to catch hangs
|
|
629
637
|
import threading
|
|
@@ -656,7 +664,8 @@ def _watchdog():
|
|
|
656
664
|
|
|
657
665
|
_watchdog_thread = threading.Thread(target=_watchdog, daemon=True)
|
|
658
666
|
_watchdog_thread.start()
|
|
659
|
-
|
|
667
|
+
if _DEBUG:
|
|
668
|
+
print(f"[worker] Watchdog started, logging to: {_watchdog_log}", flush=True)
|
|
660
669
|
|
|
661
670
|
# File-based logging for debugging (persists even if stdout/stderr are swallowed)
|
|
662
671
|
import tempfile
|
|
@@ -676,14 +685,15 @@ def wlog(msg):
|
|
|
676
685
|
|
|
677
686
|
wlog(f"[worker] === Worker starting, log file: {_worker_log_file} ===")
|
|
678
687
|
|
|
679
|
-
# Debug: print PATH at startup
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
688
|
+
# Debug: print PATH at startup (only if debug enabled)
|
|
689
|
+
if _DEBUG:
|
|
690
|
+
_path_sep = ";" if sys.platform == "win32" else ":"
|
|
691
|
+
_path_parts = os.environ.get("PATH", "").split(_path_sep)
|
|
692
|
+
print(f"[worker] PATH has {len(_path_parts)} entries:", file=sys.stderr, flush=True)
|
|
693
|
+
for _i, _p in enumerate(_path_parts[:15]):
|
|
694
|
+
print(f"[worker] [{_i}] {_p}", file=sys.stderr, flush=True)
|
|
695
|
+
if len(_path_parts) > 15:
|
|
696
|
+
print(f"[worker] ... and {len(_path_parts) - 15} more", file=sys.stderr, flush=True)
|
|
687
697
|
|
|
688
698
|
# On Windows, add host Python's DLL directories so packages like opencv can find VC++ runtime
|
|
689
699
|
if sys.platform == "win32":
|
|
@@ -1199,7 +1209,8 @@ class PersistentVenvWorker(Worker):
|
|
|
1199
1209
|
# For pixi environments, use "pixi run python" to get proper environment activation
|
|
1200
1210
|
# (CONDA_PREFIX, Library paths, etc.) which fixes DLL loading issues with bpy
|
|
1201
1211
|
is_pixi = '.pixi' in str(self.python)
|
|
1202
|
-
|
|
1212
|
+
if _DEBUG:
|
|
1213
|
+
print(f"[PersistentVenvWorker] is_pixi={is_pixi}, python={self.python}", flush=True)
|
|
1203
1214
|
if is_pixi:
|
|
1204
1215
|
# Find pixi project root (parent of .pixi directory)
|
|
1205
1216
|
pixi_project = self.python
|
|
@@ -1207,10 +1218,14 @@ class PersistentVenvWorker(Worker):
|
|
|
1207
1218
|
pixi_project = pixi_project.parent
|
|
1208
1219
|
pixi_project = pixi_project.parent # Go up from .pixi to project root
|
|
1209
1220
|
pixi_toml = pixi_project / "pixi.toml"
|
|
1210
|
-
|
|
1221
|
+
if _DEBUG:
|
|
1222
|
+
print(f"[PersistentVenvWorker] pixi_toml={pixi_toml}, exists={pixi_toml.exists()}", flush=True)
|
|
1211
1223
|
|
|
1212
1224
|
if pixi_toml.exists():
|
|
1213
|
-
|
|
1225
|
+
pixi_exe = get_pixi_path()
|
|
1226
|
+
if pixi_exe is None:
|
|
1227
|
+
raise WorkerError("pixi not found - required for isolated environment execution")
|
|
1228
|
+
cmd = [str(pixi_exe), "run", "--manifest-path", str(pixi_toml),
|
|
1214
1229
|
"python", str(self._worker_script), self._socket_addr]
|
|
1215
1230
|
# Clean PATH to remove ct-env entries that have conflicting DLLs
|
|
1216
1231
|
# Pixi will add its own environment paths
|
|
@@ -1230,15 +1245,16 @@ class PersistentVenvWorker(Worker):
|
|
|
1230
1245
|
cmd = [str(self.python), str(self._worker_script), self._socket_addr]
|
|
1231
1246
|
launch_env = env
|
|
1232
1247
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1248
|
+
if _DEBUG:
|
|
1249
|
+
print(f"[PersistentVenvWorker] launching cmd={cmd[:3]}...", flush=True)
|
|
1250
|
+
if launch_env:
|
|
1251
|
+
path_sep = ";" if sys.platform == "win32" else ":"
|
|
1252
|
+
path_parts = launch_env.get("PATH", "").split(path_sep)
|
|
1253
|
+
print(f"[PersistentVenvWorker] PATH has {len(path_parts)} entries:", flush=True)
|
|
1254
|
+
for i, p in enumerate(path_parts[:10]): # Show first 10
|
|
1255
|
+
print(f"[PersistentVenvWorker] [{i}] {p}", flush=True)
|
|
1256
|
+
if len(path_parts) > 10:
|
|
1257
|
+
print(f"[PersistentVenvWorker] ... and {len(path_parts) - 10} more", flush=True)
|
|
1242
1258
|
self._process = subprocess.Popen(
|
|
1243
1259
|
cmd,
|
|
1244
1260
|
stdin=subprocess.DEVNULL,
|
|
@@ -1389,12 +1405,15 @@ class PersistentVenvWorker(Worker):
|
|
|
1389
1405
|
Return value of the method.
|
|
1390
1406
|
"""
|
|
1391
1407
|
import sys
|
|
1392
|
-
|
|
1408
|
+
if _DEBUG:
|
|
1409
|
+
print(f"[PersistentVenvWorker] call_method: {module_name}.{class_name}.{method_name}", file=sys.stderr, flush=True)
|
|
1393
1410
|
|
|
1394
1411
|
with self._lock:
|
|
1395
|
-
|
|
1412
|
+
if _DEBUG:
|
|
1413
|
+
print(f"[PersistentVenvWorker] acquired lock, ensuring started...", file=sys.stderr, flush=True)
|
|
1396
1414
|
self._ensure_started()
|
|
1397
|
-
|
|
1415
|
+
if _DEBUG:
|
|
1416
|
+
print(f"[PersistentVenvWorker] worker started/confirmed", file=sys.stderr, flush=True)
|
|
1398
1417
|
|
|
1399
1418
|
timeout = timeout or 600.0
|
|
1400
1419
|
call_id = str(uuid.uuid4())[:8]
|
|
@@ -1406,11 +1425,14 @@ class PersistentVenvWorker(Worker):
|
|
|
1406
1425
|
try:
|
|
1407
1426
|
# Serialize kwargs
|
|
1408
1427
|
if kwargs:
|
|
1409
|
-
|
|
1428
|
+
if _DEBUG:
|
|
1429
|
+
print(f"[PersistentVenvWorker] serializing kwargs...", file=sys.stderr, flush=True)
|
|
1410
1430
|
serialized_kwargs = _serialize_for_ipc(kwargs)
|
|
1411
|
-
|
|
1431
|
+
if _DEBUG:
|
|
1432
|
+
print(f"[PersistentVenvWorker] saving to {inputs_path}...", file=sys.stderr, flush=True)
|
|
1412
1433
|
torch.save(serialized_kwargs, str(inputs_path))
|
|
1413
|
-
|
|
1434
|
+
if _DEBUG:
|
|
1435
|
+
print(f"[PersistentVenvWorker] saved inputs", file=sys.stderr, flush=True)
|
|
1414
1436
|
|
|
1415
1437
|
# Send request with class info
|
|
1416
1438
|
request = {
|
|
@@ -1422,9 +1444,11 @@ class PersistentVenvWorker(Worker):
|
|
|
1422
1444
|
"inputs_path": str(inputs_path) if kwargs else None,
|
|
1423
1445
|
"outputs_path": str(outputs_path),
|
|
1424
1446
|
}
|
|
1425
|
-
|
|
1447
|
+
if _DEBUG:
|
|
1448
|
+
print(f"[PersistentVenvWorker] sending request via socket...", file=sys.stderr, flush=True)
|
|
1426
1449
|
response = self._send_request(request, timeout)
|
|
1427
|
-
|
|
1450
|
+
if _DEBUG:
|
|
1451
|
+
print(f"[PersistentVenvWorker] got response: {response.get('status')}", file=sys.stderr, flush=True)
|
|
1428
1452
|
|
|
1429
1453
|
if response.get("status") == "error":
|
|
1430
1454
|
raise WorkerError(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|