comfy-env 0.0.52__tar.gz → 0.0.54__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 (49) hide show
  1. {comfy_env-0.0.52 → comfy_env-0.0.54}/PKG-INFO +1 -1
  2. {comfy_env-0.0.52 → comfy_env-0.0.54}/pyproject.toml +1 -1
  3. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/decorator.py +4 -4
  4. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/env/cuda_gpu_detection.py +1 -1
  5. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/errors.py +1 -1
  6. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/install.py +4 -4
  7. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/pixi.py +34 -4
  8. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/workers/venv.py +15 -1
  9. {comfy_env-0.0.52 → comfy_env-0.0.54}/.github/workflows/publish.yml +0 -0
  10. {comfy_env-0.0.52 → comfy_env-0.0.54}/.gitignore +0 -0
  11. {comfy_env-0.0.52 → comfy_env-0.0.54}/LICENSE +0 -0
  12. {comfy_env-0.0.52 → comfy_env-0.0.54}/README.md +0 -0
  13. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/__init__.py +0 -0
  14. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/cli.py +0 -0
  15. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/env/__init__.py +0 -0
  16. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/env/config.py +0 -0
  17. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/env/config_file.py +0 -0
  18. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/env/manager.py +0 -0
  19. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/env/platform/__init__.py +0 -0
  20. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/env/platform/base.py +0 -0
  21. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/env/platform/darwin.py +0 -0
  22. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/env/platform/linux.py +0 -0
  23. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/env/platform/windows.py +0 -0
  24. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/env/security.py +0 -0
  25. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/ipc/__init__.py +0 -0
  26. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/ipc/bridge.py +0 -0
  27. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/ipc/protocol.py +0 -0
  28. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/ipc/tensor.py +0 -0
  29. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/ipc/torch_bridge.py +0 -0
  30. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/ipc/transport.py +0 -0
  31. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/ipc/worker.py +0 -0
  32. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/isolation.py +0 -0
  33. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/nodes.py +0 -0
  34. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/registry.py +0 -0
  35. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/resolver.py +0 -0
  36. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/stub_imports.py +0 -0
  37. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/stubs/__init__.py +0 -0
  38. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/stubs/comfy/__init__.py +0 -0
  39. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/stubs/comfy/model_management.py +0 -0
  40. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/stubs/comfy/utils.py +0 -0
  41. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/stubs/folder_paths.py +0 -0
  42. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/templates/comfy-env-instructions.txt +0 -0
  43. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/templates/comfy-env.toml +0 -0
  44. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/wheel_sources.yml +0 -0
  45. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/workers/__init__.py +0 -0
  46. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/workers/base.py +0 -0
  47. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/workers/pool.py +0 -0
  48. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/workers/tensor_utils.py +0 -0
  49. {comfy_env-0.0.52 → comfy_env-0.0.54}/src/comfy_env/workers/torch_mp.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comfy-env
