comfy-env 0.0.65__py3-none-any.whl → 0.0.67__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.
- comfy_env/__init__.py +68 -122
- comfy_env/cli.py +74 -204
- comfy_env/config/__init__.py +19 -0
- comfy_env/config/parser.py +151 -0
- comfy_env/config/types.py +64 -0
- comfy_env/install.py +83 -361
- comfy_env/isolation/__init__.py +9 -0
- comfy_env/isolation/wrap.py +351 -0
- comfy_env/nodes.py +2 -2
- comfy_env/pixi/__init__.py +48 -0
- comfy_env/pixi/core.py +356 -0
- comfy_env/{resolver.py → pixi/resolver.py} +1 -14
- comfy_env/prestartup.py +60 -0
- comfy_env/templates/comfy-env-instructions.txt +30 -87
- comfy_env/templates/comfy-env.toml +69 -128
- comfy_env/workers/__init__.py +21 -32
- comfy_env/workers/base.py +1 -1
- comfy_env/workers/{torch_mp.py → mp.py} +47 -14
- comfy_env/workers/{venv.py → subprocess.py} +397 -443
- {comfy_env-0.0.65.dist-info → comfy_env-0.0.67.dist-info}/METADATA +23 -92
- comfy_env-0.0.67.dist-info/RECORD +32 -0
- comfy_env/decorator.py +0 -700
- comfy_env/env/__init__.py +0 -46
- comfy_env/env/config.py +0 -191
- comfy_env/env/config_file.py +0 -706
- comfy_env/env/manager.py +0 -636
- comfy_env/env/security.py +0 -267
- comfy_env/ipc/__init__.py +0 -55
- comfy_env/ipc/bridge.py +0 -476
- comfy_env/ipc/protocol.py +0 -265
- comfy_env/ipc/tensor.py +0 -371
- comfy_env/ipc/torch_bridge.py +0 -401
- comfy_env/ipc/transport.py +0 -318
- comfy_env/ipc/worker.py +0 -221
- comfy_env/isolation.py +0 -310
- comfy_env/pixi.py +0 -760
- comfy_env/registry.py +0 -130
- comfy_env/stub_imports.py +0 -270
- comfy_env/stubs/__init__.py +0 -1
- comfy_env/stubs/comfy/__init__.py +0 -6
- comfy_env/stubs/comfy/model_management.py +0 -58
- comfy_env/stubs/comfy/utils.py +0 -29
- comfy_env/stubs/folder_paths.py +0 -71
- comfy_env/wheel_sources.yml +0 -141
- comfy_env/workers/pool.py +0 -241
- comfy_env-0.0.65.dist-info/RECORD +0 -48
- /comfy_env/{env/cuda_gpu_detection.py → pixi/cuda_detection.py} +0 -0
- /comfy_env/{env → pixi}/platform/__init__.py +0 -0
- /comfy_env/{env → pixi}/platform/base.py +0 -0
- /comfy_env/{env → pixi}/platform/darwin.py +0 -0
- /comfy_env/{env → pixi}/platform/linux.py +0 -0
- /comfy_env/{env → pixi}/platform/windows.py +0 -0
- {comfy_env-0.0.65.dist-info → comfy_env-0.0.67.dist-info}/WHEEL +0 -0
- {comfy_env-0.0.65.dist-info → comfy_env-0.0.67.dist-info}/entry_points.txt +0 -0
- {comfy_env-0.0.65.dist-info → comfy_env-0.0.67.dist-info}/licenses/LICENSE +0 -0
comfy_env/__init__.py
CHANGED
|
@@ -1,55 +1,62 @@
|
|
|
1
|
+
"""
|
|
2
|
+
comfy-env: Environment management for ComfyUI custom nodes.
|
|
3
|
+
|
|
4
|
+
All dependencies go through pixi for unified management.
|
|
5
|
+
|
|
6
|
+
Main APIs:
|
|
7
|
+
- install(): Install dependencies from comfy-env.toml
|
|
8
|
+
- wrap_isolated_nodes(): Wrap nodes for subprocess isolation
|
|
9
|
+
"""
|
|
10
|
+
|
|
1
11
|
from importlib.metadata import version, PackageNotFoundError
|
|
2
12
|
|
|
3
13
|
try:
|
|
4
14
|
__version__ = version("comfy-env")
|
|
5
15
|
except PackageNotFoundError:
|
|
6
|
-
__version__ = "0.0.0-dev"
|
|
16
|
+
__version__ = "0.0.0-dev"
|
|
7
17
|
|
|
8
|
-
|
|
9
|
-
from .
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
# Config types and parsing
|
|
19
|
+
from .config import (
|
|
20
|
+
ComfyEnvConfig,
|
|
21
|
+
NodeReq,
|
|
12
22
|
load_config,
|
|
13
23
|
discover_config,
|
|
14
|
-
|
|
24
|
+
CONFIG_FILE_NAME,
|
|
15
25
|
)
|
|
16
|
-
from .env.manager import IsolatedEnvManager
|
|
17
|
-
from .env.cuda_gpu_detection import (
|
|
18
|
-
GPUInfo,
|
|
19
|
-
CUDAEnvironment,
|
|
20
|
-
detect_cuda_environment,
|
|
21
|
-
detect_cuda_version,
|
|
22
|
-
detect_gpu_info,
|
|
23
|
-
detect_gpus,
|
|
24
|
-
get_gpu_summary,
|
|
25
|
-
get_recommended_cuda_version,
|
|
26
|
-
)
|
|
27
|
-
from .env.security import (
|
|
28
|
-
normalize_env_name,
|
|
29
|
-
validate_dependency,
|
|
30
|
-
validate_dependencies,
|
|
31
|
-
validate_path_within_root,
|
|
32
|
-
validate_wheel_url,
|
|
33
|
-
)
|
|
34
|
-
from .ipc.bridge import WorkerBridge
|
|
35
|
-
from .ipc.worker import BaseWorker, register
|
|
36
|
-
from .decorator import isolated, shutdown_all_processes
|
|
37
|
-
from .isolation import enable_isolation
|
|
38
|
-
from .stub_imports import setup_isolated_imports, cleanup_stubs
|
|
39
|
-
|
|
40
|
-
# New in-place installation API
|
|
41
|
-
from .install import install, verify_installation
|
|
42
|
-
from .resolver import RuntimeEnv
|
|
43
26
|
|
|
44
|
-
# Pixi integration
|
|
27
|
+
# Pixi integration
|
|
45
28
|
from .pixi import (
|
|
46
29
|
ensure_pixi,
|
|
47
30
|
get_pixi_path,
|
|
48
|
-
pixi_install,
|
|
49
|
-
create_pixi_toml,
|
|
50
31
|
get_pixi_python,
|
|
51
32
|
pixi_run,
|
|
33
|
+
pixi_install,
|
|
34
|
+
CUDA_WHEELS_INDEX,
|
|
35
|
+
detect_cuda_version,
|
|
36
|
+
detect_cuda_environment,
|
|
37
|
+
get_recommended_cuda_version,
|
|
38
|
+
GPUInfo,
|
|
39
|
+
CUDAEnvironment,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Workers
|
|
43
|
+
from .workers import (
|
|
44
|
+
Worker,
|
|
45
|
+
WorkerError,
|
|
46
|
+
MPWorker,
|
|
47
|
+
SubprocessWorker,
|
|
52
48
|
)
|
|
49
|
+
|
|
50
|
+
# Isolation
|
|
51
|
+
from .isolation import wrap_isolated_nodes
|
|
52
|
+
|
|
53
|
+
# Install API
|
|
54
|
+
from .install import install, verify_installation
|
|
55
|
+
|
|
56
|
+
# Prestartup helpers
|
|
57
|
+
from .prestartup import setup_env
|
|
58
|
+
|
|
59
|
+
# Errors
|
|
53
60
|
from .errors import (
|
|
54
61
|
EnvManagerError,
|
|
55
62
|
ConfigError,
|
|
@@ -59,43 +66,38 @@ from .errors import (
|
|
|
59
66
|
InstallError,
|
|
60
67
|
)
|
|
61
68
|
|
|
62
|
-
# New workers module (recommended API)
|
|
63
|
-
from .workers import (
|
|
64
|
-
Worker,
|
|
65
|
-
TorchMPWorker,
|
|
66
|
-
VenvWorker,
|
|
67
|
-
WorkerPool,
|
|
68
|
-
get_worker,
|
|
69
|
-
register_worker,
|
|
70
|
-
shutdown_workers,
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
# TorchBridge is optional (requires PyTorch)
|
|
74
|
-
try:
|
|
75
|
-
from .ipc.torch_bridge import TorchBridge, TorchWorker
|
|
76
|
-
_TORCH_AVAILABLE = True
|
|
77
|
-
except ImportError:
|
|
78
|
-
_TORCH_AVAILABLE = False
|
|
79
|
-
|
|
80
|
-
# PersistentVenvWorker requires the ipc.transport module
|
|
81
|
-
try:
|
|
82
|
-
from .workers.venv import PersistentVenvWorker
|
|
83
|
-
_PERSISTENT_AVAILABLE = True
|
|
84
|
-
except ImportError:
|
|
85
|
-
_PERSISTENT_AVAILABLE = False
|
|
86
|
-
|
|
87
69
|
__all__ = [
|
|
88
|
-
#
|
|
70
|
+
# Install API
|
|
89
71
|
"install",
|
|
90
72
|
"verify_installation",
|
|
91
|
-
|
|
92
|
-
|
|
73
|
+
# Prestartup
|
|
74
|
+
"setup_env",
|
|
75
|
+
# Isolation
|
|
76
|
+
"wrap_isolated_nodes",
|
|
77
|
+
# Config
|
|
78
|
+
"ComfyEnvConfig",
|
|
79
|
+
"NodeReq",
|
|
80
|
+
"load_config",
|
|
81
|
+
"discover_config",
|
|
82
|
+
"CONFIG_FILE_NAME",
|
|
83
|
+
# Pixi
|
|
93
84
|
"ensure_pixi",
|
|
94
85
|
"get_pixi_path",
|
|
95
|
-
"pixi_install",
|
|
96
|
-
"create_pixi_toml",
|
|
97
86
|
"get_pixi_python",
|
|
98
87
|
"pixi_run",
|
|
88
|
+
"pixi_install",
|
|
89
|
+
"CUDA_WHEELS_INDEX",
|
|
90
|
+
# CUDA detection
|
|
91
|
+
"detect_cuda_version",
|
|
92
|
+
"detect_cuda_environment",
|
|
93
|
+
"get_recommended_cuda_version",
|
|
94
|
+
"GPUInfo",
|
|
95
|
+
"CUDAEnvironment",
|
|
96
|
+
# Workers
|
|
97
|
+
"Worker",
|
|
98
|
+
"WorkerError",
|
|
99
|
+
"MPWorker",
|
|
100
|
+
"SubprocessWorker",
|
|
99
101
|
# Errors
|
|
100
102
|
"EnvManagerError",
|
|
101
103
|
"ConfigError",
|
|
@@ -103,60 +105,4 @@ __all__ = [
|
|
|
103
105
|
"DependencyError",
|
|
104
106
|
"CUDANotFoundError",
|
|
105
107
|
"InstallError",
|
|
106
|
-
# Workers API (recommended for isolation)
|
|
107
|
-
"Worker",
|
|
108
|
-
"TorchMPWorker",
|
|
109
|
-
"VenvWorker",
|
|
110
|
-
"WorkerPool",
|
|
111
|
-
"get_worker",
|
|
112
|
-
"register_worker",
|
|
113
|
-
"shutdown_workers",
|
|
114
|
-
# Environment & Config
|
|
115
|
-
"IsolatedEnv",
|
|
116
|
-
"EnvManagerConfig",
|
|
117
|
-
"LocalConfig",
|
|
118
|
-
"NodeReq",
|
|
119
|
-
"CondaConfig",
|
|
120
|
-
"IsolatedEnvManager",
|
|
121
|
-
# Config file loading
|
|
122
|
-
"load_env_from_file",
|
|
123
|
-
"discover_env_config",
|
|
124
|
-
"load_config",
|
|
125
|
-
"discover_config",
|
|
126
|
-
"CONFIG_FILE_NAMES",
|
|
127
|
-
# Detection
|
|
128
|
-
"GPUInfo",
|
|
129
|
-
"CUDAEnvironment",
|
|
130
|
-
"detect_cuda_environment",
|
|
131
|
-
"detect_cuda_version",
|
|
132
|
-
"detect_gpu_info",
|
|
133
|
-
"detect_gpus",
|
|
134
|
-
"get_gpu_summary",
|
|
135
|
-
"get_recommended_cuda_version",
|
|
136
|
-
# Security validation
|
|
137
|
-
"normalize_env_name",
|
|
138
|
-
"validate_dependency",
|
|
139
|
-
"validate_dependencies",
|
|
140
|
-
"validate_path_within_root",
|
|
141
|
-
"validate_wheel_url",
|
|
142
|
-
# Legacy IPC (subprocess-based)
|
|
143
|
-
"WorkerBridge",
|
|
144
|
-
"BaseWorker",
|
|
145
|
-
"register",
|
|
146
|
-
# Legacy Decorator API
|
|
147
|
-
"isolated",
|
|
148
|
-
"shutdown_all_processes",
|
|
149
|
-
# New: Enable isolation for entire node pack
|
|
150
|
-
"enable_isolation",
|
|
151
|
-
# Import stubbing for isolated packages
|
|
152
|
-
"setup_isolated_imports",
|
|
153
|
-
"cleanup_stubs",
|
|
154
108
|
]
|
|
155
|
-
|
|
156
|
-
# Add torch-based IPC if available
|
|
157
|
-
if _TORCH_AVAILABLE:
|
|
158
|
-
__all__ += ["TorchBridge", "TorchWorker"]
|
|
159
|
-
|
|
160
|
-
# Add PersistentVenvWorker if available
|
|
161
|
-
if _PERSISTENT_AVAILABLE:
|
|
162
|
-
__all__ += ["PersistentVenvWorker"]
|
comfy_env/cli.py
CHANGED
|
@@ -2,24 +2,21 @@
|
|
|
2
2
|
CLI for comfy-env.
|
|
3
3
|
|
|
4
4
|
Provides the `comfy-env` command with subcommands:
|
|
5
|
+
- init: Create a default comfy-env.toml
|
|
6
|
+
- generate: Generate pixi.toml from comfy-env.toml
|
|
5
7
|
- install: Install dependencies from config
|
|
6
8
|
- info: Show runtime environment information
|
|
7
|
-
- resolve: Show resolved wheel URLs
|
|
8
9
|
- doctor: Verify installation
|
|
9
|
-
- list-packages: Show all packages in the built-in registry
|
|
10
10
|
|
|
11
11
|
Usage:
|
|
12
|
-
comfy-env
|
|
12
|
+
comfy-env init ---> creates template comfy-env.toml
|
|
13
|
+
comfy-env generate nodes/cgal/comfy-env.toml ---> nodes/cgal/pixi.toml
|
|
14
|
+
comfy-env install ---> installs from comfy
|
|
13
15
|
comfy-env install --dry-run
|
|
14
16
|
|
|
15
17
|
comfy-env info
|
|
16
18
|
|
|
17
|
-
comfy-env resolve nvdiffrast==0.4.0
|
|
18
|
-
comfy-env resolve --all
|
|
19
|
-
|
|
20
19
|
comfy-env doctor
|
|
21
|
-
|
|
22
|
-
comfy-env list-packages
|
|
23
20
|
"""
|
|
24
21
|
|
|
25
22
|
import argparse
|
|
@@ -54,6 +51,23 @@ def main(args: Optional[List[str]] = None) -> int:
|
|
|
54
51
|
help="Overwrite existing config file",
|
|
55
52
|
)
|
|
56
53
|
|
|
54
|
+
# generate command
|
|
55
|
+
generate_parser = subparsers.add_parser(
|
|
56
|
+
"generate",
|
|
57
|
+
help="Generate pixi.toml from comfy-env.toml",
|
|
58
|
+
description="Parse comfy-env.toml and generate a pixi.toml in the same directory",
|
|
59
|
+
)
|
|
60
|
+
generate_parser.add_argument(
|
|
61
|
+
"config",
|
|
62
|
+
type=str,
|
|
63
|
+
help="Path to comfy-env.toml",
|
|
64
|
+
)
|
|
65
|
+
generate_parser.add_argument(
|
|
66
|
+
"--force", "-f",
|
|
67
|
+
action="store_true",
|
|
68
|
+
help="Overwrite existing pixi.toml",
|
|
69
|
+
)
|
|
70
|
+
|
|
57
71
|
# install command
|
|
58
72
|
install_parser = subparsers.add_parser(
|
|
59
73
|
"install",
|
|
@@ -88,28 +102,6 @@ def main(args: Optional[List[str]] = None) -> int:
|
|
|
88
102
|
help="Output as JSON",
|
|
89
103
|
)
|
|
90
104
|
|
|
91
|
-
# resolve command
|
|
92
|
-
resolve_parser = subparsers.add_parser(
|
|
93
|
-
"resolve",
|
|
94
|
-
help="Resolve wheel URLs for packages",
|
|
95
|
-
description="Show resolved wheel URLs without installing",
|
|
96
|
-
)
|
|
97
|
-
resolve_parser.add_argument(
|
|
98
|
-
"packages",
|
|
99
|
-
nargs="*",
|
|
100
|
-
help="Package specs (e.g., nvdiffrast==0.4.0)",
|
|
101
|
-
)
|
|
102
|
-
resolve_parser.add_argument(
|
|
103
|
-
"--all", "-a",
|
|
104
|
-
action="store_true",
|
|
105
|
-
help="Resolve all packages from config",
|
|
106
|
-
)
|
|
107
|
-
resolve_parser.add_argument(
|
|
108
|
-
"--config", "-c",
|
|
109
|
-
type=str,
|
|
110
|
-
help="Path to config file",
|
|
111
|
-
)
|
|
112
|
-
|
|
113
105
|
# doctor command
|
|
114
106
|
doctor_parser = subparsers.add_parser(
|
|
115
107
|
"doctor",
|
|
@@ -127,18 +119,6 @@ def main(args: Optional[List[str]] = None) -> int:
|
|
|
127
119
|
help="Path to config file",
|
|
128
120
|
)
|
|
129
121
|
|
|
130
|
-
# list-packages command
|
|
131
|
-
list_parser = subparsers.add_parser(
|
|
132
|
-
"list-packages",
|
|
133
|
-
help="Show all packages in the built-in registry",
|
|
134
|
-
description="List CUDA packages that comfy-env knows how to install",
|
|
135
|
-
)
|
|
136
|
-
list_parser.add_argument(
|
|
137
|
-
"--json",
|
|
138
|
-
action="store_true",
|
|
139
|
-
help="Output as JSON",
|
|
140
|
-
)
|
|
141
|
-
|
|
142
122
|
parsed = parser.parse_args(args)
|
|
143
123
|
|
|
144
124
|
if parsed.command is None:
|
|
@@ -148,16 +128,14 @@ def main(args: Optional[List[str]] = None) -> int:
|
|
|
148
128
|
try:
|
|
149
129
|
if parsed.command == "init":
|
|
150
130
|
return cmd_init(parsed)
|
|
131
|
+
elif parsed.command == "generate":
|
|
132
|
+
return cmd_generate(parsed)
|
|
151
133
|
elif parsed.command == "install":
|
|
152
134
|
return cmd_install(parsed)
|
|
153
135
|
elif parsed.command == "info":
|
|
154
136
|
return cmd_info(parsed)
|
|
155
|
-
elif parsed.command == "resolve":
|
|
156
|
-
return cmd_resolve(parsed)
|
|
157
137
|
elif parsed.command == "doctor":
|
|
158
138
|
return cmd_doctor(parsed)
|
|
159
|
-
elif parsed.command == "list-packages":
|
|
160
|
-
return cmd_list_packages(parsed)
|
|
161
139
|
else:
|
|
162
140
|
parser.print_help()
|
|
163
141
|
return 1
|
|
@@ -183,7 +161,7 @@ cuda_version = "auto"
|
|
|
183
161
|
pytorch_version = "auto"
|
|
184
162
|
|
|
185
163
|
[environment.cuda]
|
|
186
|
-
# CUDA packages from
|
|
164
|
+
# CUDA packages from https://pozzettiandrea.github.io/cuda-wheels/
|
|
187
165
|
# Example: nvdiffrast = "0.4.0"
|
|
188
166
|
|
|
189
167
|
[environment.packages]
|
|
@@ -205,6 +183,53 @@ def cmd_init(args) -> int:
|
|
|
205
183
|
return 0
|
|
206
184
|
|
|
207
185
|
|
|
186
|
+
def cmd_generate(args) -> int:
|
|
187
|
+
"""Handle generate command - create pixi.toml from comfy-env.toml."""
|
|
188
|
+
from .config.parser import load_config
|
|
189
|
+
from .pixi import create_pixi_toml
|
|
190
|
+
|
|
191
|
+
config_path = Path(args.config).resolve()
|
|
192
|
+
|
|
193
|
+
if not config_path.exists():
|
|
194
|
+
print(f"Config file not found: {config_path}", file=sys.stderr)
|
|
195
|
+
return 1
|
|
196
|
+
|
|
197
|
+
if config_path.name != "comfy-env.toml":
|
|
198
|
+
print(f"Warning: Expected comfy-env.toml, got {config_path.name}", file=sys.stderr)
|
|
199
|
+
|
|
200
|
+
node_dir = config_path.parent
|
|
201
|
+
pixi_path = node_dir / "pixi.toml"
|
|
202
|
+
|
|
203
|
+
if pixi_path.exists() and not args.force:
|
|
204
|
+
print(f"pixi.toml already exists: {pixi_path}", file=sys.stderr)
|
|
205
|
+
print("Use --force to overwrite", file=sys.stderr)
|
|
206
|
+
return 1
|
|
207
|
+
|
|
208
|
+
# Load the config
|
|
209
|
+
config = load_config(config_path)
|
|
210
|
+
if not config or not config.envs:
|
|
211
|
+
print(f"No environments found in {config_path}", file=sys.stderr)
|
|
212
|
+
return 1
|
|
213
|
+
|
|
214
|
+
# Use the first environment
|
|
215
|
+
env_name = next(iter(config.envs.keys()))
|
|
216
|
+
env_config = config.envs[env_name]
|
|
217
|
+
|
|
218
|
+
print(f"Generating pixi.toml from {config_path}")
|
|
219
|
+
print(f" Environment: {env_name}")
|
|
220
|
+
print(f" Python: {env_config.python}")
|
|
221
|
+
|
|
222
|
+
# Generate pixi.toml
|
|
223
|
+
result_path = create_pixi_toml(env_config, node_dir)
|
|
224
|
+
|
|
225
|
+
print(f"Created {result_path}")
|
|
226
|
+
print()
|
|
227
|
+
print("Next steps:")
|
|
228
|
+
print(f" cd {node_dir}")
|
|
229
|
+
print(" pixi install")
|
|
230
|
+
return 0
|
|
231
|
+
|
|
232
|
+
|
|
208
233
|
def cmd_install(args) -> int:
|
|
209
234
|
"""Handle install command."""
|
|
210
235
|
from .install import install
|
|
@@ -228,7 +253,7 @@ def cmd_install(args) -> int:
|
|
|
228
253
|
|
|
229
254
|
def cmd_info(args) -> int:
|
|
230
255
|
"""Handle info command."""
|
|
231
|
-
from .
|
|
256
|
+
from .pixi import RuntimeEnv
|
|
232
257
|
|
|
233
258
|
env = RuntimeEnv.detect()
|
|
234
259
|
|
|
@@ -262,98 +287,10 @@ def cmd_info(args) -> int:
|
|
|
262
287
|
return 0
|
|
263
288
|
|
|
264
289
|
|
|
265
|
-
def cmd_resolve(args) -> int:
|
|
266
|
-
"""Handle resolve command."""
|
|
267
|
-
from .resolver import RuntimeEnv, parse_wheel_requirement
|
|
268
|
-
from .registry import PACKAGE_REGISTRY, get_cuda_short2
|
|
269
|
-
from .env.config_file import discover_env_config, load_env_from_file
|
|
270
|
-
|
|
271
|
-
env = RuntimeEnv.detect()
|
|
272
|
-
packages = []
|
|
273
|
-
|
|
274
|
-
# Get packages from args or config
|
|
275
|
-
if args.all or (not args.packages and args.config):
|
|
276
|
-
if args.config:
|
|
277
|
-
config = load_env_from_file(Path(args.config))
|
|
278
|
-
else:
|
|
279
|
-
config = discover_env_config(Path.cwd())
|
|
280
|
-
|
|
281
|
-
if config and config.no_deps_requirements:
|
|
282
|
-
packages = config.no_deps_requirements
|
|
283
|
-
else:
|
|
284
|
-
print("No CUDA packages found in config", file=sys.stderr)
|
|
285
|
-
return 1
|
|
286
|
-
elif args.packages:
|
|
287
|
-
packages = args.packages
|
|
288
|
-
else:
|
|
289
|
-
print("Specify packages or use --all with a config file", file=sys.stderr)
|
|
290
|
-
return 1
|
|
291
|
-
|
|
292
|
-
print(f"Resolving wheels for: {env}")
|
|
293
|
-
print("=" * 60)
|
|
294
|
-
|
|
295
|
-
# Build template variables
|
|
296
|
-
vars_dict = env.as_dict()
|
|
297
|
-
if env.cuda_version:
|
|
298
|
-
vars_dict["cuda_short2"] = get_cuda_short2(env.cuda_version)
|
|
299
|
-
|
|
300
|
-
all_ok = True
|
|
301
|
-
for pkg_spec in packages:
|
|
302
|
-
package, version = parse_wheel_requirement(pkg_spec)
|
|
303
|
-
pkg_lower = package.lower()
|
|
304
|
-
|
|
305
|
-
try:
|
|
306
|
-
if pkg_lower in PACKAGE_REGISTRY:
|
|
307
|
-
config = PACKAGE_REGISTRY[pkg_lower]
|
|
308
|
-
|
|
309
|
-
if "wheel_template" in config:
|
|
310
|
-
# Direct wheel URL template
|
|
311
|
-
effective_version = version or config.get("default_version")
|
|
312
|
-
if not effective_version:
|
|
313
|
-
print(f" {package}: No version specified (no default in registry)")
|
|
314
|
-
all_ok = False
|
|
315
|
-
continue
|
|
316
|
-
|
|
317
|
-
vars_dict["version"] = effective_version
|
|
318
|
-
url = _substitute_template(config["wheel_template"], vars_dict)
|
|
319
|
-
print(f" {package}=={effective_version}: resolved")
|
|
320
|
-
print(f" {url}")
|
|
321
|
-
|
|
322
|
-
elif "package_name" in config:
|
|
323
|
-
# PyPI variant (e.g., spconv-cu124)
|
|
324
|
-
pkg_name = _substitute_template(config["package_name"], vars_dict)
|
|
325
|
-
pkg_spec = f"{pkg_name}=={version}" if version else pkg_name
|
|
326
|
-
print(f" {package}: installs as {pkg_spec} from PyPI")
|
|
327
|
-
|
|
328
|
-
else:
|
|
329
|
-
print(f" {package}: no wheel_template or package_name in registry")
|
|
330
|
-
all_ok = False
|
|
331
|
-
else:
|
|
332
|
-
print(f" {package}: NOT in registry")
|
|
333
|
-
print(f" Add to [wheel_sources] in comfy-env.toml:")
|
|
334
|
-
print(f' {package} = "https://example.com/{package}-{{version}}+cu{{cuda_short}}-{{py_tag}}-{{platform}}.whl"')
|
|
335
|
-
all_ok = False
|
|
336
|
-
|
|
337
|
-
except Exception as e:
|
|
338
|
-
print(f" {package}: FAILED - {e}")
|
|
339
|
-
all_ok = False
|
|
340
|
-
|
|
341
|
-
return 0 if all_ok else 1
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
def _substitute_template(template: str, vars_dict: dict) -> str:
|
|
345
|
-
"""Substitute {var} placeholders in template."""
|
|
346
|
-
result = template
|
|
347
|
-
for key, value in vars_dict.items():
|
|
348
|
-
if value is not None:
|
|
349
|
-
result = result.replace(f"{{{key}}}", str(value))
|
|
350
|
-
return result
|
|
351
|
-
|
|
352
|
-
|
|
353
290
|
def cmd_doctor(args) -> int:
|
|
354
291
|
"""Handle doctor command."""
|
|
355
292
|
from .install import verify_installation
|
|
356
|
-
from .
|
|
293
|
+
from .config.parser import discover_env_config, load_env_from_file
|
|
357
294
|
|
|
358
295
|
print("Running diagnostics...")
|
|
359
296
|
print("=" * 40)
|
|
@@ -395,72 +332,5 @@ def cmd_doctor(args) -> int:
|
|
|
395
332
|
return 0
|
|
396
333
|
|
|
397
334
|
|
|
398
|
-
def cmd_list_packages(args) -> int:
|
|
399
|
-
"""Handle list-packages command."""
|
|
400
|
-
from .registry import PACKAGE_REGISTRY
|
|
401
|
-
|
|
402
|
-
if args.json:
|
|
403
|
-
import json
|
|
404
|
-
result = {}
|
|
405
|
-
for name, config in PACKAGE_REGISTRY.items():
|
|
406
|
-
result[name] = {
|
|
407
|
-
"description": config.get("description", ""),
|
|
408
|
-
}
|
|
409
|
-
if "wheel_template" in config:
|
|
410
|
-
result[name]["wheel_template"] = config["wheel_template"]
|
|
411
|
-
if "package_name" in config:
|
|
412
|
-
result[name]["package_name"] = config["package_name"]
|
|
413
|
-
if "default_version" in config:
|
|
414
|
-
result[name]["default_version"] = config["default_version"]
|
|
415
|
-
print(json.dumps(result, indent=2))
|
|
416
|
-
return 0
|
|
417
|
-
|
|
418
|
-
print("Built-in CUDA Package Registry")
|
|
419
|
-
print("=" * 60)
|
|
420
|
-
print()
|
|
421
|
-
print("These packages can be installed by adding them to comfy-env.toml:")
|
|
422
|
-
print()
|
|
423
|
-
print(" [cuda]")
|
|
424
|
-
print(' nvdiffrast = "0.4.0"')
|
|
425
|
-
print(' torch-scatter = "2.1.2"')
|
|
426
|
-
print()
|
|
427
|
-
print("Or override with custom wheel source:")
|
|
428
|
-
print()
|
|
429
|
-
print(" [wheel_sources]")
|
|
430
|
-
print(' nvdiffrast = "https://my-mirror.com/nvdiffrast-{version}+cu{cuda_short}-{py_tag}-{platform}.whl"')
|
|
431
|
-
print()
|
|
432
|
-
print("-" * 60)
|
|
433
|
-
|
|
434
|
-
# Group by type
|
|
435
|
-
wheel_template_packages = []
|
|
436
|
-
package_name_packages = []
|
|
437
|
-
|
|
438
|
-
for name, config in PACKAGE_REGISTRY.items():
|
|
439
|
-
desc = config.get("description", "")
|
|
440
|
-
default = config.get("default_version", "")
|
|
441
|
-
if "wheel_template" in config:
|
|
442
|
-
wheel_template_packages.append((name, desc, default))
|
|
443
|
-
elif "package_name" in config:
|
|
444
|
-
package_name_packages.append((name, desc, config["package_name"]))
|
|
445
|
-
|
|
446
|
-
if wheel_template_packages:
|
|
447
|
-
print("\nDirect wheel URL packages:")
|
|
448
|
-
for name, desc, default in sorted(wheel_template_packages):
|
|
449
|
-
version_info = f" (default: {default})" if default else ""
|
|
450
|
-
print(f" {name:20} - {desc}{version_info}")
|
|
451
|
-
|
|
452
|
-
if package_name_packages:
|
|
453
|
-
print("\nPyPI variant packages:")
|
|
454
|
-
for name, desc, pkg_template in sorted(package_name_packages):
|
|
455
|
-
print(f" {name:20} - {desc}")
|
|
456
|
-
print(f" installs as: {pkg_template}")
|
|
457
|
-
|
|
458
|
-
print()
|
|
459
|
-
print("Template variables: {version}, {cuda_short}, {torch_mm}, {py_tag}, {platform}")
|
|
460
|
-
print("See README for full documentation on writing wheel templates.")
|
|
461
|
-
print()
|
|
462
|
-
return 0
|
|
463
|
-
|
|
464
|
-
|
|
465
335
|
if __name__ == "__main__":
|
|
466
336
|
sys.exit(main())
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Config parsing for comfy-env.
|
|
3
|
+
|
|
4
|
+
This module handles parsing comfy-env.toml files and provides
|
|
5
|
+
typed configuration objects.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .types import ComfyEnvConfig, NodeReq
|
|
9
|
+
from .parser import load_config, discover_config, CONFIG_FILE_NAME
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
# Types
|
|
13
|
+
"ComfyEnvConfig",
|
|
14
|
+
"NodeReq",
|
|
15
|
+
# Parser
|
|
16
|
+
"load_config",
|
|
17
|
+
"discover_config",
|
|
18
|
+
"CONFIG_FILE_NAME",
|
|
19
|
+
]
|