comfy-env 0.1.1__tar.gz → 0.1.3__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.
Files changed (34) hide show
  1. {comfy_env-0.1.1 → comfy_env-0.1.3}/PKG-INFO +1 -1
  2. {comfy_env-0.1.1 → comfy_env-0.1.3}/pyproject.toml +1 -1
  3. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/isolation/wrap.py +23 -2
  4. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/workers/mp.py +41 -11
  5. {comfy_env-0.1.1 → comfy_env-0.1.3}/.github/workflows/ci.yml +0 -0
  6. {comfy_env-0.1.1 → comfy_env-0.1.3}/.github/workflows/publish.yml +0 -0
  7. {comfy_env-0.1.1 → comfy_env-0.1.3}/.gitignore +0 -0
  8. {comfy_env-0.1.1 → comfy_env-0.1.3}/LICENSE +0 -0
  9. {comfy_env-0.1.1 → comfy_env-0.1.3}/README.md +0 -0
  10. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/__init__.py +0 -0
  11. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/cli.py +0 -0
  12. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/config/__init__.py +0 -0
  13. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/config/parser.py +0 -0
  14. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/config/types.py +0 -0
  15. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/errors.py +0 -0
  16. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/install.py +0 -0
  17. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/isolation/__init__.py +0 -0
  18. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/nodes.py +0 -0
  19. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/pixi/__init__.py +0 -0
  20. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/pixi/core.py +0 -0
  21. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/pixi/cuda_detection.py +0 -0
  22. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/pixi/platform/__init__.py +0 -0
  23. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/pixi/platform/base.py +0 -0
  24. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/pixi/platform/darwin.py +0 -0
  25. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/pixi/platform/linux.py +0 -0
  26. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/pixi/platform/windows.py +0 -0
  27. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/pixi/resolver.py +0 -0
  28. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/prestartup.py +0 -0
  29. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/templates/comfy-env-instructions.txt +0 -0
  30. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/templates/comfy-env.toml +0 -0
  31. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/workers/__init__.py +0 -0
  32. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/workers/base.py +0 -0
  33. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/workers/subprocess.py +0 -0
  34. {comfy_env-0.1.1 → comfy_env-0.1.3}/src/comfy_env/workers/tensor_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comfy-env
3
- Version: 0.1.1
3
+ Version: 0.1.3
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "comfy-env"
3
- version = "0.1.1"
3
+ version = "0.1.3"
4
4
  description = "Environment management for ComfyUI custom nodes - CUDA wheel resolution and process isolation"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}
@@ -67,6 +67,7 @@ def _get_worker(
67
67
  working_dir: Path,
68
68
  sys_path: list[str],
69
69
  lib_path: Optional[str] = None,
70
+ env_vars: Optional[dict] = None,
70
71
  ):
71
72
  """Get or create a persistent worker for the isolated environment."""
72
73
  cache_key = str(env_dir)