3
- Version: 0.0.52
3
+ Version: 0.0.54
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.52"
3
+ version = "0.0.54"
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"}
@@ -382,7 +382,7 @@ def isolated(
382
382
 
383
383
  # Log entry with argument descriptions
384
384
  if VERBOSE_LOGGING:
385
- log_fn(f" {cls.__name__}.{func_name}({_describe_args(call_kwargs)})")
385
+ log_fn(f"-> {cls.__name__}.{func_name}({_describe_args(call_kwargs)})")
386
386
 
387
387
  start_time = time.time()
388
388
 
@@ -425,13 +425,13 @@ def isolated(
425
425
  elapsed = time.time() - start_time
426
426
  if VERBOSE_LOGGING:
427
427
  result_desc = _describe_tensor(result) if not isinstance(result, tuple) else f"tuple({len(result)} items)"
428
- log_fn(f" {cls.__name__}.{func_name} returned {result_desc} [{elapsed:.2f}s]")
428
+ log_fn(f"<- {cls.__name__}.{func_name} returned {result_desc} [{elapsed:.2f}s]")
429
429
 
430
430
  return result
431
431
 
432
432
  except Exception as e:
433
433
  elapsed = time.time() - start_time
434
- log_fn(f" {cls.__name__}.{func_name} failed after {elapsed:.2f}s: {e}")
434
+ log_fn(f"[FAIL] {cls.__name__}.{func_name} failed after {elapsed:.2f}s: {e}")
435
435
  raise
436
436
 
437
437
  # Store original method before replacing (for worker to access)
@@ -689,7 +689,7 @@ def auto_isolate(func: Callable) -> Callable:
689
689
  )
690
690
 
691
691
  elapsed = time.time() - start_time
692
- _log(env_name, f" {func.__name__} completed in isolated env [{elapsed:.2f}s]")
692
+ _log(env_name, f"<- {func.__name__} completed in isolated env [{elapsed:.2f}s]")
693
693
 
694
694
  return result
695
695
 
@@ -1,7 +1,7 @@
1
1
  """
2
2
  Robust CUDA/GPU detection with multiple fallback methods.
3
3
 
4
- Detection priority: NVML PyTorch nvidia-smi sysfs env vars
4
+ Detection priority: NVML -> PyTorch -> nvidia-smi -> sysfs -> env vars
5
5
  """
6
6
 
7
7
  from __future__ import annotations
@@ -229,7 +229,7 @@ class DependencyError(EnvManagerError):
229
229
  # Skip empty lines and progress bars
230
230
  if not line.strip():
231
231
  continue
232
- if line.startswith(" ") and ("%" in line or "━" in line):
232
+ if line.startswith(" ") and "%" in line:
233
233
  continue
234
234
 
235
235
  # Keep error lines and important info
@@ -2,8 +2,8 @@
2
2
  Installation API for comfy-env.
3
3
 
4
4
  This module provides the main `install()` function that handles:
5
- - Named environments [envname] pixi (isolated Python environment)
6
- - Local packages [local] uv/pip (in-place to current Python)
5
+ - Named environments [envname] -> pixi (isolated Python environment)
6
+ - Local packages [local] -> uv/pip (in-place to current Python)
7
7
 
8
8
  Example:
9
9
  from comfy_env import install
@@ -183,7 +183,7 @@ def install(
183
183
  user_wheel_sources = full_config.wheel_sources if hasattr(full_config, 'wheel_sources') else {}
184
184
 
185
185
  if env_config:
186
- # Named environment always pixi
186
+ # Named environment -> always pixi
187
187
  log(f"Found environment: {env_config.name}")
188
188
  python_ver = env_config.python or "3.11" # Default to 3.11 if not specified
189
189
  if not env_config.python:
@@ -204,7 +204,7 @@ def install(
204
204
  log(f" Using pixi backend (Python {python_ver})")
205
205
  return pixi_install(env_config, node_dir, log, dry_run)
206
206
  elif full_config.has_local:
207
- # [local] section uv in-place install
207
+ # [local] section -> uv in-place install
208
208
  return _install_local(full_config.local, node_dir, log, dry_run, user_wheel_sources)
209
209
  else:
210
210
  log("No packages to install")
@@ -203,10 +203,12 @@ def create_pixi_toml(
203
203
  Returns:
204
204
  Path to the generated pixi.toml file.
205
205
  """
206
- if not env_config.conda:
207
- raise ValueError("Environment has no conda configuration")
208
-
209
- conda = env_config.conda
206
+ # Conda is optional - use defaults if not present
207
+ if env_config.conda:
208
+ conda = env_config.conda
209
+ else:
210
+ from comfy_env.env.config import CondaConfig
211
+ conda = CondaConfig(channels=["conda-forge"], packages=[])
210
212
  pixi_toml_path = node_dir / "pixi.toml"
211
213
 
212
214
  # Build pixi.toml content
@@ -375,6 +377,34 @@ def create_pixi_toml(
375
377
  lines.append(f'{name} = {value}')
376
378
 
377
379
  for dep in pypi_deps:
380
+ # Handle git dependencies in two formats:
381
+ # 1. pkg @ git+https://github.com/user/repo.git@commit
382
+ # 2. git+https://github.com/user/repo.git@commit (extract name from URL)
383
+ if "git+" in dep:
384
+ if " @ git+" in dep:
385
+ # Format: pkg @ git+URL@commit
386
+ match = re.match(r'^([a-zA-Z0-9._-]+)\s*@\s*git\+(.+?)(?:@([a-f0-9]+))?$', dep)
387
+ if match:
388
+ pkg_name = match.group(1)
389
+ git_url = match.group(2)
390
+ rev = match.group(3)
391
+ else:
392
+ # Format: git+URL@commit (extract package name from repo name)
393
+ match = re.match(r'^git\+(.+?)(?:@([a-f0-9]+))?$', dep)
394
+ if match:
395
+ git_url = match.group(1)
396
+ rev = match.group(2)
397
+ # Extract package name from URL (repo name without .git)
398
+ repo_match = re.search(r'/([^/]+?)(?:\.git)?$', git_url)
399
+ pkg_name = repo_match.group(1) if repo_match else git_url.split('/')[-1].replace('.git', '')
400
+
401
+ if match:
402
+ if rev:
403
+ lines.append(f'{pkg_name} = {{ git = "{git_url}", rev = "{rev}" }}')
404
+ else:
405
+ lines.append(f'{pkg_name} = {{ git = "{git_url}" }}')
406
+ continue
407
+
378
408
  # Parse pip requirement format to pixi format
379
409
  # Handles extras like trimesh[easy]>=4.0.0
380
410
  name, version_spec, extras = _parse_pypi_requirement(dep)
@@ -671,8 +671,12 @@ def _should_use_reference(obj):
671
671
  # Primitives - pass by value
672
672
  if isinstance(obj, (bool, int, float, str, bytes)):
673
673
  return False
674
- # NumPy arrays and torch tensors - pass by value (they serialize well)
674
+ # NumPy scalars - pass by value (convert to Python primitives)
675
675
  obj_type = type(obj).__name__
676
+ if obj_type in ('float16', 'float32', 'float64', 'int8', 'int16', 'int32', 'int64',
677
+ 'uint8', 'uint16', 'uint32', 'uint64', 'bool_'):
678
+ return False
679
+ # NumPy arrays and torch tensors - pass by value (they serialize well)
676
680
  if obj_type in ('ndarray', 'Tensor'):
677
681
  return False
678
682
  # Dicts, lists, tuples - recurse into contents (don't ref the container)
@@ -705,6 +709,16 @@ def _serialize_result(obj, visited=None):
705
709
  return [_serialize_result(v, visited) for v in obj]
706
710
  if isinstance(obj, tuple):
707
711
  return tuple(_serialize_result(v, visited) for v in obj)
712
+
713
+ # Convert numpy scalars to Python primitives for JSON serialization
714
+ obj_type = type(obj).__name__
715
+ if obj_type in ('float16', 'float32', 'float64'):
716
+ return float(obj)
717
+ if obj_type in ('int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64'):
718
+ return int(obj)
719
+ if obj_type == 'bool_':
720
+ return bool(obj)
721
+
708
722
  return obj
709
723
 
710
724
  def _deserialize_input(obj):
File without changes
File without changes
File without changes