comfy-env 0.1.13__py3-none-any.whl → 0.1.15__py3-none-any.whl

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.
@@ -145,15 +145,19 @@ def _find_env_paths(node_dir: Path) -> tuple[Optional[Path], Optional[Path]]:
145
145
  """
146
146
  Find site-packages and lib directories for the isolated environment.
147
147
 
148
+ Fallback order:
149
+ 1. Marker file -> central cache
150
+ 2. _env_<name> (local)
151
+ 3. .pixi/envs/default (old pixi)
152
+ 4. .venv
153
+
148
154
  Returns:
149
155
  (site_packages, lib_dir) - lib_dir is for LD_LIBRARY_PATH
150
156
  """
151
157
  import glob
152
158
 
153
- # Check _env_<name> directory first (new pattern)
154
- env_name = get_env_name(node_dir.name)
155
- env_dir = node_dir / env_name
156
- if env_dir.exists():
159
+ def _get_paths_from_env(env_dir: Path) -> tuple[Optional[Path], Optional[Path]]:
160
+ """Extract site-packages and lib_dir from an env directory."""
157
161
  if sys.platform == "win32":
158
162
  site_packages = env_dir / "Lib" / "site-packages"
159
163
  lib_dir = env_dir / "Library" / "bin"
@@ -163,23 +167,42 @@ def _find_env_paths(node_dir: Path) -> tuple[Optional[Path], Optional[Path]]:
163
167
  site_packages = Path(matches[0]) if matches else None
164
168
  lib_dir = env_dir / "lib"
165
169
  if site_packages and site_packages.exists():
166
- return site_packages, lib_dir if lib_dir.exists() else None
170
+ return site_packages, lib_dir if lib_dir and lib_dir.exists() else None
171
+ return None, None
167
172
 
168
- # Fallback: Check old .pixi/envs/default (for backward compat)
173
+ # 1. Check marker file -> central cache
174
+ marker_path = node_dir / ".comfy-env-marker.toml"
175
+ if marker_path.exists():
176
+ try:
177
+ import tomli
178
+ with open(marker_path, "rb") as f:
179
+ marker = tomli.load(f)
180
+ env_path = marker.get("env", {}).get("path")
181
+ if env_path:
182
+ env_dir = Path(env_path)
183
+ if env_dir.exists():
184
+ result = _get_paths_from_env(env_dir)
185
+ if result[0]:
186
+ return result
187
+ except Exception:
188
+ pass # Fall through to other options
189
+
190
+ # 2. Check _env_<name> directory (local)
191
+ env_name = get_env_name(node_dir.name)
192
+ env_dir = node_dir / env_name
193
+ if env_dir.exists():
194
+ result = _get_paths_from_env(env_dir)
195
+ if result[0]:
196
+ return result
197
+
198
+ # 3. Fallback: Check old .pixi/envs/default (for backward compat)
169
199
  pixi_env = node_dir / ".pixi" / "envs" / "default"
170
200
  if pixi_env.exists():
171
- if sys.platform == "win32":
172
- site_packages = pixi_env / "Lib" / "site-packages"
173
- lib_dir = pixi_env / "Library" / "bin"
174
- else:
175
- pattern = str(pixi_env / "lib" / "python*" / "site-packages")
176
- matches = glob.glob(pattern)
177
- site_packages = Path(matches[0]) if matches else None
178
- lib_dir = pixi_env / "lib"
179
- if site_packages and site_packages.exists():
180
- return site_packages, lib_dir if lib_dir.exists() else None
201
+ result = _get_paths_from_env(pixi_env)
202
+ if result[0]:
203
+ return result
181
204
 
182
- # Check .venv directory
205
+ # 4. Check .venv directory
183
206
  venv_dir = node_dir / ".venv"
184
207
  if venv_dir.exists():
185
208
  if sys.platform == "win32":
@@ -195,19 +218,46 @@ def _find_env_paths(node_dir: Path) -> tuple[Optional[Path], Optional[Path]]:
195
218
 
196
219
 
197
220
  def _find_env_dir(node_dir: Path) -> Optional[Path]:
