diff --git a/install.py b/install.py index 017d08c..3994131 100644 --- a/install.py +++ b/install.py @@ -3,6 +3,10 @@ import os req_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "requirements.txt") +# Optional dependencies that can be skipped +OPTIONAL_PACKAGES = {"hnswlib", "numpy"} +SKIP_OPTIONAL = os.environ.get("IIB_SKIP_OPTIONAL_DEPS", "").lower() in ("1", "true", "yes") + def dist2package(dist: str): return ({ "python-dotenv": "dotenv", @@ -26,21 +30,57 @@ def extract_package_name(package_spec: str) -> str: package_spec = package_spec.split(",")[0].strip() return package_spec - +def get_optional_package_hints(package_name: str) -> str: + """Provide helpful hints for optional package installation failures.""" + hints = { + "hnswlib": ( + "\nNote: hnswlib is optional and only needed for experimental topic clustering/search.\n" + "Core image browsing features will still work without hnswlib in some cases.\n" + "To skip optional dependencies during installation, set: IIB_SKIP_OPTIONAL_DEPS=1\n" + "If you want to install hnswlib, please ensure you have:\n" + " - A C++ compiler (gcc/g++ on Linux, clang on macOS, MSVC on Windows)\n" + " - Python development headers (python3-dev on Ubuntu)\n" + " - Or try: pip install hnswlib --only-binary=:all: for pre-built wheels\n" + "See: https://github.com/nmslib/hnswlib/issues/403 and #504 for more details." + ), + "numpy": ( + "\nNote: numpy installation failed. Ensure your C++ compiler and Python dev headers are installed.\n" + "To skip optional dependencies, set: IIB_SKIP_OPTIONAL_DEPS=1\n" + "Core image browsing features will still work without numpy in some cases." + ), + } + return hints.get(package_name, "") with open(req_file) as file: for package in file: try: package = package.strip() + if not package or package.startswith("#"): + continue + package_name = extract_package_name(package) + + # Skip optional packages if IIB_SKIP_OPTIONAL_DEPS is set + if SKIP_OPTIONAL and package_name in OPTIONAL_PACKAGES: + print(f"Skipping optional dependency: {package}") + continue + if not launch.is_installed(dist2package(package_name)): launch.run_pip(f"install \"{package}\"", f"sd-webui-infinite-image-browsing requirement: {package}") except Exception as e: # Handle Unicode encoding errors on Windows try: - print(str(e)) + error_msg = str(e) except UnicodeEncodeError: - print(repr(e)) - print( - f"Warning: Failed to install {package}, some preprocessors may not work." - ) + error_msg = repr(e) + + print(f"Error details: {error_msg}") + + # Provide helpful hints for optional packages + hint_msg = get_optional_package_hints(package_name) + if hint_msg: + print(hint_msg) + else: + print(f"Warning: Failed to install {package}, some features may not work.") + + print()