diff --git a/.github/workflows/uv-build.yml b/.github/workflows/uv-build.yml new file mode 100644 index 000000000..48e8a9af6 --- /dev/null +++ b/.github/workflows/uv-build.yml @@ -0,0 +1,26 @@ +name: Build and Test + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Install uv + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh + echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: Install dependencies + run: | + uv pip install -r requirements.txt + uv pip install -r requirements_advanced.txt + # Additional steps... diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 048f127e7..e55e09a6c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,6 +35,44 @@ If you cannot find an existing issue that describes your bug or feature, create * Please refer to the article on [creating pull requests](https://github.com/comfyanonymous/ComfyUI/wiki/How-to-Contribute-Code) and contributing to this project. +## Development Environment Setup + +### Setting Up with UV (Recommended) + +*Added 2025-05-02 by kairin* + +We recommend using [UV](https://github.com/astral-sh/uv) for faster, more reliable package management: + +1. **Install UV**: + ```bash + curl -LsSf https://astral.sh/uv/install.sh | sh + source $HOME/.local/bin/env # For bash/zsh + ``` + +2. **Set up development environment**: + ```bash + git clone https://github.com/comfyanonymous/ComfyUI.git + cd ComfyUI + + # Create virtual environment + uv venv + source .venv/bin/activate # Linux/macOS + # or + .venv\Scripts\activate # Windows + + # Install dependencies + uv pip install -r requirements.txt + + # Install development dependencies + uv add --dev pytest black isort + ``` + +3. **Install in development mode**: + ```bash + uv pip install -e . + ``` + +### Working with Dependencies ## Thank You diff --git a/README.md b/README.md index 0f39cfce2..92e014a69 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,35 @@ Put your SD checkpoints (the huge ckpt/safetensors files) in: models/checkpoints Put your VAE in: models/vae +## Installation Options + +### Option 1: Install with UV (Recommended) + +*Added 2025-05-02* + +[UV](https://github.com/astral-sh/uv) is a faster, more reliable Python package installer that we now recommend for ComfyUI. + +1. **Install UV**: + ```bash + curl -LsSf https://astral.sh/uv/install.sh | sh + source $HOME/.local/bin/env # For bash/zsh + ``` + +2. **Install ComfyUI dependencies**: + ```bash + # Create and activate virtual environment + uv venv + source .venv/bin/activate # Linux/macOS + # or + .venv\Scripts\activate # Windows + + # Install dependencies + uv pip install -r requirements.txt + ``` + +For detailed instructions on using UV with ComfyUI, see our [UV Migration Guide](UV_MIGRATION.md). + +### Option 2: Install with pip (Traditional) ### AMD GPUs (Linux only) AMD users can install rocm and pytorch with pip if you don't have it already installed, this is the command to install the stable version: diff --git a/UV_MIGRATION.md b/UV_MIGRATION.md new file mode 100644 index 000000000..cbf45cf23 --- /dev/null +++ b/UV_MIGRATION.md @@ -0,0 +1,83 @@ +# ComfyUI Migration to UV Package Manager + +## What is UV? + +[UV](https://github.com/astral-sh/uv) is a modern Python package installer and resolver written in Rust. It serves as a drop-in replacement for pip with significant performance improvements: + +- **Speed**: UV installs packages 10-100x faster than pip +- **Reliability**: Better dependency resolution to avoid conflicts +- **Compatibility**: Works with existing requirements.txt files +- **Modern**: Built with Rust for performance and safety + +## Why Migrate from pip to UV? + +- Faster installation of dependencies +- Improved virtual environment management +- Better handling of dependency conflicts +- Consistent installation experience across platforms +- Compatibility with existing pip workflows + +## Installation + +Install UV: + +```bash +# Install UV +curl -LsSf https://astral.sh/uv/install.sh | sh + +# Add to PATH (bash/zsh) +source $HOME/.local/bin/env + +# Or for fish shell +# source $HOME/.local/bin/env.fish +``` + +## Using UV with ComfyUI + +### Basic Usage + +```bash +# Create a virtual environment +uv venv +source .venv/bin/activate # On Linux/macOS +# .venv\Scripts\activate # On Windows + +# Install dependencies +uv pip install -r requirements.txt + +# Install advanced dependencies (if needed) +uv pip install -r requirements_advanced.txt +``` + +### UV Native Commands + +Instead of using the pip-compatible interface, you can use UV's native commands: + +```bash +# Install packages +uv add packagename + +# Install dev dependencies +uv add --dev pytest black + +# View dependency tree +uv tree + +# Update dependencies +uv sync +``` + +## Migration Tips + +1. UV is designed to be a drop-in replacement for pip, so most commands work similarly +2. Existing requirements.txt files are fully compatible +3. For best results, start with a fresh virtual environment +4. UV includes built-in lockfile support for reproducible environments + +## Troubleshooting + +If you encounter issues: + +- Ensure you have the latest version of UV: `uv self update` +- Try running with verbose output: `uv -vvv pip install -r requirements.txt` +- Check the [UV documentation](https://github.com/astral-sh/uv) for known issues diff --git a/convert_requirements_to_pyproject.py b/convert_requirements_to_pyproject.py new file mode 100644 index 000000000..74219ea0a --- /dev/null +++ b/convert_requirements_to_pyproject.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +""" +Convert requirements.txt to pyproject.toml dependencies +""" + +import re +import toml +from pathlib import Path + +def parse_requirements(file_path): + """Parse requirements file into a list of packages.""" + requirements = [] + + with open(file_path, 'r') as f: + for line in f: + line = line.strip() + if line and not line.startswith('#') and not line.startswith('-r'): + requirements.append(line) + + return requirements + +def main(): + project_root = Path(__file__).parent + pyproject_path = project_root / "pyproject.toml" + + # Parse requirements + requirements = parse_requirements(project_root / "requirements.txt") + + try: + advanced_requirements = parse_requirements(project_root / "requirements_advanced.txt") + except FileNotFoundError: + advanced_requirements = [] + + # Load existing pyproject.toml if it exists + if pyproject_path.exists(): + with open(pyproject_path, 'r') as f: + pyproject_data = toml.load(f) + else: + # Create basic structure + pyproject_data = { + "build-system": { + "requires": ["setuptools>=42", "wheel"], + "build-backend": "setuptools.build_meta" + }, + "project": { + "name": "ComfyUI", + "version": "0.1.0", + "description": "The most powerful and modular diffusion model GUI, api and backend with a graph/nodes interface.", + "readme": "README.md", + "requires-python": ">=3.8", + "dependencies": requirements + } + } + + # Update dependencies + if "project" not in pyproject_data: + pyproject_data["project"] = {} + + pyproject_data["project"]["dependencies"] = requirements + + # Add optional dependencies + if advanced_requirements: + if "optional-dependencies" not in pyproject_data["project"]: + pyproject_data["project"]["optional-dependencies"] = {} + + pyproject_data["project"]["optional-dependencies"]["advanced"] = advanced_requirements + + # Save updated pyproject.toml + with open(pyproject_path, 'w') as f: + toml.dump(pyproject_data, f) + + print(f"Updated {pyproject_path} with dependencies from requirements files") + +if __name__ == "__main__": + main() diff --git a/install_with_uv.py b/install_with_uv.py new file mode 100644 index 000000000..c7ed79864 --- /dev/null +++ b/install_with_uv.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +""" +ComfyUI Installation Script using UV +""" + +import os +import platform +import subprocess +import sys +import shutil +from pathlib import Path +import argparse +from datetime import datetime + +def check_python_version(): + """Check if Python version is supported.""" + if sys.version_info < (3, 8): + print("Python 3.8 or higher is required.") + sys.exit(1) + +def install_uv(): + """Install UV if not already installed.""" + if shutil.which("uv") is None: + print("Installing UV package manager...") + try: + if platform.system() == "Windows": + # For Windows, download and run the installer + subprocess.check_call( + ["powershell", "-Command", + "Invoke-WebRequest -Uri https://astral.sh/uv/install.ps1 -OutFile install.ps1; ./install.ps1"], + stdout=sys.stdout, stderr=sys.stderr + ) + else: + # For macOS and Linux + subprocess.check_call( + ["bash", "-c", "curl -LsSf https://astral.sh/uv/install.sh | sh"], + stdout=sys.stdout, stderr=sys.stderr + ) + print("UV installed successfully.") + except subprocess.CalledProcessError: + print("Failed to install UV. Please install it manually from https://github.com/astral-sh/uv") + sys.exit(1) + else: + print("UV is already installed.") + +def create_venv(): + """Create a virtual environment using UV.""" + print("Creating virtual environment...") + try: + subprocess.check_call( + ["uv", "venv", ".venv"], + stdout=sys.stdout, stderr=sys.stderr + ) + print("Virtual environment created successfully.") + except subprocess.CalledProcessError: + print("Failed to create virtual environment.") + sys.exit(1) + +def activate_venv(): + """Return the activation command for the virtual environment.""" + if platform.system() == "Windows": + return str(Path(".venv/Scripts/activate")) + return f"source {str(Path('.venv/bin/activate'))}" + +def install_requirements(args): + """Install ComfyUI requirements using UV.""" + print("Installing requirements...") + + # Basic requirements + try: + subprocess.check_call( + ["uv", "pip", "install", "-r", "requirements.txt"], + stdout=sys.stdout, stderr=sys.stderr + ) + print("Basic requirements installed successfully.") + except subprocess.CalledProcessError: + print("Failed to install basic requirements.") + sys.exit(1) + + # Advanced requirements if specified + if args.advanced: + try: + if os.path.exists("requirements_advanced.txt"): + subprocess.check_call( + ["uv", "pip", "install", "-r", "requirements_advanced.txt"], + stdout=sys.stdout, stderr=sys.stderr + ) + print("Advanced requirements installed successfully.") + else: + print("Advanced requirements file not found.") + except subprocess.CalledProcessError: + print("Failed to install advanced requirements.") + sys.exit(1) + + # GPU requirements if specified + if args.gpu: + print("Installing PyTorch with CUDA support...") + try: + subprocess.check_call( + ["uv", "pip", "install", "torch", "torchvision", "torchaudio", "--index-url", "https://download.pytorch.org/whl/cu118"], + stdout=sys.stdout, stderr=sys.stderr + ) + print("PyTorch with CUDA installed successfully.") + except subprocess.CalledProcessError: + print("Failed to install PyTorch with CUDA.") + sys.exit(1) + +def main(): + parser = argparse.ArgumentParser(description="Install ComfyUI with UV package manager") + parser.add_argument("--advanced", action="store_true", help="Install advanced requirements") + parser.add_argument("--gpu", action="store_true", help="Install PyTorch with CUDA support") + parser.add_argument("--no-venv", action="store_true", help="Skip virtual environment creation") + args = parser.parse_args() + + print(f"ComfyUI installation with UV started at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") + + check_python_version() + install_uv() + + if not args.no_venv: + create_venv() + print(f"To activate the virtual environment, run: {activate_venv()}") + + install_requirements(args) + + print("\nComfyUI installation completed successfully!") + if not args.no_venv: + print(f"Remember to activate the virtual environment with: {activate_venv()}") + print("To start ComfyUI, run: python main.py") + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml index a9c028c7e..97420defc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,11 @@ +[build-system] +requires = ["setuptools>=42", "wheel"] +build-backend = "setuptools.build_meta" + [project] name = "ComfyUI" version = "0.3.30" +description = "The most powerful and modular diffusion model GUI, api and backend with a graph/nodes interface." readme = "README.md" license = { file = "LICENSE" } requires-python = ">=3.9" @@ -10,6 +15,11 @@ homepage = "https://www.comfy.org/" repository = "https://github.com/comfyanonymous/ComfyUI" documentation = "https://docs.comfy.org/" +[project.optional-dependencies] +advanced = [ + # Include dependencies from requirements_advanced.txt here +] + [tool.ruff] lint.select = [ "N805", # invalid-first-argument-name-for-method @@ -22,3 +32,6 @@ lint.select = [ "F", ] exclude = ["*.ipynb"] + +[tool.uv] +# Add any uv-specific configurations here