198
- """Find the environment directory (for cache key)."""
199
- # Check _env_<name> first
221
+ """
222
+ Find the environment directory (for cache key).
223
+
224
+ Fallback order:
225
+ 1. Marker file -> central cache
226
+ 2. _env_<name> (local)
227
+ 3. .pixi/envs/default (old pixi)
228
+ 4. .venv
229
+ """
230
+ # 1. Check marker file -> central cache
231
+ marker_path = node_dir / ".comfy-env-marker.toml"
232
+ if marker_path.exists():
233
+ try:
234
+ import tomli
235
+ with open(marker_path, "rb") as f:
236
+ marker = tomli.load(f)
237
+ env_path = marker.get("env", {}).get("path")
238
+ if env_path:
239
+ env_dir = Path(env_path)
240
+ if env_dir.exists():
241
+ return env_dir
242
+ except Exception:
243
+ pass
244
+
245
+ # 2. Check _env_<name> first
200
246
  env_name = get_env_name(node_dir.name)
201
247
  env_dir = node_dir / env_name
202
248
  if env_dir.exists():
203
249
  return env_dir
204
- # Fallback to old paths
250
+
251
+ # 3. Fallback to old .pixi path
205
252
  pixi_env = node_dir / ".pixi" / "envs" / "default"
206
253
  if pixi_env.exists():
207
254
  return pixi_env
255
+
256
+ # 4. Check .venv
208
257
  venv_dir = node_dir / ".venv"
209
258
  if venv_dir.exists():
210
259
  return venv_dir
260
+
211
261
  return None
212
262
 
213
263
 
