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.
- {comfy_env-0.0.73 → comfy_env-0.0.75}/PKG-INFO +1 -1
- {comfy_env-0.0.73 → comfy_env-0.0.75}/pyproject.toml +1 -1
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/install.py +112 -12
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/core.py +28 -8
- {comfy_env-0.0.73 → comfy_env-0.0.75}/.github/workflows/ci.yml +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/.github/workflows/publish.yml +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/.gitignore +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/LICENSE +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/README.md +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/__init__.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/cli.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/config/__init__.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/config/parser.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/config/types.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/errors.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/isolation/__init__.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/isolation/wrap.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/nodes.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/__init__.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/cuda_detection.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/platform/__init__.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/platform/base.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/platform/darwin.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/platform/linux.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/platform/windows.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/pixi/resolver.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/prestartup.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/templates/comfy-env-instructions.txt +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/templates/comfy-env.toml +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/workers/__init__.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/workers/base.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/workers/mp.py +0 -0
- {comfy_env-0.0.73 → comfy_env-0.0.75}/src/comfy_env/workers/subprocess.py +0 -0
- {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.
|
|
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
|
|
@@ -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
|
-
#
|
|
121
|
-
log(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
129
|
-
log("
|
|
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"[
|
|
132
|
-
|
|
133
|
-
|
|
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 --
|
|
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
|
|
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
|