comfy-env 0.0.73__tar.gz → 0.0.75__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.0.73 → comfy_env-0.0.75}/PKG-INFO +1 -1
  2. {comfy_env-0.0.73 → comfy_env-0.0.75}/pyproject.toml +1 -1
  3. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/install.py +112 -12
  4. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/core.py +28 -8
  5. {comfy_env-0.0.73 → comfy_env-0.0.75}/.github/workflows/ci.yml +0 -0
  6. {comfy_env-0.0.73 → comfy_env-0.0.75}/.github/workflows/publish.yml +0 -0
  7. {comfy_env-0.0.73 → comfy_env-0.0.75}/.gitignore +0 -0
  8. {comfy_env-0.0.73 → comfy_env-0.0.75}/LICENSE +0 -0
  9. {comfy_env-0.0.73 → comfy_env-0.0.75}/README.md +0 -0
  10. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/__init__.py +0 -0
  11. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/cli.py +0 -0
  12. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/config/__init__.py +0 -0
  13. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/config/parser.py +0 -0
  14. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/config/types.py +0 -0
  15. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/errors.py +0 -0
  16. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/isolation/__init__.py +0 -0
  17. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/isolation/wrap.py +0 -0
  18. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/nodes.py +0 -0
  19. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/__init__.py +0 -0
  20. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/cuda_detection.py +0 -0
  21. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/platform/__init__.py +0 -0
  22. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/platform/base.py +0 -0
  23. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/platform/darwin.py +0 -0
  24. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/platform/linux.py +0 -0
  25. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/platform/windows.py +0 -0
  26. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/resolver.py +0 -0
  27. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/prestartup.py +0 -0
  28. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/templates/comfy-env-instructions.txt +0 -0
  29. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/templates/comfy-env.toml +0 -0
  30. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/workers/__init__.py +0 -0
  31. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/workers/base.py +0 -0
  32. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/workers/mp.py +0 -0
  33. {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/workers/subprocess.py +0 -0
  34. {comfy_env-0.0.73 → comfy_env-0.0.75}/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.0.73
3
+ Version: 0.0.75
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.0.73"
3
+ version = "0.0.75"
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"}
@@ -59,6 +59,10 @@ def install(
59
59
  if cfg.apt_packages:
60
60
  _install_apt_packages(cfg.apt_packages, log, dry_run)
61
61
 
62
+ # Set persistent env vars (for OpenMP settings, etc.)
63
+ if cfg.env_vars:
64
+ _set_persistent_env_vars(cfg.env_vars, log, dry_run)
65
+
62
66
  # Install node dependencies
63
67
  if cfg.node_reqs:
64
68
  _install_node_dependencies(cfg.node_reqs, node_dir, log, dry_run)
@@ -117,20 +121,116 @@ def _install_apt_packages(
117
121
  if result.returncode != 0:
118
122
  log(f"[apt] Warning: apt-get update failed: {result.stderr.strip()}")
119
123
 
120
- # Run apt-get install
121
- log(f"[apt] Installing packages...")
122
- result = subprocess.run(
123
- prefix + ["apt-get", "install", "-y"] + packages,
124
- capture_output=True,
125
- text=True,
126
- )
124
+ # Install each package individually (some may not exist on all distros)
125
+ log("[apt] Installing packages...")
126
+ installed = []
127
+ skipped = []
128
+ for pkg in packages:
129
+ result = subprocess.run(
130
+ prefix + ["apt-get", "install", "-y", pkg],
131
+ capture_output=True,
132
+ text=True,
133
+ )
134
+ if result.returncode == 0:
135
+ installed.append(pkg)
136
+ log(f" [apt] Installed {pkg}")
137
+ else:
138
+ skipped.append(pkg)
139
+ log(f" [apt] Skipped {pkg} (not available)")
140
+
141
+ if installed:
142
+ log(f"[apt] Installed {len(installed)} package(s)")
143
+ if skipped:
144
+ log(f"[apt] Skipped {len(skipped)} unavailable package(s)")
145
+
146
+
147
+ def _set_persistent_env_vars(
148
+ env_vars: dict,
149
+ log: Callable[[str], None],
150
+ dry_run: bool,
151
+ ) -> None:
152
+ """Set env vars permanently (survives restarts)."""
153
+ import os
154
+ import platform
155
+ import subprocess
156
+ from pathlib import Path
157
+
158
+ if not env_vars:
159
+ return
160
+
161
+ system = platform.system()
162
+ log(f"\n[env] Setting {len(env_vars)} persistent environment variable(s)...")
127
163
 
128
- if result.returncode == 0:
129
- log("[apt] System packages installed successfully!")
164
+ for key, value in env_vars.items():
165
+ log(f" - {key}={value}")
166
+
167
+ if dry_run:
168
+ log(" (dry run - no changes made)")
169
+ return
170
+
171
+ if system == "Windows":
172
+ # Windows: use setx (writes to registry)
173
+ for key, value in env_vars.items():
174
+ result = subprocess.run(
175
+ ["setx", key, value],
176
+ capture_output=True, text=True
177
+ )
178
+ if result.returncode == 0:
179
+ log(f" [env] Set {key} (Windows registry)")
180
+ else:
181
+ log(f" [env] Warning: Failed to set {key}: {result.stderr.strip()}")
182
+ log("[env] Restart terminal/ComfyUI for changes to take effect")
183
+
184
+ elif system == "Darwin": # macOS
185
+ # macOS: launchctl for GUI apps + zshrc for terminal
186
+ for key, value in env_vars.items():
187
+ subprocess.run(["launchctl", "setenv", key, value], capture_output=True)
188
+ log(f" [env] Set {key} (launchctl)")
189
+
190
+ # Also add to zshrc for terminal (zsh is default on macOS)
191
+ _add_to_shell_profile(env_vars, log)
192
+
193
+ else: # Linux
194
+ _add_to_shell_profile(env_vars, log)
195
+
196
+
197
+ def _add_to_shell_profile(
198
+ env_vars: dict,
199
+ log: Callable[[str], None],
200
+ ) -> None:
201
+ """Add env vars to shell profile (Linux/macOS)."""
202
+ import os
203
+ from pathlib import Path
204
+
205
+ # Determine shell profile
206
+ shell = os.environ.get("SHELL", "/bin/bash")
207
+ if "zsh" in shell:
208
+ rc_file = Path.home() / ".zshrc"
209
+ else:
210
+ rc_file = Path.home() / ".bashrc"
211
+
212
+ profile_file = Path.home() / ".comfy-env-profile"
213
+
214
+ # Write env vars to our dedicated file
215
+ with open(profile_file, "w") as f:
216
+ f.write("# Generated by comfy-env - do not edit manually\n")
217
+ for key, value in env_vars.items():
218
+ f.write(f'export {key}="{value}"\n')
219
+ log(f" [env] Wrote {profile_file}")
220
+
221
+ # Add source line to shell rc (only once)
222
+ source_line = f'source "{profile_file}"'
223
+ existing = rc_file.read_text() if rc_file.exists() else ""
224
+
225
+ if source_line not in existing and str(profile_file) not in existing:
226
+ with open(rc_file, "a") as f:
227
+ f.write(f'\n# comfy-env environment variables\n')
228
+ f.write(f'{source_line}\n')
229
+ log(f" [env] Added source line to {rc_file}")
130
230
  else:
131
- log(f"[apt] Warning: Installation failed: {result.stderr.strip()}")
132
- log(f"[apt] You may need to install manually:")
133
- log(f" sudo apt-get install -y {' '.join(packages)}")
231
+ log(f" [env] Already configured in {rc_file}")
232
+
233
+ log("[env] Restart terminal/ComfyUI for changes to take effect")
134
234
 
135
235
 
136
236
  def _install_node_dependencies(
@@ -31,6 +31,12 @@ PIXI_URLS = {
31
31
  # CUDA wheels index
32
32
  CUDA_WHEELS_INDEX = "https://pozzettiandrea.github.io/cuda-wheels/"
33
33
 
34
+ # Flash attention pre-built wheels (mjun0812)
35
+ FLASH_ATTN_INDEX = "https://github.com/mjun0812/flash-attention-prebuild-wheels/releases/expanded_assets/v0.7.16"
36
+
37
+ # PyTorch Geometric wheels index
38
+ PYG_WHEELS_INDEX = "https://data.pyg.org/whl/"
39
+
34
40
  # CUDA version -> PyTorch version mapping
35
41
  CUDA_TORCH_MAP = {
36
42
  "12.8": "2.8",
@@ -39,6 +45,20 @@ CUDA_TORCH_MAP = {
39
45
  }
40
46
 
41
47
 
48
+ def get_all_find_links(package: str, torch_version: str, cuda_version: str) -> list:
49
+ """Get all find-links URLs for a CUDA package."""
50
+ cuda_short = cuda_version.replace(".", "")[:3]
51
+
52
+ return [
53
+ # cuda-wheels index (package-specific page)
54
+ f"{CUDA_WHEELS_INDEX}{package}/",
55
+ # flash-attn GitHub releases
56
+ FLASH_ATTN_INDEX,
57
+ # PyG index (torch version specific)
58
+ f"{PYG_WHEELS_INDEX}torch-{torch_version}.0+cu{cuda_short}.html",
59
+ ]
60
+
61
+
42
62
  def get_current_platform() -> str:
43
63
  """Get the current platform string for pixi."""
44
64
  if sys.platform == "linux":
@@ -310,7 +330,7 @@ def pixi_install(
310
330
  log(f"pixi install failed:\n{result.stderr}")
311
331
  raise RuntimeError(f"pixi install failed: {result.stderr}")
312
332
 
313
- # Install CUDA packages with --no-index --find-links (bypasses PyPI completely)
333
+ # Install CUDA packages with --find-links (searches all known sources)
314
334
  if cfg.cuda_packages and cuda_version:
315
335
  log(f"Installing CUDA packages: {cfg.cuda_packages}")
316
336
  python_path = get_pixi_python(node_dir)
@@ -318,18 +338,18 @@ def pixi_install(
318
338
  raise RuntimeError("Could not find Python in pixi environment")
319
339
 
320
340
  for package in cfg.cuda_packages:
321
- # Each package has its own find-links page at CUDA_WHEELS_INDEX/<package>/
322
- find_links_url = f"{CUDA_WHEELS_INDEX}{package}/"
323
- log(f" Installing {package} from {find_links_url}")
324
-
325
341
  pip_cmd = [
326
342
  str(python_path), "-m", "pip", "install",
327
- "--no-index",
328
343
  "--no-deps",
329
344
  "--no-cache-dir",
330
- "--find-links", find_links_url,
331
- package,
332
345
  ]
346
+
347
+ # Add all find-links sources
348
+ for url in get_all_find_links(package, torch_version, cuda_version):
349
+ pip_cmd.extend(["--find-links", url])
350
+
351
+ log(f" Installing {package}")
352
+ pip_cmd.append(package)
333
353
  result = subprocess.run(pip_cmd, capture_output=True, text=True)
334
354
  if result.returncode != 0:
335
355
  log(f"CUDA package install failed for {package}:\n{result.stderr}")
File without changes
File without changes
File without changes