comfy-env 0.0.71__tar.gz → 0.0.72__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 (34) hide show
  1. {comfy_env-0.0.71 → comfy_env-0.0.72}/PKG-INFO +1 -1
  2. {comfy_env-0.0.71 → comfy_env-0.0.72}/pyproject.toml +1 -1
  3. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/cli.py +96 -0
  4. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/config/parser.py +6 -1
  5. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/config/types.py +3 -0
  6. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/prestartup.py +38 -3
  7. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/templates/comfy-env.toml +16 -1
  8. {comfy_env-0.0.71 → comfy_env-0.0.72}/.github/workflows/ci.yml +0 -0
  9. {comfy_env-0.0.71 → comfy_env-0.0.72}/.github/workflows/publish.yml +0 -0
  10. {comfy_env-0.0.71 → comfy_env-0.0.72}/.gitignore +0 -0
  11. {comfy_env-0.0.71 → comfy_env-0.0.72}/LICENSE +0 -0
  12. {comfy_env-0.0.71 → comfy_env-0.0.72}/README.md +0 -0
  13. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/__init__.py +0 -0
  14. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/config/__init__.py +0 -0
  15. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/errors.py +0 -0
  16. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/install.py +0 -0
  17. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/isolation/__init__.py +0 -0
  18. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/isolation/wrap.py +0 -0
  19. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/nodes.py +0 -0
  20. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/pixi/__init__.py +0 -0
  21. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/pixi/core.py +0 -0
  22. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/pixi/cuda_detection.py +0 -0
  23. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/pixi/platform/__init__.py +0 -0
  24. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/pixi/platform/base.py +0 -0
  25. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/pixi/platform/darwin.py +0 -0
  26. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/pixi/platform/linux.py +0 -0
  27. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/pixi/platform/windows.py +0 -0
  28. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/pixi/resolver.py +0 -0
  29. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/templates/comfy-env-instructions.txt +0 -0
  30. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/workers/__init__.py +0 -0
  31. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/workers/base.py +0 -0
  32. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/workers/mp.py +0 -0
  33. {comfy_env-0.0.71 → comfy_env-0.0.72}/src/comfy_env/workers/subprocess.py +0 -0
  34. {comfy_env-0.0.71 → comfy_env-0.0.72}/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.71
3
+ Version: 0.0.72
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "comfy-env"
3
- version = "0.0.71"
3
+ version = "0.0.72"
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"}
@@ -119,6 +119,23 @@ def main(args: Optional[List[str]] = None) -> int:
119
119
  help="Path to config file",
120
120
  )
121
121
 
122
+ # apt-install command
123
+ apt_parser = subparsers.add_parser(
124
+ "apt-install",
125
+ help="Install system packages from [apt] section (Linux only)",
126
+ description="Read [apt] packages from comfy-env.toml and install via apt-get",
127
+ )
128
+ apt_parser.add_argument(
129
+ "--config", "-c",
130
+ type=str,
131
+ help="Path to comfy-env.toml (default: auto-discover)",
132
+ )
133
+ apt_parser.add_argument(
134
+ "--dry-run",
135
+ action="store_true",
136
+ help="Show what would be installed without installing",
137
+ )
138
+
122
139
  parsed = parser.parse_args(args)
123
140
 
124
141
  if parsed.command is None:
@@ -136,6 +153,8 @@ def main(args: Optional[List[str]] = None) -> int:
136
153
  return cmd_info(parsed)
137
154
  elif parsed.command == "doctor":
138
155
  return cmd_doctor(parsed)
156
+ elif parsed.command == "apt-install":
157
+ return cmd_apt_install(parsed)
139
158
  else:
140
159
  parser.print_help()
141
160
  return 1
@@ -332,5 +351,82 @@ def cmd_doctor(args) -> int:
332
351
  return 0
333
352
 
334
353
 
