comfy-env 0.1.15__tar.gz → 0.1.16__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 (61) hide show
  1. comfy_env-0.1.16/PKG-INFO +279 -0
  2. comfy_env-0.1.16/README.md +250 -0
  3. {comfy_env-0.1.15 → comfy_env-0.1.16}/pyproject.toml +1 -1
  4. comfy_env-0.1.16/src/comfy_env/__init__.py +186 -0
  5. comfy_env-0.1.16/src/comfy_env/cli.py +202 -0
  6. comfy_env-0.1.16/src/comfy_env/config/__init__.py +29 -0
  7. comfy_env-0.1.16/src/comfy_env/config/parser.py +60 -0
  8. comfy_env-0.1.16/src/comfy_env/config/types.py +37 -0
  9. comfy_env-0.1.16/src/comfy_env/detection/__init__.py +77 -0
  10. comfy_env-0.1.16/src/comfy_env/detection/cuda.py +61 -0
  11. comfy_env-0.1.16/src/comfy_env/detection/gpu.py +230 -0
  12. comfy_env-0.1.16/src/comfy_env/detection/platform.py +70 -0
  13. comfy_env-0.1.16/src/comfy_env/detection/runtime.py +103 -0
  14. comfy_env-0.1.16/src/comfy_env/environment/__init__.py +53 -0
  15. comfy_env-0.1.16/src/comfy_env/environment/cache.py +141 -0
  16. comfy_env-0.1.16/src/comfy_env/environment/libomp.py +41 -0
  17. comfy_env-0.1.16/src/comfy_env/environment/paths.py +38 -0
  18. comfy_env-0.1.16/src/comfy_env/environment/setup.py +88 -0
  19. comfy_env-0.1.16/src/comfy_env/install.py +249 -0
  20. comfy_env-0.1.16/src/comfy_env/isolation/__init__.py +40 -0
  21. comfy_env-0.1.16/src/comfy_env/isolation/tensor_utils.py +83 -0
  22. comfy_env-0.1.16/src/comfy_env/isolation/workers/__init__.py +16 -0
  23. {comfy_env-0.1.15/src/comfy_env → comfy_env-0.1.16/src/comfy_env/isolation}/workers/mp.py +1 -1
  24. {comfy_env-0.1.15/src/comfy_env → comfy_env-0.1.16/src/comfy_env/isolation}/workers/subprocess.py +1 -1
  25. comfy_env-0.1.16/src/comfy_env/isolation/wrap.py +235 -0
  26. comfy_env-0.1.16/src/comfy_env/packages/__init__.py +60 -0
  27. comfy_env-0.1.16/src/comfy_env/packages/apt.py +36 -0
  28. comfy_env-0.1.16/src/comfy_env/packages/cuda_wheels.py +97 -0
  29. comfy_env-0.1.16/src/comfy_env/packages/node_dependencies.py +77 -0
  30. comfy_env-0.1.16/src/comfy_env/packages/pixi.py +85 -0
  31. comfy_env-0.1.16/src/comfy_env/packages/toml_generator.py +88 -0
  32. comfy_env-0.1.15/PKG-INFO +0 -291
  33. comfy_env-0.1.15/README.md +0 -262
  34. comfy_env-0.1.15/src/comfy_env/__init__.py +0 -111
  35. comfy_env-0.1.15/src/comfy_env/cache.py +0 -203
  36. comfy_env-0.1.15/src/comfy_env/cli.py +0 -430
  37. comfy_env-0.1.15/src/comfy_env/config/__init__.py +0 -17
  38. comfy_env-0.1.15/src/comfy_env/config/parser.py +0 -114
  39. comfy_env-0.1.15/src/comfy_env/install.py +0 -451
  40. comfy_env-0.1.15/src/comfy_env/isolation/__init__.py +0 -10
  41. comfy_env-0.1.15/src/comfy_env/isolation/wrap.py +0 -616
  42. comfy_env-0.1.15/src/comfy_env/nodes.py +0 -187
  43. comfy_env-0.1.15/src/comfy_env/pixi/__init__.py +0 -48
  44. comfy_env-0.1.15/src/comfy_env/pixi/core.py +0 -587
  45. comfy_env-0.1.15/src/comfy_env/pixi/cuda_detection.py +0 -303
  46. comfy_env-0.1.15/src/comfy_env/pixi/platform/__init__.py +0 -21
  47. comfy_env-0.1.15/src/comfy_env/pixi/platform/base.py +0 -96
  48. comfy_env-0.1.15/src/comfy_env/pixi/platform/darwin.py +0 -53
  49. comfy_env-0.1.15/src/comfy_env/pixi/platform/linux.py +0 -68
  50. comfy_env-0.1.15/src/comfy_env/pixi/platform/windows.py +0 -284
  51. comfy_env-0.1.15/src/comfy_env/pixi/resolver.py +0 -198
  52. comfy_env-0.1.15/src/comfy_env/prestartup.py +0 -208
  53. comfy_env-0.1.15/src/comfy_env/workers/__init__.py +0 -38
  54. comfy_env-0.1.15/src/comfy_env/workers/tensor_utils.py +0 -188
  55. {comfy_env-0.1.15 → comfy_env-0.1.16}/.github/workflows/ci.yml +0 -0
  56. {comfy_env-0.1.15 → comfy_env-0.1.16}/.github/workflows/publish.yml +0 -0
  57. {comfy_env-0.1.15 → comfy_env-0.1.16}/.gitignore +0 -0
  58. {comfy_env-0.1.15 → comfy_env-0.1.16}/LICENSE +0 -0
  59. {comfy_env-0.1.15/src/comfy_env → comfy_env-0.1.16/src/comfy_env/isolation}/workers/base.py +0 -0
  60. {comfy_env-0.1.15 → comfy_env-0.1.16}/src/comfy_env/templates/comfy-env-instructions.txt +0 -0
  61. {comfy_env-0.1.15 → comfy_env-0.1.16}/src/comfy_env/templates/comfy-env.toml +0 -0