@@ -335,6 +385,131 @@ def _wrap_node_class(
335
385
  return cls
336
386
 
337
387
 
388
+ def _is_comfy_env_enabled() -> bool:
389
+ """Check if comfy-env isolation is enabled (default: True)."""
390
+ val = os.environ.get("USE_COMFY_ENV", "1").lower()
391
+ return val not in ("0", "false", "no", "off")
392
+
393
+
394
+ def wrap_nodes() -> None:
395
+ """
396
+ Auto-wrap nodes for isolation. Call from your __init__.py after defining NODE_CLASS_MAPPINGS.
397
+
398
+ Usage:
399
+ from comfy_env import wrap_nodes
400
+ wrap_nodes()
401
+ """
402
+ # Skip if isolation is disabled
403
+ if not _is_comfy_env_enabled():
404
+ print(f"[comfy-env] Isolation disabled, nodes running in main process")
405
+ return
406
+
407
+ # Skip if running inside worker subprocess
408
+ if os.environ.get("COMFYUI_ISOLATION_WORKER") == "1":
409
+ return
410
+
411
+ # Get caller's frame and module
412
+ frame = inspect.stack()[1]
413
+ caller_module = inspect.getmodule(frame.frame)
414
+ if caller_module is None:
415
+ print("[comfy-env] Warning: Could not determine caller module")
416
+ return
417
+
418
+ # Get NODE_CLASS_MAPPINGS from caller's module
419
+ node_class_mappings = getattr(caller_module, "NODE_CLASS_MAPPINGS", None)
420
+ if not node_class_mappings:
421
+ print("[comfy-env] Warning: No NODE_CLASS_MAPPINGS found in caller module")
422
+ return
423
+
424
+ # Get package root directory
425
+ caller_file = Path(frame.filename).resolve()
426
+ package_dir = caller_file.parent
427
+
428
+ # Find all comfy-env.toml files
429
+ config_files = list(package_dir.rglob("comfy-env.toml"))
430
+ if not config_files:
431
+ return # No configs, nothing to wrap
432
+
433
+ # Get ComfyUI base path
434
+ try:
435
+ import folder_paths
436
+ comfyui_base = folder_paths.base_path
437
+ except ImportError:
438
+ comfyui_base = None
439
+
440
+ # Build a map of config_dir -> env info
441
+ config_envs = []
442
+ for config_file in config_files:
443
+ config_dir = config_file.parent
444
+ env_dir = _find_env_dir(config_dir)
445
+ site_packages, lib_dir = _find_env_paths(config_dir)
446
+
447
+ if not env_dir or not site_packages:
448
+ continue
449
+
450
+ # Read env_vars from config
451
+ env_vars = {}
452
+ try:
453
+ import tomli
454
+ with open(config_file, "rb") as f:
455
+ config = tomli.load(f)
456
+ env_vars_data = config.get("env_vars", {})
457
+ env_vars = {str(k): str(v) for k, v in env_vars_data.items()}
458
+ except Exception:
459
+ pass
460
+
461
+ if comfyui_base:
462
+ env_vars["COMFYUI_BASE"] = str(comfyui_base)
463
+
464
+ config_envs.append({
465
+ "config_dir": config_dir,
466
+ "env_dir": env_dir,
467
+ "site_packages": site_packages,
468
+ "lib_dir": lib_dir,
469
+ "env_vars": env_vars,
470
+ })
471
+
472
+ if not config_envs:
473
+ return
474
+
475
+ # Match nodes to configs by checking source file location
476
+ wrapped_count = 0
477
+ for node_name, node_cls in node_class_mappings.items():
478
+ if not hasattr(node_cls, "FUNCTION"):
479
+ continue
480
+
481
+ # Get node's source file
482
+ try:
483
+ source_file = Path(inspect.getfile(node_cls)).resolve()
484
+ except (TypeError, OSError):
485
+ continue
486
+
487
+ # Find which config this node belongs to
488
+ for env_info in config_envs:
489
+ config_dir = env_info["config_dir"]
490
+ try:
491
+ source_file.relative_to(config_dir)
492
+ # Node is under this config dir - wrap it
493
+ sys_path = [str(env_info["site_packages"]), str(config_dir)]
494
+ lib_path = str(env_info["lib_dir"]) if env_info["lib_dir"] else None
495
+
496
+ _wrap_node_class(
497
+ node_cls,
498
+ env_info["env_dir"],
499
+ config_dir,
500
+ sys_path,
501
+ lib_path,
502
+ env_info["env_vars"],
503
+ )
504
+ wrapped_count += 1
505
+ break
506
+ except ValueError:
507
+ continue # Node not under this config dir
508
+
509
+ if wrapped_count > 0:
510
+ print(f"[comfy-env] Wrapped {wrapped_count} nodes for isolation")
511
+
512
+
338
513
  def wrap_isolated_nodes(
339
514
  node_class_mappings: Dict[str, type],
340
515
  nodes_dir: Path,
@@ -369,6 +544,11 @@ def wrap_isolated_nodes(
369
544
  wrap_isolated_nodes(cgal_nodes, Path(__file__).parent / "nodes/cgal")
370
545
  )
371
546
  """
547
+ # Skip if isolation is disabled
548
+ if not _is_comfy_env_enabled():
549
+ print(f"[comfy-env] Isolation disabled, nodes running in main process")
550
+ return node_class_mappings
551
+
372
552
  # Skip if running inside worker subprocess
373
553
  if os.environ.get("COMFYUI_ISOLATION_WORKER") == "1":
374
554
  return node_class_mappings
@@ -391,12 +571,9 @@ def wrap_isolated_nodes(
391
571
  # Read env_vars from comfy-env.toml
392
572
  env_vars = {}
393
573
  try:
394
- if sys.version_info >= (3, 11):
395
- import tomllib
396
- else:
397
- import tomli as tomllib
574
+ import tomli
398
575
  with open(config_file, "rb") as f:
399
- config = tomllib.load(f)
576
+ config = tomli.load(f)
400
577
  env_vars_data = config.get("env_vars", {})
401
578
  env_vars = {str(k): str(v) for k, v in env_vars_data.items()}
402
579
  except Exception:
comfy_env/nodes.py CHANGED
@@ -17,7 +17,7 @@ from pathlib import Path
17
17
  from typing import TYPE_CHECKING, Callable, List, Set
18
18
 
19
19
  if TYPE_CHECKING:
20
- from .config.types import NodeReq
20
+ from .config.parser import NodeReq
21
21
 
22
22
 
23
23
  def normalize_repo_url(repo: str) -> str:
comfy_env/pixi/core.py CHANGED
@@ -18,7 +18,7 @@ import urllib.request
18
18
  from pathlib import Path
19
19
  from typing import Any, Callable, Dict, List, Optional
20
20
 
21
- from ..config.types import ComfyEnvConfig
21
+ from ..config.parser import ComfyEnvConfig
22
22
 
23
23
 
24
24
  # Pixi download URLs by platform
@@ -37,7 +37,6 @@ CUDA_WHEELS_INDEX = "https://pozzettiandrea.github.io/cuda-wheels/"
37
37
  CUDA_TORCH_MAP = {
38
38
  "12.8": "2.8",
39
39
  "12.4": "2.4",
40
- "12.1": "2.4",
41
40
  }
42
41
 
43
42
  def find_wheel_url(
@@ -534,20 +533,55 @@ def pixi_install(
534
533
 
535
534
  log("CUDA packages installed")
536
535
 
537
- # Move environment from .pixi/envs/default to _env_<name>
536
+ # Move environment from .pixi/envs/default to central cache
537
+ from ..cache import (
538
+ get_central_env_path, write_marker, write_env_metadata,
539
+ MARKER_FILE, get_cache_dir
540
+ )
541
+
538
542
  old_env = node_dir / ".pixi" / "envs" / "default"
539
- env_name = get_env_name(node_dir.name)
540
- new_env = node_dir / env_name
543
+ config_path = node_dir / "comfy-env.toml"
544
+
545
+ # Determine the main node directory (for naming)
546
+ # If node_dir is custom_nodes/NodeName/subdir, main_node_dir is custom_nodes/NodeName
547
+ # If node_dir is custom_nodes/NodeName, main_node_dir is custom_nodes/NodeName
548
+ if node_dir.parent.name == "custom_nodes":
549
+ main_node_dir = node_dir
550
+ else:
551
+ # Walk up to find custom_nodes parent
552
+ main_node_dir = node_dir
553
+ for parent in node_dir.parents:
554
+ if parent.parent.name == "custom_nodes":
555
+ main_node_dir = parent
556
+ break
557
+
558
+ # Get central env path
559
+ central_env = get_central_env_path(main_node_dir, config_path)
541
560
 
542
561
  if old_env.exists():
543
- if new_env.exists():
544
- shutil.rmtree(new_env) # Clean old env
545
- shutil.move(str(old_env), str(new_env))
546
- # Clean up .pixi directory (keep pixi.toml and pixi.lock)
562
+ # Ensure cache directory exists
563
+ get_cache_dir()
564
+
565
+ # Remove old central env if exists
566
+ if central_env.exists():
567
+ shutil.rmtree(central_env)
568
+
569
+ # Move to central cache
570
+ shutil.move(str(old_env), str(central_env))
571
+
572
+ # Write marker file in node directory
573
+ write_marker(config_path, central_env)
574
+
575
+ # Write metadata in env for orphan detection
576
+ marker_path = config_path.parent / MARKER_FILE
577
+ write_env_metadata(central_env, marker_path)
578
+
579
+ # Clean up .pixi directory
547
580
  pixi_dir = node_dir / ".pixi"
548
581
  if pixi_dir.exists():
549
582
  shutil.rmtree(pixi_dir)
550
- log(f"Moved environment to {new_env}")
583
+
584
+ log(f"Environment created at: {central_env}")
551
585
 
552
586
  log("Installation complete!")
553
587
  return True
comfy_env/prestartup.py CHANGED
@@ -20,24 +20,16 @@ def get_env_name(dir_name: str) -> str:
20
20
  def _load_env_vars(config_path: str) -> Dict[str, str]:
21
21
  """
22
22
  Load [env_vars] section from comfy-env.toml.
23
-
24
- Uses tomllib (Python 3.11+) or tomli fallback.
25
23
  Returns empty dict if file not found or parsing fails.
26
24
  """
27
25
  if not os.path.exists(config_path):
28
26
  return {}
29
27
 
30
28
  try:
31
- if sys.version_info >= (3, 11):
32
- import tomllib
33
- else:
34
- try:
35
- import tomli as tomllib
36
- except ImportError:
37
- return {}
29
+ import tomli
38
30
 
39
31
  with open(config_path, "rb") as f:
40
- data = tomllib.load(f)
32
+ data = tomli.load(f)
41
33
 
42
34
  env_vars_data = data.get("env_vars", {})
43
35
  return {str(k): str(v) for k, v in env_vars_data.items()}
@@ -95,6 +87,12 @@ def _dedupe_libomp_macos():
95
87
  pass # Permission denied, etc.
96
88
 
97
89
 
90
+ def _is_comfy_env_enabled() -> bool:
91
+ """Check if comfy-env isolation is enabled (default: True)."""
92
+ val = os.environ.get("USE_COMFY_ENV", "1").lower()
93
+ return val not in ("0", "false", "no", "off")
94
+
95
+
98
96
  def setup_env(node_dir: Optional[str] = None) -> None:
99
97
  """
100
98
  Set up environment for pixi conda libraries.
@@ -112,6 +110,10 @@ def setup_env(node_dir: Optional[str] = None) -> None:
112
110
  from comfy_env import setup_env
113
111
  setup_env()
114
112
  """
113
+ # Skip if isolation is disabled
114
+ if not _is_comfy_env_enabled():
115
+ return
116
+
115
117
  # macOS: Dedupe libomp to prevent OpenMP conflicts (torch vs pymeshlab, etc.)
116
118
  _dedupe_libomp_macos()
117
119
 
@@ -127,15 +129,40 @@ def setup_env(node_dir: Optional[str] = None) -> None:
127
129
  for key, value in env_vars.items():
128
130
  os.environ[key] = value
129
131
 
130
- # Check _env_<name> first, then fallback to old .pixi path
131
- env_name = get_env_name(os.path.basename(node_dir))
132
- pixi_env = os.path.join(node_dir, env_name)
133
-
134
- if not os.path.exists(pixi_env):
135
- # Fallback to old .pixi path
136
- pixi_env = os.path.join(node_dir, ".pixi", "envs", "default")
137
- if not os.path.exists(pixi_env):
138
- return # No environment found
132
+ # Resolve environment path with fallback chain:
133
+ # 1. Marker file -> central cache
134
+ # 2. _env_<name> (current local)
135
+ # 3. .pixi/envs/default (old pixi)
136
+ pixi_env = None
137
+
138
+ # 1. Check marker file -> central cache
139
+ marker_path = os.path.join(node_dir, ".comfy-env-marker.toml")
140
+ if os.path.exists(marker_path):
141
+ try:
142
+ import tomli
143
+ with open(marker_path, "rb") as f:
144
+ marker = tomli.load(f)
145
+ env_path = marker.get("env", {}).get("path")
146
+ if env_path and os.path.exists(env_path):
147
+ pixi_env = env_path
148
+ except Exception:
149
+ pass # Fall through to other options
150
+
151
+ # 2. Check _env_<name> (local)
152
+ if not pixi_env:
153
+ env_name = get_env_name(os.path.basename(node_dir))
154
+ local_env = os.path.join(node_dir, env_name)
155
+ if os.path.exists(local_env):
156
+ pixi_env = local_env
157
+
158
+ # 3. Fallback to old .pixi path
159
+ if not pixi_env:
160
+ old_pixi = os.path.join(node_dir, ".pixi", "envs", "default")
161
+ if os.path.exists(old_pixi):
162
+ pixi_env = old_pixi
163
+
164
+ if not pixi_env:
165
+ return # No environment found
139
166
 
140
167
  if sys.platform == "win32":
141
168
  # Windows: add to PATH for DLL loading
@@ -162,3 +189,20 @@ def setup_env(node_dir: Optional[str] = None) -> None:
162
189
 
163
190
  if site_packages and os.path.exists(site_packages) and site_packages not in sys.path:
164
191
  sys.path.insert(0, site_packages)
192
+
193
+
194
+ def copy_files(src, dst, pattern: str = "*") -> None:
195
+ """Copy files matching pattern from src to dst (skip existing)."""
196
+ import shutil
197
+
198
+ src, dst = Path(src), Path(dst)
199
+ if not src.exists():
200
+ return
201
+
202
+ dst.mkdir(parents=True, exist_ok=True)
203
+ for f in src.glob(pattern):
204
+ if f.is_file():
205
+ target = dst / f.relative_to(src)
206
+ target.parent.mkdir(parents=True, exist_ok=True)
207
+ if not target.exists():
208
+ shutil.copy2(f, target)
@@ -440,7 +440,7 @@ def _watchdog():
440
440
  f.flush()
441
441
 
442
442
  # Also print
443
- print(f"\\n=== WATCHDOG TICK {tick} ===", flush=True)
443
+ print(f"\\n=== WATCHDOG TICK {tick} (debug only, don't worry) ===", flush=True)
444
444
  print(dump, flush=True)
445
445
  print("=== END ===\\n", flush=True)
446
446
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comfy-env
3
- Version: 0.1.13
3
+ Version: 0.1.15
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
@@ -19,7 +19,7 @@ Classifier: Programming Language :: Python :: 3.13
19
19
  Requires-Python: >=3.10
20
20
  Requires-Dist: pip>=21.0
21
21
  Requires-Dist: tomli-w>=1.0.0
22
- Requires-Dist: tomli>=2.0.0; python_version < '3.11'
22
+ Requires-Dist: tomli>=2.0.0
23
23
  Requires-Dist: uv>=0.4.0
24
24
  Provides-Extra: dev
25
25
  Requires-Dist: mypy; extra == 'dev'
@@ -0,0 +1,31 @@
1
+ comfy_env/__init__.py,sha256=vtMEMhys8esoSXM3H5pFJGecE_ZoDwPS0foeEzlbmZA,2331
2
+ comfy_env/cache.py,sha256=LnOVGCheF0hM-JZcX_-HD46o_nA7U2SIptdOT1TQkBE,6293
3
+ comfy_env/cli.py,sha256=UJbPbCEKfAAoZ_J0JeUs4jVsWuJ8BeR6CV6XtCSuy1g,12707
4
+ comfy_env/install.py,sha256=nuG3z5V1PQ4IoXKknLfS9sUKAUq0RHcpZp7jvdOTgIY,14853
5
+ comfy_env/nodes.py,sha256=tqMBf3hTjtgbT9sdcUiNnMaiFNPsHWtw79_TgvsrU9Q,5392
6
+ comfy_env/prestartup.py,sha256=Aw8yvmkraP3bRXPTZKOFnhUHLNtGujAZ4aD76nKx6pA,7215
7
+ comfy_env/config/__init__.py,sha256=_udIO2AkntkFfktst1uKqRkLdne1cXf2b0BrErvNT_k,289
8
+ comfy_env/config/parser.py,sha256=B9iK3RQdErAHnmvD_jfZm87u5K5gTnEwFDMdOXil3YM,3458
9
+ comfy_env/isolation/__init__.py,sha256=Fy8A7_5plxcCMFOf00cJlEMbRVu8aKFkTo0Spj31YqI,206
10
+ comfy_env/isolation/wrap.py,sha256=vJz75TtS6NMyfxX_UlqNdZNQQYROHP9KbcghmNIPyFM,20046
11
+ comfy_env/pixi/__init__.py,sha256=BUrq7AQf3WDm0cHWh72B2xZbURNnDu2dCuELWiQCUiM,997
12
+ comfy_env/pixi/core.py,sha256=LY2wrvMNqO-cp9MOgixvpe1mJKtGK3U311-0rbURTBo,21770
13
+ comfy_env/pixi/cuda_detection.py,sha256=sqB3LjvGNdV4eFqiARQGfyecBM3ZiUmeh6nG0YCRYQw,9751
14
+ comfy_env/pixi/resolver.py,sha256=U_A8rBDxCj4gUlJt2YJQniP4cCKqxJEiVFgXOoH7vM8,6339
15
+ comfy_env/pixi/platform/__init__.py,sha256=Nb5MPZIEeanSMEWwqU4p4bnEKTJn1tWcwobnhq9x9IY,614
16
+ comfy_env/pixi/platform/base.py,sha256=iS0ptTTVjXRwPU4qWUdvHI7jteuzxGSjWr5BUQ7hGiU,2453
17
+ comfy_env/pixi/platform/darwin.py,sha256=HK3VkLT6DfesAnIXwx2IaUFHTBclF0xTQnC7azWY6Kc,1552
18
+ comfy_env/pixi/platform/linux.py,sha256=xLp8FEbFqZLQrzIZBI9z3C4g23Ab1ASTHLsXDzsdCoA,2062
19
+ comfy_env/pixi/platform/windows.py,sha256=FCOCgpzGzorY9-HueMlJUR8DxM2eH-cj9iZk6K026Is,10891
20
+ comfy_env/templates/comfy-env-instructions.txt,sha256=ve1RAthW7ouumU9h6DM7mIRX1MS8_Tyonq2U4tcrFu8,1031
21
+ comfy_env/templates/comfy-env.toml,sha256=ROIqi4BlPL1MEdL1VgebfTHpdwPNYGHwWeigI9Kw-1I,4831
22
+ comfy_env/workers/__init__.py,sha256=TMVG55d2XLP1mJ3x1d16H0SBDJZtk2kMC5P4HLk9TrA,1073
23
+ comfy_env/workers/base.py,sha256=4ZYTaQ4J0kBHCoO_OfZnsowm4rJCoqinZUaOtgkOPbw,2307
24
+ comfy_env/workers/mp.py,sha256=R0XWsiHv8gswxa_-iNHU14o_9Og0RFG0QnY9DRZzn2c,34060
25
+ comfy_env/workers/subprocess.py,sha256=FvhEWilFWkjYNVDm7mmbFmXiSYB7eT5Tl2uvJ_23qnc,57154
26
+ comfy_env/workers/tensor_utils.py,sha256=TCuOAjJymrSbkgfyvcKtQ_KbVWTqSwP9VH_bCaFLLq8,6409
27
+ comfy_env-0.1.15.dist-info/METADATA,sha256=HMJQ4qs9ObD6YpTGffqmUACR67_kzcWv392WpdNASzc,6946
28
+ comfy_env-0.1.15.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
29
+ comfy_env-0.1.15.dist-info/entry_points.txt,sha256=J4fXeqgxU_YenuW_Zxn_pEL7J-3R0--b6MS5t0QmAr0,49
30
+ comfy_env-0.1.15.dist-info/licenses/LICENSE,sha256=E68QZMMpW4P2YKstTZ3QU54HRQO8ecew09XZ4_Vn870,1093
31
+ comfy_env-0.1.15.dist-info/RECORD,,
comfy_env/config/types.py DELETED
@@ -1,70 +0,0 @@
1
- """Configuration types for comfy-env."""
2
-
3
- from dataclasses import dataclass, field
4
- from typing import Any, Dict, List, Optional
5
-
6
-
7
- @dataclass
8
- class NodeReq:
9
- """A node dependency (another ComfyUI custom node)."""
10
- name: str
11
- repo: str # GitHub repo, e.g., "owner/repo"
12
-
13
-
14
- @dataclass
15
- class ComfyEnvConfig:
16
- """
17
- Configuration from comfy-env.toml.
18
-
19
- comfy-env.toml is a superset of pixi.toml. Custom sections we handle:
20
- - python = "3.11" - Python version for isolated envs
21
- - [cuda] packages = [...] - CUDA packages (triggers find-links + PyTorch detection)
22
- - [node_reqs] - Other ComfyUI nodes to clone
23
-
24
- Everything else passes through to pixi.toml directly:
25
- - [dependencies] - conda packages
26
- - [pypi-dependencies] - pip packages
27
- - [target.linux-64.pypi-dependencies] - platform-specific deps
28
- - Any other pixi.toml syntax
29
-
30
- Example config:
31
- python = "3.11"
32
-
33
- [cuda]
34
- packages = ["cumesh"]
35
-
36
- [dependencies]
37
- mesalib = "*"
38
- cgal = "*"
39
-
40
- [pypi-dependencies]
41
- numpy = ">=1.21.0,<2"
42
- trimesh = { version = ">=4.0.0", extras = ["easy"] }
43
-
44
- [target.linux-64.pypi-dependencies]
45
- embreex = "*"
46
-
47
- [node_reqs]
48
- SomeNode = "owner/repo"
49
- """
50
- # python = "3.11" - Python version (for isolated envs)
51
- python: Optional[str] = None
52
-
53
- # [cuda] - CUDA packages (installed via find-links index)
54
- cuda_packages: List[str] = field(default_factory=list)
55
-
56
- # [apt] - System packages to install via apt (Linux only)
57
- apt_packages: List[str] = field(default_factory=list)
58
-
59
- # [env_vars] - Environment variables to set early (in prestartup)
60
- env_vars: Dict[str, str] = field(default_factory=dict)
61
-
62
- # [node_reqs] - other ComfyUI nodes to clone
63
- node_reqs: List[NodeReq] = field(default_factory=list)
64
-
65
- # Everything else from comfy-env.toml passes through to pixi.toml
66
- pixi_passthrough: Dict[str, Any] = field(default_factory=dict)
67
-
68
- @property
69
- def has_cuda(self) -> bool:
70
- return bool(self.cuda_packages)