354
+ def cmd_apt_install(args) -> int:
355
+ """Handle apt-install command - install system packages from [apt] section."""
356
+ import os
357
+ import shutil
358
+ import subprocess
359
+ import platform
360
+
361
+ if platform.system() != "Linux":
362
+ print("apt-install is only supported on Linux", file=sys.stderr)
363
+ return 1
364
+
365
+ # Find config
366
+ if args.config:
367
+ config_path = Path(args.config).resolve()
368
+ else:
369
+ config_path = Path.cwd() / "comfy-env.toml"
370
+
371
+ if not config_path.exists():
372
+ print(f"Config file not found: {config_path}", file=sys.stderr)
373
+ return 1
374
+
375
+ # Parse config to get apt packages
376
+ from .config.parser import load_config
377
+ config = load_config(config_path)
378
+
379
+ if not config.apt_packages:
380
+ print("No [apt] packages specified in config")
381
+ return 0
382
+
383
+ packages = config.apt_packages
384
+ print(f"Found {len(packages)} apt package(s) to install:")
385
+ for pkg in packages:
386
+ print(f" - {pkg}")
387
+
388
+ # Determine if we need sudo
389
+ is_root = os.geteuid() == 0
390
+ has_sudo = shutil.which("sudo") is not None
391
+ use_sudo = not is_root and has_sudo
392
+
393
+ prefix = ["sudo"] if use_sudo else []
394
+
395
+ if args.dry_run:
396
+ print("\n[Dry run] Would run:")
397
+ prefix_str = "sudo " if use_sudo else ""
398
+ print(f" {prefix_str}apt-get update && {prefix_str}apt-get install -y {' '.join(packages)}")
399
+ return 0
400
+
401
+ if not is_root and not has_sudo:
402
+ print("\nError: Need root privileges to install apt packages.", file=sys.stderr)
403
+ print("Run manually with:", file=sys.stderr)
404
+ print(f" sudo apt-get update && sudo apt-get install -y {' '.join(packages)}", file=sys.stderr)
405
+ return 1
406
+
407
+ # Run apt-get update
408
+ print("\nUpdating package lists...")
409
+ result = subprocess.run(
410
+ prefix + ["apt-get", "update"],
411
+ capture_output=False,
412
+ )
413
+ if result.returncode != 0:
414
+ print("Warning: apt-get update failed, continuing anyway...")
415
+
416
+ # Run apt-get install
417
+ print(f"\nInstalling: {' '.join(packages)}")
418
+ result = subprocess.run(
419
+ prefix + ["apt-get", "install", "-y"] + packages,
420
+ capture_output=False,
421
+ )
422
+
423
+ if result.returncode == 0:
424
+ print("\nSystem packages installed successfully!")
425
+ return 0
426
+ else:
427
+ print("\nFailed to install some packages", file=sys.stderr)
428
+ return result.returncode
429
+
430
+
335
431
  if __name__ == "__main__":
336
432
  sys.exit(main())
@@ -49,7 +49,7 @@ from .types import ComfyEnvConfig, NodeReq
49
49
  CONFIG_FILE_NAME = "comfy-env.toml"
50
50
 
51
51
  # Sections we handle specially (not passed through to pixi.toml)
52
- CUSTOM_SECTIONS = {"python", "cuda", "node_reqs", "apt"}
52
+ CUSTOM_SECTIONS = {"python", "cuda", "node_reqs", "apt", "env_vars"}
53
53
 
54
54
 
55
55
  def load_config(path: Path) -> ComfyEnvConfig:
@@ -120,6 +120,10 @@ def _parse_config(data: Dict[str, Any]) -> ComfyEnvConfig:
120
120
  apt_data = data.pop("apt", {})
121
121
  apt_packages = _ensure_list(apt_data.get("packages", []))
122
122
 
123
+ # Extract [env_vars] section
124
+ env_vars_data = data.pop("env_vars", {})
125
+ env_vars = {str(k): str(v) for k, v in env_vars_data.items()}
126
+
123
127
  # Extract [node_reqs] section
124
128
  node_reqs_data = data.pop("node_reqs", {})
125
129
  node_reqs = _parse_node_reqs(node_reqs_data)
@@ -131,6 +135,7 @@ def _parse_config(data: Dict[str, Any]) -> ComfyEnvConfig:
131
135
  python=python_version,
132
136
  cuda_packages=cuda_packages,
133
137
  apt_packages=apt_packages,
138
+ env_vars=env_vars,
134
139
  node_reqs=node_reqs,
135
140
  pixi_passthrough=pixi_passthrough,
136
141
  )
@@ -56,6 +56,9 @@ class ComfyEnvConfig:
56
56
  # [apt] - System packages to install via apt (Linux only)
57
57
  apt_packages: List[str] = field(default_factory=list)
58
58
 