@@ -106,11 +107,14 @@ def _get_worker(
106
107
 
107
108
  print(f"[comfy-env] Starting isolated worker (MPWorker)")
108
109
  print(f"[comfy-env] Env: {env_dir}")
110
+ if env_vars:
111
+ print(f"[comfy-env] env_vars: {', '.join(f'{k}={v}' for k, v in env_vars.items())}")
109
112
 
110
113
  worker = MPWorker(
111
114
  name=working_dir.name,
112
115
  sys_path=sys_path,
113
116
  lib_path=lib_path,
117
+ env_vars=env_vars,
114
118
  )
115
119
 
116
120
  _workers[cache_key] = worker
@@ -187,6 +191,7 @@ def _wrap_node_class(
187
191
  working_dir: Path,
188
192
  sys_path: list[str],
189
193
  lib_path: Optional[str] = None,
194
+ env_vars: Optional[dict] = None,
190
195
  ) -> type:
191
196
  """
192
197
  Wrap a node class so its FUNCTION method runs in the isolated environment.
@@ -232,7 +237,7 @@ def _wrap_node_class(
232
237
  print(f"[comfy-env] PROXY CALLED: {cls.__name__}.{func_name}", flush=True)
233
238
  print(f"[comfy-env] kwargs keys: {list(kwargs.keys())}", flush=True)
234
239
 
235
- worker = _get_worker(env_dir, working_dir, sys_path, lib_path)
240
+ worker = _get_worker(env_dir, working_dir, sys_path, lib_path, env_vars)
236
241
  if _DEBUG:
237
242
  print(f"[comfy-env] worker alive: {worker.is_alive()}", flush=True)
238
243
 
@@ -322,6 +327,20 @@ def wrap_isolated_nodes(
322
327
  print(f"[comfy-env] Warning: No comfy-env.toml in {nodes_dir}")
323
328
  return node_class_mappings
324
329
 
330
+ # Read env_vars from comfy-env.toml
331
+ env_vars = {}
332
+ try:
333
+ if sys.version_info >= (3, 11):
334
+ import tomllib
335
+ else:
336
+ import tomli as tomllib
337
+ with open(config_file, "rb") as f:
338
+ config = tomllib.load(f)
339
+ env_vars_data = config.get("env_vars", {})
340
+ env_vars = {str(k): str(v) for k, v in env_vars_data.items()}
341
+ except Exception:
342
+ pass # Ignore errors reading config
343
+
325
344
  # Find environment directory and paths
326
345
  env_dir = _find_env_dir(nodes_dir)
327
346
  site_packages, lib_dir = _find_env_paths(nodes_dir)
@@ -342,10 +361,12 @@ def wrap_isolated_nodes(
342
361
  print(f"[comfy-env] site-packages: {site_packages}")
343
362
  if lib_path:
344
363
  print(f"[comfy-env] lib: {lib_path}")
364
+ if env_vars:
365
+ print(f"[comfy-env] env_vars: {', '.join(f'{k}={v}' for k, v in env_vars.items())}")
345
366
 
346
367
  # Wrap all node classes
347
368
  for node_name, node_cls in node_class_mappings.items():
348
369
  if hasattr(node_cls, "FUNCTION"):
349
- _wrap_node_class(node_cls, env_dir, nodes_dir, sys_path, lib_path)
370
+ _wrap_node_class(node_cls, env_dir, nodes_dir, sys_path, lib_path, env_vars)
350
371
 
351
372
  return node_class_mappings
@@ -40,7 +40,7 @@ _SHUTDOWN = object()
40
40
  _CALL_METHOD = "call_method"
41
41
 
42
42
 
43
- def _worker_loop(queue_in, queue_out, sys_path_additions=None, lib_path=None):
43
+ def _worker_loop(queue_in, queue_out, sys_path_additions=None, lib_path=None, env_vars=None):
44
44
  """
45
45
  Worker process main loop.
46
46
 
@@ -56,22 +56,50 @@ def _worker_loop(queue_in, queue_out, sys_path_additions=None, lib_path=None):
56
56
  queue_out: Output queue for sending results
57
57
  sys_path_additions: Paths to add to sys.path
58
58
  lib_path: Path to add to LD_LIBRARY_PATH (for conda libraries)
59
+ env_vars: Environment variables to set (from comfy-env.toml)
59
60
  """
60
61
  import os
61
62
  import sys
62
63
  from pathlib import Path
63
64
 
65
+ # Apply env_vars FIRST (before any library imports that might check them)
66
+ if env_vars:
67
+ os.environ.update(env_vars)
68
+
64
69
  # Set worker mode env var
65
70
  os.environ["COMFYUI_ISOLATION_WORKER"] = "1"
66
71
 
67
- # Set LD_LIBRARY_PATH for conda libraries (must be done before imports)
68
- if lib_path:
69
- if sys.platform == "win32":
70
- # Windows: add to PATH for DLL loading
71
- os.environ["PATH"] = lib_path + ";" + os.environ.get("PATH", "")
72
- else:
73
- # Linux/Mac: LD_LIBRARY_PATH
74
- os.environ["LD_LIBRARY_PATH"] = lib_path + ":" + os.environ.get("LD_LIBRARY_PATH", "")
72
+ # DLL/library isolation - match SubprocessWorker's isolation level
73
+ # Filter out conflicting paths from conda/mamba/etc and use proper DLL registration
74
+ path_sep = ";" if sys.platform == "win32" else ":"
75
+
76
+ if sys.platform == "win32":
77
+ # Use os.add_dll_directory() for explicit DLL registration (Python 3.8+)
78
+ if lib_path and hasattr(os, "add_dll_directory"):
79
+ try:
80
+ os.add_dll_directory(lib_path)
81
+ except Exception:
82
+ pass
83
+
84
+ # Filter conflicting paths from PATH (matches subprocess.py:1203-1212)
85
+ current_path = os.environ.get("PATH", "")
86
+ clean_parts = [
87
+ p for p in current_path.split(path_sep)
88
+ if not any(x in p.lower() for x in (".ct-envs", "conda", "mamba", "miniforge", "miniconda", "anaconda", "mingw"))
89
+ ]
90
+ if lib_path:
91
+ clean_parts.insert(0, lib_path)
92
+ os.environ["PATH"] = path_sep.join(clean_parts)
93
+ else:
94
+ # Linux/Mac: Filter LD_LIBRARY_PATH with same patterns
95
+ current = os.environ.get("LD_LIBRARY_PATH", "")
96
+ clean_parts = [
97
+ p for p in current.split(path_sep) if p
98
+ and not any(x in p.lower() for x in (".ct-envs", "conda", "mamba", "miniforge", "miniconda", "anaconda"))
99
+ ]
100
+ if lib_path:
101
+ clean_parts.insert(0, lib_path)
102
+ os.environ["LD_LIBRARY_PATH"] = path_sep.join(clean_parts)
75
103
 
76
104
  # Find ComfyUI base and add to sys.path for real folder_paths/comfy modules
77
105
  # This works because comfy.options.args_parsing=False by default, so folder_paths
@@ -401,7 +429,7 @@ class MPWorker(Worker):
401
429
  interpreter without inherited state from the parent.
402
430
  """
403
431
 
404
- def __init__(self, name: Optional[str] = None, sys_path: Optional[list] = None, lib_path: Optional[str] = None):
432
+ def __init__(self, name: Optional[str] = None, sys_path: Optional[list] = None, lib_path: Optional[str] = None, env_vars: Optional[dict] = None):
405
433
  """
406
434
  Initialize the worker.
407
435
 
@@ -409,10 +437,12 @@ class MPWorker(Worker):
409
437
  name: Optional name for logging/debugging.
410
438
  sys_path: Optional list of paths to add to sys.path in worker process.
411
439
  lib_path: Optional path to add to LD_LIBRARY_PATH (for conda libraries).
440
+ env_vars: Optional environment variables to set in worker process.
412
441
  """
413
442
  self.name = name or "MPWorker"
414
443
  self._sys_path = sys_path or []
415
444
  self._lib_path = lib_path
445
+ self._env_vars = env_vars or {}
416
446
  self._process = None
417
447
  self._queue_in = None
418
448
  self._queue_out = None
@@ -481,7 +511,7 @@ class MPWorker(Worker):
481
511
  self._queue_out = ctx.Queue()
482
512
  self._process = ctx.Process(
483
513
  target=_worker_loop,
484
- args=(self._queue_in, self._queue_out, self._sys_path, self._lib_path),
514
+ args=(self._queue_in, self._queue_out, self._sys_path, self._lib_path, self._env_vars),
485
515
  daemon=True,
486
516
  )
487
517
  self._process.start()
File without changes
File without changes
File without changes