comfy-env 0.1.3__tar.gz → 0.1.4__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.1.3 → comfy_env-0.1.4}/PKG-INFO +1 -1
- {comfy_env-0.1.3 → comfy_env-0.1.4}/pyproject.toml +1 -1
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/pixi/core.py +86 -19
- {comfy_env-0.1.3 → comfy_env-0.1.4}/.github/workflows/ci.yml +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/.github/workflows/publish.yml +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/.gitignore +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/LICENSE +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/README.md +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/__init__.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/cli.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/config/__init__.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/config/parser.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/config/types.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/errors.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/install.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/isolation/__init__.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/isolation/wrap.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/nodes.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/pixi/__init__.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/pixi/cuda_detection.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/pixi/platform/__init__.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/pixi/platform/base.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/pixi/platform/darwin.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/pixi/platform/linux.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/pixi/platform/windows.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/pixi/resolver.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/prestartup.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/templates/comfy-env-instructions.txt +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/templates/comfy-env.toml +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/workers/__init__.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/workers/base.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/workers/mp.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/src/comfy_env/workers/subprocess.py +0 -0
- {comfy_env-0.1.3 → comfy_env-0.1.4}/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.
|
|
3
|
+
Version: 0.1.4
|
|
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
|
|
@@ -9,10 +9,12 @@ See: https://pixi.sh/
|
|
|
9
9
|
|
|
10
10
|
import copy
|
|
11
11
|
import platform
|
|
12
|
+
import re
|
|
12
13
|
import shutil
|
|
13
14
|
import stat
|
|
14
15
|
import subprocess
|
|
15
16
|
import sys
|
|
17
|
+
import urllib.request
|
|
16
18
|
from pathlib import Path
|
|
17
19
|
from typing import Any, Callable, Dict, List, Optional
|
|
18
20
|
|
|
@@ -28,15 +30,9 @@ PIXI_URLS = {
|
|
|
28
30
|
("Windows", "AMD64"): "https://github.com/prefix-dev/pixi/releases/latest/download/pixi-x86_64-pc-windows-msvc.exe",
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
# CUDA wheels index
|
|
33
|
+
# CUDA wheels index (includes flash-attn, PyG packages, and custom wheels)
|
|
32
34
|
CUDA_WHEELS_INDEX = "https://pozzettiandrea.github.io/cuda-wheels/"
|
|
33
35
|
|
|
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
|
-
|
|
40
36
|
# CUDA version -> PyTorch version mapping
|
|
41
37
|
CUDA_TORCH_MAP = {
|
|
42
38
|
"12.8": "2.8",
|
|
@@ -44,19 +40,87 @@ CUDA_TORCH_MAP = {
|
|
|
44
40
|
"12.1": "2.4",
|
|
45
41
|
}
|
|
46
42
|
|
|
43
|
+
def find_matching_wheel(package: str, torch_version: str, cuda_version: str) -> Optional[str]:
|
|
44
|
+
"""
|
|
45
|
+
Query cuda-wheels index to find a wheel matching the CUDA/torch version.
|
|
46
|
+
Returns the full version spec (e.g., "flash-attn===2.8.3+cu128torch2.8") or None.
|
|
47
|
+
"""
|
|
48
|
+
cuda_short = cuda_version.replace(".", "")[:3] # "12.8" -> "128"
|
|
49
|
+
torch_short = torch_version.replace(".", "")[:2] # "2.8" -> "28"
|
|
50
|
+
|
|
51
|
+
# Try different directory name variants
|
|
52
|
+
pkg_variants = [package, package.replace("-", "_"), package.replace("_", "-")]
|
|
53
|
+
|
|
54
|
+
for pkg_dir in pkg_variants:
|
|
55
|
+
url = f"{CUDA_WHEELS_INDEX}{pkg_dir}/"
|
|
56
|
+
try:
|
|
57
|
+
with urllib.request.urlopen(url, timeout=10) as resp:
|
|
58
|
+
html = resp.read().decode("utf-8")
|
|
59
|
+
except Exception:
|
|
60
|
+
continue
|
|
61
|
+
|
|
62
|
+
# Parse wheel filenames from href attributes
|
|
63
|
+
# Pattern: package_name-version+localversion-cpXX-cpXX-platform.whl
|
|
64
|
+
wheel_pattern = re.compile(
|
|
65
|
+
r'href="[^"]*?([^"/]+\.whl)"',
|
|
66
|
+
re.IGNORECASE
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# Local version patterns to match:
|
|
70
|
+
# flash-attn style: +cu128torch2.8
|
|
71
|
+
# PyG style: +pt28cu128
|
|
72
|
+
local_patterns = [
|
|
73
|
+
f"+cu{cuda_short}torch{torch_version}", # flash-attn style
|
|
74
|
+
f"+pt{torch_short}cu{cuda_short}", # PyG style
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
best_match = None
|
|
78
|
+
best_version = None
|
|
79
|
+
|
|
80
|
+
for match in wheel_pattern.finditer(html):
|
|
81
|
+
wheel_name = match.group(1)
|
|
82
|
+
# URL decode
|
|
83
|
+
wheel_name = wheel_name.replace("%2B", "+")
|
|
84
|
+
|
|
85
|
+
# Check if wheel matches our CUDA/torch version
|
|
86
|
+
for local_pattern in local_patterns:
|
|
87
|
+
if local_pattern in wheel_name:
|
|
88
|
+
# Extract version from wheel name
|
|
89
|
+
# Format: name-version+local-cpXX-cpXX-platform.whl
|
|
90
|
+
parts = wheel_name.split("-")
|
|
91
|
+
if len(parts) >= 2:
|
|
92
|
+
version_part = parts[1] # e.g., "2.8.3+cu128torch2.8"
|
|
93
|
+
if best_version is None or version_part > best_version:
|
|
94
|
+
best_version = version_part
|
|
95
|
+
best_match = f"{package}==={version_part}"
|
|
96
|
+
break
|
|
97
|
+
|
|
98
|
+
if best_match:
|
|
99
|
+
return best_match
|
|
100
|
+
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def get_package_spec(package: str, torch_version: str, cuda_version: str) -> str:
|
|
105
|
+
"""
|
|
106
|
+
Get package spec with local version for CUDA/torch compatibility.
|
|
107
|
+
Queries the index to find matching wheels dynamically.
|
|
108
|
+
"""
|
|
109
|
+
spec = find_matching_wheel(package, torch_version, cuda_version)
|
|
110
|
+
return spec if spec else package
|
|
111
|
+
|
|
47
112
|
|
|
48
113
|
def get_all_find_links(package: str, torch_version: str, cuda_version: str) -> list:
|
|
49
114
|
"""Get all find-links URLs for a CUDA package."""
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
]
|
|
115
|
+
# Try both underscore and hyphen variants since directory naming is inconsistent
|
|
116
|
+
pkg_underscore = package.replace("-", "_")
|
|
117
|
+
pkg_hyphen = package.replace("_", "-")
|
|
118
|
+
urls = [f"{CUDA_WHEELS_INDEX}{package}/"]
|
|
119
|
+
if pkg_underscore != package:
|
|
120
|
+
urls.append(f"{CUDA_WHEELS_INDEX}{pkg_underscore}/")
|
|
121
|
+
if pkg_hyphen != package:
|
|
122
|
+
urls.append(f"{CUDA_WHEELS_INDEX}{pkg_hyphen}/")
|
|
123
|
+
return urls
|
|
60
124
|
|
|
61
125
|
|
|
62
126
|
def get_current_platform() -> str:
|
|
@@ -340,6 +404,7 @@ def pixi_install(
|
|
|
340
404
|
for package in cfg.cuda_packages:
|
|
341
405
|
pip_cmd = [
|
|
342
406
|
str(python_path), "-m", "pip", "install",
|
|
407
|
+
"--no-index", # Only use --find-links, don't query PyPI
|
|
343
408
|
"--no-deps",
|
|
344
409
|
"--no-cache-dir",
|
|
345
410
|
]
|
|
@@ -348,8 +413,10 @@ def pixi_install(
|
|
|
348
413
|
for url in get_all_find_links(package, torch_version, cuda_version):
|
|
349
414
|
pip_cmd.extend(["--find-links", url])
|
|
350
415
|
|
|
351
|
-
|
|
352
|
-
|
|
416
|
+
# Get package spec with local version for CUDA/torch compatibility
|
|
417
|
+
pkg_spec = get_package_spec(package, torch_version, cuda_version)
|
|
418
|
+
log(f" Installing {pkg_spec}")
|
|
419
|
+
pip_cmd.append(pkg_spec)
|
|
353
420
|
result = subprocess.run(pip_cmd, capture_output=True, text=True)
|
|
354
421
|
if result.returncode != 0:
|
|
355
422
|
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
|
|
File without changes
|