@@ -0,0 +1,279 @@
1
+ Metadata-Version: 2.4
2
+ Name: comfy-env
3
+ Version: 0.1.16
4
+ Summary: Environment management for ComfyUI custom nodes - CUDA wheel resolution and process isolation
5
+ Project-URL: Homepage, https://github.com/PozzettiAndrea/comfy-env
6
+ Project-URL: Repository, https://github.com/PozzettiAndrea/comfy-env
7
+ Project-URL: Issues, https://github.com/PozzettiAndrea/comfy-env/issues
8
+ Author: Andrea Pozzetti
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: comfyui,cuda,environment,isolation,process,venv,wheels
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Requires-Python: >=3.10
20
+ Requires-Dist: pip>=21.0
21
+ Requires-Dist: tomli-w>=1.0.0
22
+ Requires-Dist: tomli>=2.0.0
23
+ Requires-Dist: uv>=0.4.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: mypy; extra == 'dev'
26
+ Requires-Dist: pytest; extra == 'dev'
27
+ Requires-Dist: ruff; extra == 'dev'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # comfy-env
31
+
32
+ Environment management for ComfyUI custom nodes.
33
+
34
+ ## Quick Start
35
+
36
+ ```bash
37
+ pip install comfy-env
38
+ ```
39
+
40
+ **1. Create `comfy-env.toml` in your node directory:**
41
+
42
+ ```toml
43
+ [cuda]
44
+ packages = ["nvdiffrast", "pytorch3d"]
45
+
46
+ [pypi-dependencies]
47
+ trimesh = { version = "*", extras = ["easy"] }
48
+ ```
49
+
50
+ **2. In `install.py`:**
51
+
52
+ ```python
53
+ from comfy_env import install
54
+ install()
55
+ ```
56
+
57
+ **3. In `prestartup_script.py`:**
58
+
59
+ ```python
60
+ from comfy_env import setup_env
61
+ setup_env()
62
+ ```
63
+
64
+ That's it. CUDA wheels install without compilation, and the environment is ready.
65
+
66
+ ---
67
+
68
+ ## Configuration
69
+
70
+ Create `comfy-env.toml` in your node directory:
71
+
72
+ ```toml
73
+ # Python version for isolated environment (optional)
74
+ python = "3.11"
75
+
76
+ # CUDA packages from cuda-wheels index (no compilation needed)
77
+ [cuda]
78
+ packages = ["nvdiffrast", "pytorch3d", "flash-attn"]
79
+
80
+ # System packages (Linux only)
81
+ [apt]
82
+ packages = ["libgl1-mesa-glx", "libglu1-mesa"]
83
+
84
+ # Environment variables
85
+ [env_vars]
86
+ KMP_DUPLICATE_LIB_OK = "TRUE"
87
+ OMP_NUM_THREADS = "1"
88
+
89
+ # Dependent custom nodes to auto-install
90
+ [node_reqs]
91
+ ComfyUI_essentials = "cubiq/ComfyUI_essentials"
92
+
93
+ # Conda packages (via pixi)
94
+ [dependencies]
95
+ cgal = "*"
96
+
97
+ # PyPI packages
98
+ [pypi-dependencies]
99
+ trimesh = { version = "*", extras = ["easy"] }
100
+ numpy = "*"
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Process Isolation
106
+
107
+ For nodes with conflicting dependencies, use isolated execution:
108
+
109
+ ```python
110
+ # In nodes/__init__.py
111
+ from pathlib import Path
112
+ from comfy_env import wrap_isolated_nodes
113
+
114
+ # Import your isolated nodes
115
+ from .cgal import NODE_CLASS_MAPPINGS as cgal_mappings
116
+
117
+ # Wrap them for isolated execution
118
+ NODE_CLASS_MAPPINGS = wrap_isolated_nodes(
119
+ cgal_mappings,
120
+ Path(__file__).parent / "cgal" # Directory with comfy-env.toml
121
+ )
122
+ ```
123
+
124
+ Each wrapped node runs in a subprocess with its own Python environment.
125
+
126
+ ---
127
+
128
+ ## CLI Commands
129
+
130
+ ```bash
131
+ # Show detected environment
132
+ comfy-env info
133
+
134
+ # Install dependencies
135
+ comfy-env install
136
+
137
+ # Preview without installing
138
+ comfy-env install --dry-run
139
+
140
+ # Verify packages
141
+ comfy-env doctor
142
+
143
+ # Install system packages
144
+ comfy-env apt-install
145
+ ```
146
+
147
+ ---
148
+
149
+ ## API Reference
150
+
151
+ ### install()
152
+
153
+ Install dependencies from comfy-env.toml:
154
+
155
+ ```python
156
+ from comfy_env import install
157
+
158
+ install() # Auto-detect config
159
+ install(dry_run=True) # Preview only
160
+ install(config="path.toml") # Explicit config
161
+ ```
162
+
163
+ ### setup_env()
164
+
165
+ Set up environment at ComfyUI startup:
166
+
167
+ ```python
168
+ from comfy_env import setup_env
169
+
170
+ setup_env() # Auto-detects node directory from caller
171
+ ```
172
+
173
+ Sets library paths, environment variables, and injects site-packages.
174
+
175
+ ### wrap_isolated_nodes()
176
+
177
+ Wrap nodes for subprocess isolation:
178
+
179
+ ```python
180
+ from comfy_env import wrap_isolated_nodes
181
+
182
+ wrapped = wrap_isolated_nodes(NODE_CLASS_MAPPINGS, node_dir)
183
+ ```
184
+
185
+ ### Detection
186
+
187
+ ```python
188
+ from comfy_env import (
189
+ detect_cuda_version, # Returns "12.8", "12.4", or None
190
+ detect_gpu, # Returns GPUInfo or None
191
+ get_gpu_summary, # Human-readable string
192
+ RuntimeEnv, # Combined runtime info
193
+ )
194
+
195
+ env = RuntimeEnv.detect()
196
+ print(env) # Python 3.11, CUDA 12.8, PyTorch 2.8.0, GPU: RTX 4090
197
+ ```
198
+
199
+ ### Workers
200
+
201
+ Low-level process isolation:
202
+
203
+ ```python
204
+ from comfy_env import MPWorker, SubprocessWorker
205
+
206
+ # Same Python version (multiprocessing)
207
+ worker = MPWorker()
208
+ result = worker.call(my_function, arg1, arg2)
209
+
210
+ # Different Python version (subprocess)
211
+ worker = SubprocessWorker(python="/path/to/python")
212
+ result = worker.call(my_function, arg1, arg2)
213
+ ```
214
+
215
+ ---
216
+
217
+ ## Real Example
218
+
219
+ See [ComfyUI-GeometryPack](https://github.com/PozzettiAndrea/ComfyUI-GeometryPack) for a production example with:
220
+
221
+ - Multiple isolated environments (CGAL, Blender, GPU)
222
+ - Per-subdirectory comfy-env.toml
223
+ - Prestartup asset copying
224
+ - Different Python versions (3.11 for Blender API)
225
+
226
+ ---
227
+
228
+ ## Architecture
229
+
230
+ ### Layers
231
+
232
+ ```
233
+ comfy_env/
234
+ ├── detection/ # Pure functions - CUDA, GPU, platform detection
235
+ ├── config/ # Pure parsing - comfy-env.toml → typed config
236
+ ├── environment/ # Side effects - cache, paths, setup
237
+ ├── packages/ # Side effects - pixi, cuda-wheels, apt
238
+ ├── isolation/ # Side effects - subprocess workers, node wrapping
239
+ └── install.py # Orchestration
240
+ ```
241
+
242
+ ### Why Isolation?
243
+
244
+ ComfyUI nodes share a single Python environment. This breaks when:
245
+
246
+ 1. **Dependency conflicts**: Node A needs `torch==2.4`, Node B needs `torch==2.8`
247
+ 2. **Native library conflicts**: Two packages bundle incompatible libomp
248
+ 3. **Python version requirements**: Blender API requires Python 3.11
249
+
250
+ Solution: Run each node group in its own subprocess with isolated dependencies.
251
+
252
+ ### Why CUDA Wheels?
253
+
254
+ Installing packages like `nvdiffrast` normally requires:
255
+ - CUDA toolkit
256
+ - C++ compiler
257
+ - 30+ minutes of compilation
258
+
259
+ CUDA wheels from [cuda-wheels](https://pozzettiandrea.github.io/cuda-wheels/) are pre-built for common configurations:
260
+
261
+ | GPU | CUDA | PyTorch |
262
+ |-----|------|---------|
263
+ | Blackwell (sm_100+) | 12.8 | 2.8 |
264
+ | Ada/Hopper/Ampere | 12.8 | 2.8 |
265
+ | Turing | 12.8 | 2.8 |
266
+ | Pascal | 12.4 | 2.4 |
267
+
268
+ ### How Environments Work
269
+
270
+ 1. **Central cache**: Environments stored at `~/.comfy-env/envs/`
271
+ 2. **Marker files**: `.comfy-env-marker.toml` links node → env
272
+ 3. **Orphan cleanup**: Envs deleted when their node is removed
273
+ 4. **Hash-based naming**: Config changes create new envs
274
+
275
+ ---
276
+
277
+ ## License
278
+
279
+ MIT
@@ -0,0 +1,250 @@
1
+ # comfy-env
2
+
3
+ Environment management for ComfyUI custom nodes.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ pip install comfy-env
9
+ ```
10
+
11
+ **1. Create `comfy-env.toml` in your node directory:**
12
+
13
+ ```toml
14
+ [cuda]
15
+ packages = ["nvdiffrast", "pytorch3d"]
16
+
17
+ [pypi-dependencies]
18
+ trimesh = { version = "*", extras = ["easy"] }
19
+ ```
20
+
21
+ **2. In `install.py`:**
22
+
23
+ ```python
24
+ from comfy_env import install
25
+ install()
26
+ ```
27
+
28
+ **3. In `prestartup_script.py`:**
29
+
30
+ ```python
31
+ from comfy_env import setup_env
32
+ setup_env()
33
+ ```
34
+
35
+ That's it. CUDA wheels install without compilation, and the environment is ready.
36
+
37
+ ---
38
+
39
+ ## Configuration
40
+
41
+ Create `comfy-env.toml` in your node directory:
42
+
43
+ ```toml
44
+ # Python version for isolated environment (optional)
45
+ python = "3.11"
46
+
47
+ # CUDA packages from cuda-wheels index (no compilation needed)
48
+ [cuda]
49
+ packages = ["nvdiffrast", "pytorch3d", "flash-attn"]
50
+
51
+ # System packages (Linux only)
52
+ [apt]
53
+ packages = ["libgl1-mesa-glx", "libglu1-mesa"]
54
+
55
+ # Environment variables
56
+ [env_vars]
57
+ KMP_DUPLICATE_LIB_OK = "TRUE"
58
+ OMP_NUM_THREADS = "1"
59
+
60
+ # Dependent custom nodes to auto-install
61
+ [node_reqs]
62
+ ComfyUI_essentials = "cubiq/ComfyUI_essentials"
63
+
64
+ # Conda packages (via pixi)
65
+ [dependencies]
66
+ cgal = "*"
67
+
68
+ # PyPI packages
69
+ [pypi-dependencies]
70
+ trimesh = { version = "*", extras = ["easy"] }
71
+ numpy = "*"
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Process Isolation
77
+
78
+ For nodes with conflicting dependencies, use isolated execution:
79
+
80
+ ```python
81
+ # In nodes/__init__.py
82
+ from pathlib import Path
83
+ from comfy_env import wrap_isolated_nodes
84
+
85
+ # Import your isolated nodes
86
+ from .cgal import NODE_CLASS_MAPPINGS as cgal_mappings
87
+
88
+ # Wrap them for isolated execution
89
+ NODE_CLASS_MAPPINGS = wrap_isolated_nodes(
90
+ cgal_mappings,
91
+ Path(__file__).parent / "cgal" # Directory with comfy-env.toml
92
+ )
93
+ ```
94
+
95
+ Each wrapped node runs in a subprocess with its own Python environment.
96
+
97
+ ---
98
+
99
+ ## CLI Commands
100
+
101
+ ```bash
102
+ # Show detected environment
103
+ comfy-env info
104
+
105
+ # Install dependencies
106
+ comfy-env install
107
+
108
+ # Preview without installing
109
+ comfy-env install --dry-run
110
+
111
+ # Verify packages
112
+ comfy-env doctor
113
+
114
+ # Install system packages
115
+ comfy-env apt-install
116
+ ```
117
+
118
+ ---
119
+
120
+ ## API Reference
121
+
122
+ ### install()
123
+
124
+ Install dependencies from comfy-env.toml:
125
+
126
+ ```python
127
+ from comfy_env import install
128
+
129
+ install() # Auto-detect config
130
+ install(dry_run=True) # Preview only
131
+ install(config="path.toml") # Explicit config
132
+ ```
133
+
134
+ ### setup_env()
135
+
136
+ Set up environment at ComfyUI startup:
137
+
138
+ ```python
139
+ from comfy_env import setup_env
140
+
141
+ setup_env() # Auto-detects node directory from caller
142
+ ```
143
+
144
+ Sets library paths, environment variables, and injects site-packages.
145
+
146
+ ### wrap_isolated_nodes()
147
+
148
+ Wrap nodes for subprocess isolation:
149
+
150
+ ```python
151
+ from comfy_env import wrap_isolated_nodes
152
+
153
+ wrapped = wrap_isolated_nodes(NODE_CLASS_MAPPINGS, node_dir)
154
+ ```
155
+
156
+ ### Detection
157
+
158
+ ```python
159
+ from comfy_env import (
160
+ detect_cuda_version, # Returns "12.8", "12.4", or None
161
+ detect_gpu, # Returns GPUInfo or None
162
+ get_gpu_summary, # Human-readable string
163
+ RuntimeEnv, # Combined runtime info
164
+ )
165
+
166
+ env = RuntimeEnv.detect()
167
+ print(env) # Python 3.11, CUDA 12.8, PyTorch 2.8.0, GPU: RTX 4090
168
+ ```
169
+
170
+ ### Workers
171
+
172
+ Low-level process isolation:
173
+
174
+ ```python
175
+ from comfy_env import MPWorker, SubprocessWorker
176
+
177
+ # Same Python version (multiprocessing)
178
+ worker = MPWorker()
179
+ result = worker.call(my_function, arg1, arg2)
180
+
181
+ # Different Python version (subprocess)
182
+ worker = SubprocessWorker(python="/path/to/python")
183
+ result = worker.call(my_function, arg1, arg2)
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Real Example
189
+
190
+ See [ComfyUI-GeometryPack](https://github.com/PozzettiAndrea/ComfyUI-GeometryPack) for a production example with:
191
+
192
+ - Multiple isolated environments (CGAL, Blender, GPU)
193
+ - Per-subdirectory comfy-env.toml
194
+ - Prestartup asset copying
195
+ - Different Python versions (3.11 for Blender API)
196
+
197
+ ---
198
+
199
+ ## Architecture
200
+
201
+ ### Layers
202
+
203
+ ```
204
+ comfy_env/
205
+ ├── detection/ # Pure functions - CUDA, GPU, platform detection
206
+ ├── config/ # Pure parsing - comfy-env.toml → typed config
207
+ ├── environment/ # Side effects - cache, paths, setup
208
+ ├── packages/ # Side effects - pixi, cuda-wheels, apt
209
+ ├── isolation/ # Side effects - subprocess workers, node wrapping
210
+ └── install.py # Orchestration
211
+ ```
212
+
213
+ ### Why Isolation?
214
+
215
+ ComfyUI nodes share a single Python environment. This breaks when:
216
+
217
+ 1. **Dependency conflicts**: Node A needs `torch==2.4`, Node B needs `torch==2.8`
218
+ 2. **Native library conflicts**: Two packages bundle incompatible libomp
219
+ 3. **Python version requirements**: Blender API requires Python 3.11
220
+
221
+ Solution: Run each node group in its own subprocess with isolated dependencies.
222
+
223
+ ### Why CUDA Wheels?
224
+
225
+ Installing packages like `nvdiffrast` normally requires:
226
+ - CUDA toolkit
227
+ - C++ compiler
228
+ - 30+ minutes of compilation
229
+
230
+ CUDA wheels from [cuda-wheels](https://pozzettiandrea.github.io/cuda-wheels/) are pre-built for common configurations:
231
+
232
+ | GPU | CUDA | PyTorch |
233
+ |-----|------|---------|
234
+ | Blackwell (sm_100+) | 12.8 | 2.8 |
235
+ | Ada/Hopper/Ampere | 12.8 | 2.8 |
236
+ | Turing | 12.8 | 2.8 |
237
+ | Pascal | 12.4 | 2.4 |
238
+
239
+ ### How Environments Work
240
+
241
+ 1. **Central cache**: Environments stored at `~/.comfy-env/envs/`
242
+ 2. **Marker files**: `.comfy-env-marker.toml` links node → env
243
+ 3. **Orphan cleanup**: Envs deleted when their node is removed
244
+ 4. **Hash-based naming**: Config changes create new envs
245
+
246
+ ---
247
+
248
+ ## License
249
+
250
+ MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "comfy-env"
3
- version = "0.1.15"
3
+ version = "0.1.16"
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"}
@@ -0,0 +1,186 @@
1
+ """
2
+ comfy-env - Environment management for ComfyUI custom nodes.
3
+
4
+ Features:
5
+ - CUDA wheel resolution (pre-built wheels without compilation)
6
+ - Process isolation (run nodes in separate Python environments)
7
+ - Central environment cache (~/.comfy-env/envs/)
8
+ """
9
+
10
+ from importlib.metadata import version, PackageNotFoundError
11
+
12
+ try:
13
+ __version__ = version("comfy-env")
14
+ except PackageNotFoundError:
15
+ __version__ = "0.0.0-dev"
16
+
17
+
18
+ # =============================================================================
19
+ # Primary API (what most users need)
20
+ # =============================================================================
21
+
22
+ # Install API
23
+ from .install import install, verify_installation, USE_COMFY_ENV_VAR
24
+
25
+ # Prestartup helpers
26
+ from .environment.setup import setup_env
27
+ from .environment.paths import copy_files
28
+
29
+ # Isolation
30
+ from .isolation import wrap_isolated_nodes, wrap_nodes
31
+
32
+
33
+ # =============================================================================
34
+ # Config Layer
35
+ # =============================================================================
36
+
37
+ from .config import (
38
+ ComfyEnvConfig,
39
+ NodeDependency,
40
+ NodeReq, # Backwards compatibility alias
41
+ load_config,
42
+ discover_config,
43
+ CONFIG_FILE_NAME,
44
+ )
45
+
46
+
47
+ # =============================================================================
48
+ # Detection Layer
49
+ # =============================================================================
50
+
51
+ from .detection import (
52
+ # CUDA detection
53
+ detect_cuda_version,
54
+ detect_cuda_environment,
55
+ get_recommended_cuda_version,
56
+ # GPU detection
57
+ GPUInfo,
58
+ CUDAEnvironment,
59
+ detect_gpu,
60
+ get_gpu_summary,
61
+ # Platform detection
62
+ detect_platform,
63
+ get_platform_tag,
64
+ # Runtime detection
65
+ RuntimeEnv,
66
+ detect_runtime,
67
+ )
68
+
69
+
70
+ # =============================================================================
71
+ # Packages Layer
72
+ # =============================================================================
73
+
74
+ from .packages import (
75
+ # Pixi
76
+ ensure_pixi,
77
+ get_pixi_path,
78
+ get_pixi_python,
79
+ pixi_run,
80
+ pixi_clean,
81
+ # CUDA wheels
82
+ CUDA_WHEELS_INDEX,
83
+ get_wheel_url,
84
+ get_cuda_torch_mapping,
85
+ )
86
+
87
+
88
+ # =============================================================================
89
+ # Environment Layer
90
+ # =============================================================================
91
+
92
+ from .environment import (
93
+ # Cache management
94
+ get_cache_dir,
95
+ cleanup_orphaned_envs,
96
+ resolve_env_path,
97
+ CACHE_DIR,
98
+ MARKER_FILE,
99
+ )
100
+
101
+
102
+ # =============================================================================
103
+ # Isolation Layer
104
+ # =============================================================================
105
+
106
+ from .isolation import (
107
+ # Workers
108
+ Worker,
109
+ WorkerError,
110
+ MPWorker,
111
+ SubprocessWorker,
112
+ # Tensor utilities
113
+ TensorKeeper,
114
+ )
115
+
116
+
117
+ # =============================================================================
118
+ # Exports
119
+ # =============================================================================
120
+
121
+ __all__ = [
122
+ # Install API
123
+ "install",
124
+ "verify_installation",
125
+ "USE_COMFY_ENV_VAR",
126
+ # Prestartup
127
+ "setup_env",
128
+ "copy_files",
129
+ # Isolation
130
+ "wrap_isolated_nodes",
131
+ "wrap_nodes",
132
+ # Config
133
+ "ComfyEnvConfig",
134
+ "NodeDependency",
135
+ "NodeReq",
136
+ "load_config",
137
+ "discover_config",
138
+ "CONFIG_FILE_NAME",
139
+ # Detection
140
+ "detect_cuda_version",
141
+ "detect_cuda_environment",
142
+ "get_recommended_cuda_version",
143
+ "GPUInfo",
144
+ "CUDAEnvironment",
145
+ "detect_gpu",
146
+ "get_gpu_summary",
147
+ "detect_platform",
148
+ "get_platform_tag",
149
+ "RuntimeEnv",
150
+ "detect_runtime",
151
+ # Packages
152
+ "ensure_pixi",
153
+ "get_pixi_path",
154
+ "get_pixi_python",
155
+ "pixi_run",
156
+ "pixi_clean",
157
+ "CUDA_WHEELS_INDEX",
158
+ "get_wheel_url",
159
+ "get_cuda_torch_mapping",
160
+ # Environment
161
+ "get_cache_dir",
162
+ "cleanup_orphaned_envs",
163
+ "resolve_env_path",
164
+ "CACHE_DIR",
165
+ "MARKER_FILE",
166
+ # Workers
167
+ "Worker",
168
+ "WorkerError",
169
+ "MPWorker",
170
+ "SubprocessWorker",
171
+ "TensorKeeper",
172
+ ]
173
+
174
+
175
+ # =============================================================================
176
+ # Startup cleanup
177
+ # =============================================================================
178
+
179
+ def _run_startup_cleanup():
180
+ """Clean orphaned envs on startup."""
181
+ try:
182
+ cleanup_orphaned_envs(log=lambda x: None) # Silent
183
+ except Exception:
184
+ pass # Never fail startup due to cleanup
185
+
186
+ _run_startup_cleanup()