59
+ # [env_vars] - Environment variables to set early (in prestartup)
60
+ env_vars: Dict[str, str] = field(default_factory=dict)
61
+
59
62
  # [node_reqs] - other ComfyUI nodes to clone
60
63
  node_reqs: List[NodeReq] = field(default_factory=list)
61
64
 
@@ -8,7 +8,35 @@ import glob
8
8
  import os
9
9
  import sys
10
10
  from pathlib import Path
11
- from typing import Optional
11
+ from typing import Optional, Dict
12
+
13
+
14
+ def _load_env_vars(config_path: str) -> Dict[str, str]:
15
+ """
16
+ Load [env_vars] section from comfy-env.toml.
17
+
18
+ Uses tomllib (Python 3.11+) or tomli fallback.
19
+ Returns empty dict if file not found or parsing fails.
20
+ """
21
+ if not os.path.exists(config_path):
22
+ return {}
23
+
24
+ try:
25
+ if sys.version_info >= (3, 11):
26
+ import tomllib
27
+ else:
28
+ try:
29
+ import tomli as tomllib
30
+ except ImportError:
31
+ return {}
32
+
33
+ with open(config_path, "rb") as f:
34
+ data = tomllib.load(f)
35
+
36
+ env_vars_data = data.get("env_vars", {})
37
+ return {str(k): str(v) for k, v in env_vars_data.items()}
38
+ except Exception:
39
+ return {}
12
40
 
13
41
 
14
42
  def setup_env(node_dir: Optional[str] = None) -> None:
@@ -16,8 +44,9 @@ def setup_env(node_dir: Optional[str] = None) -> None:
16
44
  Set up environment for pixi conda libraries.
17
45
 
18
46
  Call this in prestartup_script.py before any native library imports.
19
- Sets LD_LIBRARY_PATH (Linux/Mac) or PATH (Windows) for conda libs,
20
- and adds pixi site-packages to sys.path.
47
+ - Applies [env_vars] from comfy-env.toml first (for OpenMP settings, etc.)
48
+ - Sets LD_LIBRARY_PATH (Linux/Mac) or PATH (Windows) for conda libs
49
+ - Adds pixi site-packages to sys.path
21
50
 
22
51
  Args:
23
52
  node_dir: Path to the custom node directory. Auto-detected if not provided.
@@ -33,6 +62,12 @@ def setup_env(node_dir: Optional[str] = None) -> None:
33
62
  frame = inspect.stack()[1]
34
63
  node_dir = str(Path(frame.filename).parent)
35
64
 
65
+ # Apply [env_vars] from comfy-env.toml FIRST (before any library loading)
66
+ config_path = os.path.join(node_dir, "comfy-env.toml")
67
+ env_vars = _load_env_vars(config_path)
68
+ for key, value in env_vars.items():
69
+ os.environ[key] = value
70
+
36
71
  pixi_env = os.path.join(node_dir, ".pixi", "envs", "default")
37
72
 
38
73
  if not os.path.exists(pixi_env):
@@ -3,7 +3,7 @@
3
3
  # =============================================================================
4
4
  #
5
5
  # comfy-env.toml is a SUPERSET of pixi.toml. All pixi.toml syntax works here.
6
- # We add custom sections: [cuda], [node_reqs], and top-level `python = "x.x"`.
6
+ # We add custom sections: [cuda], [node_reqs], [env_vars], and top-level `python = "x.x"`.
7
7
  #
8
8
  # GPU is auto-detected to select the right CUDA version.
9
9
  #
@@ -22,6 +22,21 @@
22
22
  # python = "3.11"
23
23
 
24
24
 
25
+ # =============================================================================
26
+ # ENVIRONMENT VARIABLES (custom section)
27
+ # =============================================================================
28
+ # Environment variables applied early via setup_env() in prestartup_script.py.
29
+ # Useful for OpenMP settings, library configs, etc. that must be set before imports.
30
+ #
31
+ # Requires prestartup_script.py in your node directory:
32
+ # from comfy_env import setup_env
33
+ # setup_env()
34
+
35
+ [env_vars]
36
+ # KMP_DUPLICATE_LIB_OK = "TRUE" # Allow duplicate OpenMP libraries (macOS fix)
37
+ # OMP_NUM_THREADS = "4" # Limit OpenMP threads
38
+
39
+
25
40
  # =============================================================================
26
41
  # CUDA PACKAGES (custom section)
27
42
  # =============================================================================
File without changes
File without changes
File without changes