comfy-env 0.0.8__py3-none-any.whl → 0.0.16__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 +16 -44
- comfy_env/cli.py +103 -5
- comfy_env/env/__init__.py +19 -2
- comfy_env/env/config.py +14 -0
- comfy_env/env/config_file.py +101 -35
- comfy_env/env/cuda_gpu_detection.py +303 -0
- comfy_env/env/manager.py +27 -10
- comfy_env/env/platform/windows.py +1 -94
- comfy_env/errors.py +0 -32
- comfy_env/install.py +47 -8
- comfy_env/ipc/bridge.py +0 -36
- comfy_env/registry.py +17 -178
- comfy_env/resolver.py +7 -18
- comfy_env/stubs/folder_paths.py +4 -0
- comfy_env/tools.py +221 -0
- comfy_env/wheel_sources.yml +141 -0
- {comfy_env-0.0.8.dist-info → comfy_env-0.0.16.dist-info}/METADATA +2 -1
- comfy_env-0.0.16.dist-info/RECORD +40 -0
- comfy_env/env/detection.py +0 -176
- comfy_env/runner.py +0 -273
- comfy_env-0.0.8.dist-info/RECORD +0 -39
- {comfy_env-0.0.8.dist-info → comfy_env-0.0.16.dist-info}/WHEEL +0 -0
- {comfy_env-0.0.8.dist-info → comfy_env-0.0.16.dist-info}/entry_points.txt +0 -0
- {comfy_env-0.0.8.dist-info → comfy_env-0.0.16.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
comfy_env/__init__.py,sha256=76gIAh7qFff_v_bAolXVzuWzcgvD3bp-yQGCNzba_Iw,3287
|
|
2
|
+
comfy_env/cli.py,sha256=q4y_tlPyqKMZhge7XeO9VdbFVZ4dl9LZsgnnTVQYXD4,15979
|
|
3
|
+
comfy_env/decorator.py,sha256=daFR5aLzshkmo5sRKhSGPcTUgIUWml7Gs6A1bfnDuyc,15718
|
|
4
|
+
comfy_env/errors.py,sha256=8hN8NDlo8oBUdapc-eT3ZluigI5VBzfqsSBvQdfWlz4,9943
|
|
5
|
+
comfy_env/install.py,sha256=uk7mtmoDrcCs6MCfz-5WuyYtgd9JFaByarBWgSUc7Dk,20518
|
|
6
|
+
comfy_env/registry.py,sha256=uFCtGmWYvwGCqObXgzmArX7o5JsFNsHXxayofk3m6no,2569
|
|
7
|
+
comfy_env/resolver.py,sha256=l-AnmCE1puG6CvdpDB-KrsfG_cn_3uO2DryYizUnG_4,12474
|
|
8
|
+
comfy_env/tools.py,sha256=mFNB_uq64ON5hlreH_0wTLONahDo3pBHxhQYTcTHxXE,6554
|
|
9
|
+
comfy_env/env/__init__.py,sha256=imQdoQEQvrRT-QDtyNpFlkVbm2fBzgACdpQwRPd09fI,1157
|
|
10
|
+
comfy_env/env/config.py,sha256=6KZPhRiW8ShhuDnX-e6_yjZHMdO_xBm02w00Q3NBJXM,5980
|
|
11
|
+
comfy_env/env/config_file.py,sha256=tJ9xfmf2RghzK6PUxwTrhpvqV_5pecjC6IYYBoZ0U58,21890
|
|
12
|
+
comfy_env/env/cuda_gpu_detection.py,sha256=YLuXUdWg6FeKdNyLlQAHPlveg4rTenXJ2VbeAaEi9QE,9755
|
|
13
|
+
comfy_env/env/manager.py,sha256=bbV1MpURNGuBJ1sSWg_2oSU0J-dW-FhBCuHHHQxgrSM,24785
|
|
14
|
+
comfy_env/env/security.py,sha256=dNSitAnfBNVdvxgBBntYw33AJaCs_S1MHb7KJhAVYzM,8171
|
|
15
|
+
comfy_env/env/platform/__init__.py,sha256=Nb5MPZIEeanSMEWwqU4p4bnEKTJn1tWcwobnhq9x9IY,614
|
|
16
|
+
comfy_env/env/platform/base.py,sha256=iS0ptTTVjXRwPU4qWUdvHI7jteuzxGSjWr5BUQ7hGiU,2453
|
|
17
|
+
comfy_env/env/platform/darwin.py,sha256=HK3VkLT6DfesAnIXwx2IaUFHTBclF0xTQnC7azWY6Kc,1552
|
|
18
|
+
comfy_env/env/platform/linux.py,sha256=xLp8FEbFqZLQrzIZBI9z3C4g23Ab1ASTHLsXDzsdCoA,2062
|
|
19
|
+
comfy_env/env/platform/windows.py,sha256=FCOCgpzGzorY9-HueMlJUR8DxM2eH-cj9iZk6K026Is,10891
|
|
20
|
+
comfy_env/ipc/__init__.py,sha256=pTjgJn5YJxLXmEvuKh3lkCEJQs-6W6_F01jfkFMUi0c,1375
|
|
21
|
+
comfy_env/ipc/bridge.py,sha256=zcyN3xzV4WWBrBFNwCniPBR58dLCg46-k9TtyW5U000,16437
|
|
22
|
+
comfy_env/ipc/protocol.py,sha256=gfWe5yEDUn4QWhcdWFcxn40GqxlW1Uf23j0edOzPPng,7951
|
|
23
|
+
comfy_env/ipc/tensor.py,sha256=DyU28GymKkLPVwzZyKdm2Av222hdaycMgv3KdL5mtO0,12009
|
|
24
|
+
comfy_env/ipc/torch_bridge.py,sha256=WzdwDJa3N_1fEl9OeZxikvMbwryO5P63o0WmEDpS18A,13206
|
|
25
|
+
comfy_env/ipc/transport.py,sha256=XQlRcfQsd4nd909KIYnZKvsS3ksGpGjyVucn8jvmLIU,9698
|
|
26
|
+
comfy_env/ipc/worker.py,sha256=oxTLF9xXrl8CRx_JVNBdkxZh35NuzfkdxhaUtUuXogs,6661
|
|
27
|
+
comfy_env/stubs/__init__.py,sha256=jMeWEKY30y8QqYX9AUyuZbmm607erQTc4N7YaDoAH00,38
|
|
28
|
+
comfy_env/stubs/folder_paths.py,sha256=Pv30qHeHBmfK5icIpmXnTGvZkRMJHDrTh9mQ1WMclLg,1713
|
|
29
|
+
comfy_env/workers/__init__.py,sha256=IKZwOvrWOGqBLDUIFAalg4CdqzJ_YnAdxo2Ha7gZTJ0,1467
|
|
30
|
+
comfy_env/workers/base.py,sha256=ZILYXlvGCWuCZXmjKqfG8VeD19ihdYaASdlbasl2BMo,2312
|
|
31
|
+
comfy_env/workers/pool.py,sha256=MtjeOWfvHSCockq8j1gfnxIl-t01GSB79T5N4YB82Lg,6956
|
|
32
|
+
comfy_env/workers/tensor_utils.py,sha256=TCuOAjJymrSbkgfyvcKtQ_KbVWTqSwP9VH_bCaFLLq8,6409
|
|
33
|
+
comfy_env/workers/torch_mp.py,sha256=DsfxE3LBAWEuGtk-p-YL0UhVQ7VDh73KT_TFRxYN4-Q,12563
|
|
34
|
+
comfy_env/workers/venv.py,sha256=_ekHfZPqBIPY08DjqiXm6cTBQH4DrbxRWR3AAv3mit8,31589
|
|
35
|
+
comfy_env/wheel_sources.yml,sha256=ubVuQllCQGkZhLNQaG54divCwn0zLzYg4turzhnIZQ8,7150
|
|
36
|
+
comfy_env-0.0.16.dist-info/METADATA,sha256=jj04Wmh8ojLkTKSOwyRug1kSWT4SrpsY5PKfgbuq0NE,5399
|
|
37
|
+
comfy_env-0.0.16.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
38
|
+
comfy_env-0.0.16.dist-info/entry_points.txt,sha256=J4fXeqgxU_YenuW_Zxn_pEL7J-3R0--b6MS5t0QmAr0,49
|
|
39
|
+
comfy_env-0.0.16.dist-info/licenses/LICENSE,sha256=E68QZMMpW4P2YKstTZ3QU54HRQO8ecew09XZ4_Vn870,1093
|
|
40
|
+
comfy_env-0.0.16.dist-info/RECORD,,
|
comfy_env/env/detection.py
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
GPU detection for automatic CUDA version selection.
|
|
3
|
-
|
|
4
|
-
Detects Blackwell GPUs (RTX 50xx, B100, B200) which require CUDA 12.8,
|
|
5
|
-
vs older GPUs which use CUDA 12.4.
|
|
6
|
-
|
|
7
|
-
This runs BEFORE PyTorch is installed, so we use nvidia-smi directly.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
import subprocess
|
|
11
|
-
from typing import List, Dict, Optional
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def detect_gpu_info() -> List[Dict[str, str]]:
|
|
15
|
-
"""
|
|
16
|
-
Detect GPU name and compute capability using nvidia-smi.
|
|
17
|
-
|
|
18
|
-
Returns:
|
|
19
|
-
List of dicts with 'name' and 'compute_cap' keys.
|
|
20
|
-
Empty list if detection fails.
|
|
21
|
-
"""
|
|
22
|
-
try:
|
|
23
|
-
result = subprocess.run(
|
|
24
|
-
["nvidia-smi", "--query-gpu=name,compute_cap", "--format=csv,noheader"],
|
|
25
|
-
capture_output=True,
|
|
26
|
-
text=True,
|
|
27
|
-
timeout=10
|
|
28
|
-
)
|
|
29
|
-
if result.returncode == 0:
|
|
30
|
-
gpus = []
|
|
31
|
-
for line in result.stdout.strip().split('\n'):
|
|
32
|
-
if not line.strip():
|
|
33
|
-
continue
|
|
34
|
-
parts = [p.strip() for p in line.split(',')]
|
|
35
|
-
name = parts[0] if parts else "Unknown"
|
|
36
|
-
cc = parts[1] if len(parts) > 1 else "0.0"
|
|
37
|
-
gpus.append({"name": name, "compute_cap": cc})
|
|
38
|
-
return gpus
|
|
39
|
-
except FileNotFoundError:
|
|
40
|
-
# nvidia-smi not found - no NVIDIA GPU or driver not installed
|
|
41
|
-
pass
|
|
42
|
-
except subprocess.TimeoutExpired:
|
|
43
|
-
pass
|
|
44
|
-
except Exception:
|
|
45
|
-
pass
|
|
46
|
-
return []
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def is_blackwell_gpu(name: str, compute_cap: str) -> bool:
|
|
50
|
-
"""
|
|
51
|
-
Check if a GPU is Blackwell architecture.
|
|
52
|
-
|
|
53
|
-
Args:
|
|
54
|
-
name: GPU name from nvidia-smi
|
|
55
|
-
compute_cap: Compute capability string (e.g., "8.9", "12.0")
|
|
56
|
-
|
|
57
|
-
Returns:
|
|
58
|
-
True if Blackwell (requires CUDA 12.8)
|
|
59
|
-
"""
|
|
60
|
-
name_upper = name.upper()
|
|
61
|
-
|
|
62
|
-
# Check by name patterns
|
|
63
|
-
blackwell_patterns = [
|
|
64
|
-
"RTX 50", # RTX 5090, 5080, 5070, etc.
|
|
65
|
-
"RTX50", # Without space
|
|
66
|
-
"B100", # Datacenter Blackwell
|
|
67
|
-
"B200", # Datacenter Blackwell
|
|
68
|
-
"GB202", # Blackwell die
|
|
69
|
-
"GB203",
|
|
70
|
-
"GB205",
|
|
71
|
-
"GB206",
|
|
72
|
-
"GB207",
|
|
73
|
-
]
|
|
74
|
-
|
|
75
|
-
if any(pattern in name_upper for pattern in blackwell_patterns):
|
|
76
|
-
return True
|
|
77
|
-
|
|
78
|
-
# Check by compute capability (10.0+ = Blackwell)
|
|
79
|
-
try:
|
|
80
|
-
cc = float(compute_cap)
|
|
81
|
-
if cc >= 10.0:
|
|
82
|
-
return True
|
|
83
|
-
except (ValueError, TypeError):
|
|
84
|
-
pass
|
|
85
|
-
|
|
86
|
-
return False
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def needs_cuda_128() -> bool:
|
|
90
|
-
"""
|
|
91
|
-
Check if any detected GPU requires CUDA 12.8.
|
|
92
|
-
|
|
93
|
-
Returns:
|
|
94
|
-
True if Blackwell GPU detected, False otherwise.
|
|
95
|
-
"""
|
|
96
|
-
gpus = detect_gpu_info()
|
|
97
|
-
|
|
98
|
-
for gpu in gpus:
|
|
99
|
-
if is_blackwell_gpu(gpu["name"], gpu["compute_cap"]):
|
|
100
|
-
return True
|
|
101
|
-
|
|
102
|
-
return False
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
def is_legacy_gpu(compute_cap: str) -> bool:
|
|
106
|
-
"""
|
|
107
|
-
Check if GPU is Pascal or older (requires legacy CUDA/PyTorch).
|
|
108
|
-
|
|
109
|
-
Args:
|
|
110
|
-
compute_cap: Compute capability string (e.g., "6.1", "7.5")
|
|
111
|
-
|
|
112
|
-
Returns:
|
|
113
|
-
True if Pascal or older (compute < 7.5)
|
|
114
|
-
"""
|
|
115
|
-
try:
|
|
116
|
-
cc = float(compute_cap)
|
|
117
|
-
return cc < 7.5 # Turing starts at 7.5
|
|
118
|
-
except (ValueError, TypeError):
|
|
119
|
-
return False
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
def detect_cuda_version() -> Optional[str]:
|
|
123
|
-
"""
|
|
124
|
-
Get recommended CUDA version based on detected GPU.
|
|
125
|
-
|
|
126
|
-
Returns:
|
|
127
|
-
"12.4" for Pascal or older (compute < 7.5),
|
|
128
|
-
"12.8" for Turing or newer (compute >= 7.5),
|
|
129
|
-
None if no GPU detected.
|
|
130
|
-
|
|
131
|
-
GPU Architecture Reference:
|
|
132
|
-
- Pascal (GTX 10xx, P100): compute 6.0-6.1 → CUDA 12.4
|
|
133
|
-
- Turing (RTX 20xx, T4): compute 7.5 → CUDA 12.8
|
|
134
|
-
- Ampere (RTX 30xx, A100): compute 8.0-8.6 → CUDA 12.8
|
|
135
|
-
- Ada (RTX 40xx, L40): compute 8.9 → CUDA 12.8
|
|
136
|
-
- Hopper (H100): compute 9.0 → CUDA 12.8
|
|
137
|
-
- Blackwell (RTX 50xx, B100/B200): compute 10.0+ → CUDA 12.8
|
|
138
|
-
"""
|
|
139
|
-
gpus = detect_gpu_info()
|
|
140
|
-
if not gpus:
|
|
141
|
-
return None
|
|
142
|
-
|
|
143
|
-
# Check if any GPU is legacy (Pascal or older)
|
|
144
|
-
for gpu in gpus:
|
|
145
|
-
if is_legacy_gpu(gpu.get("compute_cap", "0.0")):
|
|
146
|
-
return "12.4"
|
|
147
|
-
|
|
148
|
-
# Turing or newer - use modern stack
|
|
149
|
-
return "12.8"
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def get_gpu_summary() -> str:
|
|
153
|
-
"""
|
|
154
|
-
Get a human-readable summary of detected GPUs.
|
|
155
|
-
|
|
156
|
-
Returns:
|
|
157
|
-
Summary string for logging.
|
|
158
|
-
"""
|
|
159
|
-
gpus = detect_gpu_info()
|
|
160
|
-
|
|
161
|
-
if not gpus:
|
|
162
|
-
return "No NVIDIA GPU detected"
|
|
163
|
-
|
|
164
|
-
lines = []
|
|
165
|
-
for i, gpu in enumerate(gpus):
|
|
166
|
-
cc = gpu.get("compute_cap", "0.0")
|
|
167
|
-
is_legacy = is_legacy_gpu(cc)
|
|
168
|
-
if is_legacy:
|
|
169
|
-
tag = " [Pascal - CUDA 12.4]"
|
|
170
|
-
elif is_blackwell_gpu(gpu["name"], cc):
|
|
171
|
-
tag = " [Blackwell - CUDA 12.8]"
|
|
172
|
-
else:
|
|
173
|
-
tag = " [CUDA 12.8]"
|
|
174
|
-
lines.append(f" GPU {i}: {gpu['name']} (sm_{cc.replace('.', '')}){tag}")
|
|
175
|
-
|
|
176
|
-
return "\n".join(lines)
|
comfy_env/runner.py
DELETED
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Generic runner for isolated subprocess execution.
|
|
3
|
-
|
|
4
|
-
This module is the entry point for subprocess execution. The runner handles
|
|
5
|
-
requests for ANY @isolated class in the environment, importing classes on demand.
|
|
6
|
-
|
|
7
|
-
Usage (Unix Domain Socket - recommended):
|
|
8
|
-
python -m comfy_env.runner \
|
|
9
|
-
--node-dir /path/to/ComfyUI-SAM3DObjects/nodes \
|
|
10
|
-
--comfyui-base /path/to/ComfyUI \
|
|
11
|
-
--import-paths ".,../vendor" \
|
|
12
|
-
--socket /tmp/comfyui-isolation-myenv-12345.sock
|
|
13
|
-
|
|
14
|
-
Usage (Legacy stdin/stdout):
|
|
15
|
-
python -m comfy_env.runner \
|
|
16
|
-
--node-dir /path/to/ComfyUI-SAM3DObjects/nodes \
|
|
17
|
-
--comfyui-base /path/to/ComfyUI \
|
|
18
|
-
--import-paths ".,../vendor"
|
|
19
|
-
|
|
20
|
-
The runner:
|
|
21
|
-
1. Sets COMFYUI_ISOLATION_WORKER=1 (so @isolated decorator becomes no-op)
|
|
22
|
-
2. Adds paths to sys.path
|
|
23
|
-
3. Connects to Unix Domain Socket (or uses stdin/stdout)
|
|
24
|
-
4. Dynamically imports classes as needed (cached)
|
|
25
|
-
5. Calls methods and returns responses
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
import os
|
|
29
|
-
import sys
|
|
30
|
-
import json
|
|
31
|
-
import argparse
|
|
32
|
-
import traceback
|
|
33
|
-
import warnings
|
|
34
|
-
import logging
|
|
35
|
-
import importlib
|
|
36
|
-
from typing import Any, Dict, Optional
|
|
37
|
-
|
|
38
|
-
# Suppress warnings that could interfere with JSON IPC
|
|
39
|
-
warnings.filterwarnings("ignore")
|
|
40
|
-
os.environ.setdefault("TF_CPP_MIN_LOG_LEVEL", "3")
|
|
41
|
-
logging.disable(logging.WARNING)
|
|
42
|
-
|
|
43
|
-
# Mark that we're in worker mode - this makes @isolated decorator a no-op
|
|
44
|
-
os.environ["COMFYUI_ISOLATION_WORKER"] = "1"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def setup_paths(node_dir: str, comfyui_base: Optional[str], import_paths: Optional[str]):
|
|
48
|
-
"""Setup sys.path for imports."""
|
|
49
|
-
from pathlib import Path
|
|
50
|
-
|
|
51
|
-
node_path = Path(node_dir)
|
|
52
|
-
|
|
53
|
-
# Set COMFYUI_BASE env var for stubs to use
|
|
54
|
-
if comfyui_base:
|
|
55
|
-
os.environ["COMFYUI_BASE"] = comfyui_base
|
|
56
|
-
|
|
57
|
-
# Add comfyui-isolation stubs directory (provides folder_paths, etc.)
|
|
58
|
-
stubs_dir = Path(__file__).parent / "stubs"
|
|
59
|
-
sys.path.insert(0, str(stubs_dir))
|
|
60
|
-
|
|
61
|
-
# Add import paths
|
|
62
|
-
if import_paths:
|
|
63
|
-
for p in import_paths.split(","):
|
|
64
|
-
p = p.strip()
|
|
65
|
-
if p:
|
|
66
|
-
full_path = node_path / p
|
|
67
|
-
sys.path.insert(0, str(full_path))
|
|
68
|
-
|
|
69
|
-
# Add node_dir itself
|
|
70
|
-
sys.path.insert(0, str(node_path))
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def serialize_result(obj: Any) -> Any:
|
|
74
|
-
"""Serialize result for JSON transport."""
|
|
75
|
-
from comfy_env.ipc.protocol import encode_object
|
|
76
|
-
return encode_object(obj)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def deserialize_arg(obj: Any) -> Any:
|
|
80
|
-
"""Deserialize argument from JSON transport."""
|
|
81
|
-
from comfy_env.ipc.protocol import decode_object
|
|
82
|
-
return decode_object(obj)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
# Cache for imported classes and instances
|
|
86
|
-
_class_cache: Dict[str, type] = {}
|
|
87
|
-
_instance_cache: Dict[str, object] = {}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def get_instance(module_name: str, class_name: str) -> object:
|
|
91
|
-
"""Get or create an instance of a class."""
|
|
92
|
-
cache_key = f"{module_name}.{class_name}"
|
|
93
|
-
|
|
94
|
-
if cache_key not in _instance_cache:
|
|
95
|
-
# Import the class if not cached
|
|
96
|
-
if cache_key not in _class_cache:
|
|
97
|
-
print(f"[Runner] Importing {class_name} from {module_name}...", file=sys.stderr)
|
|
98
|
-
module = importlib.import_module(module_name)
|
|
99
|
-
cls = getattr(module, class_name)
|
|
100
|
-
_class_cache[cache_key] = cls
|
|
101
|
-
|
|
102
|
-
# Create instance
|
|
103
|
-
cls = _class_cache[cache_key]
|
|
104
|
-
_instance_cache[cache_key] = cls()
|
|
105
|
-
print(f"[Runner] Created instance of {class_name}", file=sys.stderr)
|
|
106
|
-
|
|
107
|
-
return _instance_cache[cache_key]
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def run_worker(
|
|
111
|
-
node_dir: str,
|
|
112
|
-
comfyui_base: Optional[str],
|
|
113
|
-
import_paths: Optional[str],
|
|
114
|
-
socket_path: Optional[str] = None,
|
|
115
|
-
):
|
|
116
|
-
"""
|
|
117
|
-
Main worker loop - handles JSON-RPC requests via transport.
|
|
118
|
-
|
|
119
|
-
Args:
|
|
120
|
-
node_dir: Path to node package directory
|
|
121
|
-
comfyui_base: Path to ComfyUI base directory
|
|
122
|
-
import_paths: Comma-separated import paths
|
|
123
|
-
socket_path: Unix domain socket path (if None, uses stdin/stdout)
|
|
124
|
-
"""
|
|
125
|
-
from comfy_env.ipc.transport import UnixSocketTransport, StdioTransport
|
|
126
|
-
|
|
127
|
-
# Setup paths first
|
|
128
|
-
setup_paths(node_dir, comfyui_base, import_paths)
|
|
129
|
-
|
|
130
|
-
# Create transport
|
|
131
|
-
if socket_path:
|
|
132
|
-
# Unix Domain Socket transport (recommended)
|
|
133
|
-
print(f"[Runner] Connecting to socket: {socket_path}", file=sys.stderr)
|
|
134
|
-
transport = UnixSocketTransport.connect(socket_path)
|
|
135
|
-
use_uds = True
|
|
136
|
-
else:
|
|
137
|
-
# Legacy stdin/stdout transport
|
|
138
|
-
print("[Runner] Using stdin/stdout transport", file=sys.stderr)
|
|
139
|
-
transport = StdioTransport()
|
|
140
|
-
use_uds = False
|
|
141
|
-
|
|
142
|
-
try:
|
|
143
|
-
# Send ready signal
|
|
144
|
-
transport.send({"status": "ready"})
|
|
145
|
-
|
|
146
|
-
# Main loop - read requests, execute, respond
|
|
147
|
-
while True:
|
|
148
|
-
response = {"jsonrpc": "2.0", "id": None}
|
|
149
|
-
|
|
150
|
-
try:
|
|
151
|
-
request = transport.recv()
|
|
152
|
-
response["id"] = request.get("id")
|
|
153
|
-
|
|
154
|
-
method_name = request.get("method")
|
|
155
|
-
params = request.get("params", {})
|
|
156
|
-
|
|
157
|
-
if method_name == "shutdown":
|
|
158
|
-
# Clean shutdown
|
|
159
|
-
response["result"] = {"status": "shutdown"}
|
|
160
|
-
transport.send(response)
|
|
161
|
-
break
|
|
162
|
-
|
|
163
|
-
# Get module/class from request
|
|
164
|
-
module_name = request.get("module")
|
|
165
|
-
class_name = request.get("class")
|
|
166
|
-
|
|
167
|
-
if not module_name or not class_name:
|
|
168
|
-
response["error"] = {
|
|
169
|
-
"code": -32602,
|
|
170
|
-
"message": "Missing 'module' or 'class' in request",
|
|
171
|
-
}
|
|
172
|
-
transport.send(response)
|
|
173
|
-
continue
|
|
174
|
-
|
|
175
|
-
# Get or create instance
|
|
176
|
-
try:
|
|
177
|
-
instance = get_instance(module_name, class_name)
|
|
178
|
-
except Exception as e:
|
|
179
|
-
response["error"] = {
|
|
180
|
-
"code": -32000,
|
|
181
|
-
"message": f"Failed to import {module_name}.{class_name}: {e}",
|
|
182
|
-
"data": {"traceback": traceback.format_exc()}
|
|
183
|
-
}
|
|
184
|
-
transport.send(response)
|
|
185
|
-
continue
|
|
186
|
-
|
|
187
|
-
# Get the method
|
|
188
|
-
method = getattr(instance, method_name, None)
|
|
189
|
-
if method is None:
|
|
190
|
-
response["error"] = {
|
|
191
|
-
"code": -32601,
|
|
192
|
-
"message": f"Method not found: {method_name}",
|
|
193
|
-
}
|
|
194
|
-
transport.send(response)
|
|
195
|
-
continue
|
|
196
|
-
|
|
197
|
-
# Deserialize arguments
|
|
198
|
-
deserialized_params = {}
|
|
199
|
-
for key, value in params.items():
|
|
200
|
-
deserialized_params[key] = deserialize_arg(value)
|
|
201
|
-
|
|
202
|
-
# For legacy stdio transport, redirect stdout to stderr during execution
|
|
203
|
-
# This prevents print() in node code from corrupting JSON protocol
|
|
204
|
-
# (UDS transport doesn't need this since it uses a separate socket)
|
|
205
|
-
if not use_uds:
|
|
206
|
-
original_stdout = sys.stdout
|
|
207
|
-
sys.stdout = sys.stderr
|
|
208
|
-
|
|
209
|
-
# Also redirect at file descriptor level for C libraries
|
|
210
|
-
stdout_fd = original_stdout.fileno()
|
|
211
|
-
stderr_fd = sys.stderr.fileno()
|
|
212
|
-
stdout_fd_copy = os.dup(stdout_fd)
|
|
213
|
-
os.dup2(stderr_fd, stdout_fd)
|
|
214
|
-
|
|
215
|
-
# Call the method
|
|
216
|
-
print(f"[Runner] Calling {class_name}.{method_name}...", file=sys.stderr)
|
|
217
|
-
try:
|
|
218
|
-
result = method(**deserialized_params)
|
|
219
|
-
finally:
|
|
220
|
-
if not use_uds:
|
|
221
|
-
# Restore file descriptor first, then Python stdout
|
|
222
|
-
os.dup2(stdout_fd_copy, stdout_fd)
|
|
223
|
-
os.close(stdout_fd_copy)
|
|
224
|
-
sys.stdout = original_stdout
|
|
225
|
-
|
|
226
|
-
# Serialize result
|
|
227
|
-
serialized_result = serialize_result(result)
|
|
228
|
-
response["result"] = serialized_result
|
|
229
|
-
|
|
230
|
-
print(f"[Runner] {class_name}.{method_name} completed", file=sys.stderr)
|
|
231
|
-
|
|
232
|
-
except ConnectionError as e:
|
|
233
|
-
# Socket closed - normal shutdown
|
|
234
|
-
print(f"[Runner] Connection closed: {e}", file=sys.stderr)
|
|
235
|
-
break
|
|
236
|
-
except Exception as e:
|
|
237
|
-
tb = traceback.format_exc()
|
|
238
|
-
print(f"[Runner] Error: {e}", file=sys.stderr)
|
|
239
|
-
print(tb, file=sys.stderr)
|
|
240
|
-
response["error"] = {
|
|
241
|
-
"code": -32000,
|
|
242
|
-
"message": str(e),
|
|
243
|
-
"data": {"traceback": tb}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
try:
|
|
247
|
-
transport.send(response)
|
|
248
|
-
except ConnectionError:
|
|
249
|
-
break
|
|
250
|
-
|
|
251
|
-
finally:
|
|
252
|
-
transport.close()
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
def main():
|
|
256
|
-
parser = argparse.ArgumentParser(description="Isolated node runner")
|
|
257
|
-
parser.add_argument("--node-dir", required=True, help="Node package directory")
|
|
258
|
-
parser.add_argument("--comfyui-base", help="ComfyUI base directory")
|
|
259
|
-
parser.add_argument("--import-paths", help="Comma-separated import paths")
|
|
260
|
-
parser.add_argument("--socket", help="Unix domain socket path (if not provided, uses stdin/stdout)")
|
|
261
|
-
|
|
262
|
-
args = parser.parse_args()
|
|
263
|
-
|
|
264
|
-
run_worker(
|
|
265
|
-
node_dir=args.node_dir,
|
|
266
|
-
comfyui_base=args.comfyui_base,
|
|
267
|
-
import_paths=args.import_paths,
|
|
268
|
-
socket_path=args.socket,
|
|
269
|
-
)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
if __name__ == "__main__":
|
|
273
|
-
main()
|
comfy_env-0.0.8.dist-info/RECORD
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
comfy_env/__init__.py,sha256=U5XtB2UeXZi8JPBhlh0XjQprLsAuVslPoJNWOSvCFhs,4249
|
|
2
|
-
comfy_env/cli.py,sha256=9GvQYrXlJRl0ZaCuFHvRtVxWQ34Axd5Brgu5FWRONp4,11424
|
|
3
|
-
comfy_env/decorator.py,sha256=daFR5aLzshkmo5sRKhSGPcTUgIUWml7Gs6A1bfnDuyc,15718
|
|
4
|
-
comfy_env/errors.py,sha256=egeyXY-j7KpxyA0s67TcJLEfJX23LCAD3v1P4FgQIGE,10917
|
|
5
|
-
comfy_env/install.py,sha256=JaatBM5PyY4Ua6E2HgkLAlFZ2TSEjlI-lAwJ-Hl7wU8,18876
|
|
6
|
-
comfy_env/registry.py,sha256=iZprw2iIAJl-Vvotsf_B_PofzqE-6IiVfNPBHYUYg6g,11577
|
|
7
|
-
comfy_env/resolver.py,sha256=xz7GPlxy02iwwpocIzzbdGnrwnSpi-D5IzpL8SQSgvI,12893
|
|
8
|
-
comfy_env/runner.py,sha256=0YUqzK93u--7pKV6_yVC564AJE9rS3y81t5ZhQi2t4Y,9696
|
|
9
|
-
comfy_env/env/__init__.py,sha256=sybOBrxJCfL4Xry9NNd5xwn9hXIHudXlXDa7SpJkPCE,811
|
|
10
|
-
comfy_env/env/config.py,sha256=fL2P0ScoioPktZEHQnoo1dy-VB5intJEYLHm5fuOmF8,5406
|
|
11
|
-
comfy_env/env/config_file.py,sha256=QLf3WPCqx46v1kVzM4jV_QAz919zmkk0_FRtLD3jO8s,19507
|
|
12
|
-
comfy_env/env/detection.py,sha256=Co8BJmTRCq1ZHDsm6832jF87za0GRAhH7zF04-5QwcE,4949
|
|
13
|
-
comfy_env/env/manager.py,sha256=ysIVlpxRD5x-5X47ESmfly2Vz6jv-9yA6863szHf7-8,24131
|
|
14
|
-
comfy_env/env/security.py,sha256=dNSitAnfBNVdvxgBBntYw33AJaCs_S1MHb7KJhAVYzM,8171
|
|
15
|
-
comfy_env/env/platform/__init__.py,sha256=Nb5MPZIEeanSMEWwqU4p4bnEKTJn1tWcwobnhq9x9IY,614
|
|
16
|
-
comfy_env/env/platform/base.py,sha256=iS0ptTTVjXRwPU4qWUdvHI7jteuzxGSjWr5BUQ7hGiU,2453
|
|
17
|
-
comfy_env/env/platform/darwin.py,sha256=HK3VkLT6DfesAnIXwx2IaUFHTBclF0xTQnC7azWY6Kc,1552
|
|
18
|
-
comfy_env/env/platform/linux.py,sha256=xLp8FEbFqZLQrzIZBI9z3C4g23Ab1ASTHLsXDzsdCoA,2062
|
|
19
|
-
comfy_env/env/platform/windows.py,sha256=nD1-bKU2rGmEJlS-cc5yWXMSA51YQtVupn-lQEO5UYA,14840
|
|
20
|
-
comfy_env/ipc/__init__.py,sha256=pTjgJn5YJxLXmEvuKh3lkCEJQs-6W6_F01jfkFMUi0c,1375
|
|
21
|
-
comfy_env/ipc/bridge.py,sha256=kEy__kco8FVQNj5MyadF5k00YEivcGmifAJAOfr643U,17645
|
|
22
|
-
comfy_env/ipc/protocol.py,sha256=gfWe5yEDUn4QWhcdWFcxn40GqxlW1Uf23j0edOzPPng,7951
|
|
23
|
-
comfy_env/ipc/tensor.py,sha256=DyU28GymKkLPVwzZyKdm2Av222hdaycMgv3KdL5mtO0,12009
|
|
24
|
-
comfy_env/ipc/torch_bridge.py,sha256=WzdwDJa3N_1fEl9OeZxikvMbwryO5P63o0WmEDpS18A,13206
|
|
25
|
-
comfy_env/ipc/transport.py,sha256=XQlRcfQsd4nd909KIYnZKvsS3ksGpGjyVucn8jvmLIU,9698
|
|
26
|
-
comfy_env/ipc/worker.py,sha256=oxTLF9xXrl8CRx_JVNBdkxZh35NuzfkdxhaUtUuXogs,6661
|
|
27
|
-
comfy_env/stubs/__init__.py,sha256=jMeWEKY30y8QqYX9AUyuZbmm607erQTc4N7YaDoAH00,38
|
|
28
|
-
comfy_env/stubs/folder_paths.py,sha256=KEH9ntMH6HOgE595G5dBL9kSTEUvf_shYtQKIyiiDbk,1586
|
|
29
|
-
comfy_env/workers/__init__.py,sha256=IKZwOvrWOGqBLDUIFAalg4CdqzJ_YnAdxo2Ha7gZTJ0,1467
|
|
30
|
-
comfy_env/workers/base.py,sha256=ZILYXlvGCWuCZXmjKqfG8VeD19ihdYaASdlbasl2BMo,2312
|
|
31
|
-
comfy_env/workers/pool.py,sha256=MtjeOWfvHSCockq8j1gfnxIl-t01GSB79T5N4YB82Lg,6956
|
|
32
|
-
comfy_env/workers/tensor_utils.py,sha256=TCuOAjJymrSbkgfyvcKtQ_KbVWTqSwP9VH_bCaFLLq8,6409
|
|
33
|
-
comfy_env/workers/torch_mp.py,sha256=DsfxE3LBAWEuGtk-p-YL0UhVQ7VDh73KT_TFRxYN4-Q,12563
|
|
34
|
-
comfy_env/workers/venv.py,sha256=_ekHfZPqBIPY08DjqiXm6cTBQH4DrbxRWR3AAv3mit8,31589
|
|
35
|
-
comfy_env-0.0.8.dist-info/METADATA,sha256=mir9pZymbCPcnI6yc1YrjxyMMnX3qm3pUR7NILB5iCE,5371
|
|
36
|
-
comfy_env-0.0.8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
37
|
-
comfy_env-0.0.8.dist-info/entry_points.txt,sha256=J4fXeqgxU_YenuW_Zxn_pEL7J-3R0--b6MS5t0QmAr0,49
|
|
38
|
-
comfy_env-0.0.8.dist-info/licenses/LICENSE,sha256=E68QZMMpW4P2YKstTZ3QU54HRQO8ecew09XZ4_Vn870,1093
|
|
39
|
-
comfy_env-0.0.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|