Spaces:
Running
Running
""" | |
Package installation utility that checks for package existence and installs if needed. | |
Supports both pip and conda package managers. | |
""" | |
import importlib.util | |
import subprocess | |
import sys | |
from typing import Literal, Optional, Union | |
from swarms.utils.loguru_logger import initialize_logger | |
import pkg_resources | |
logger = initialize_logger("autocheckpackages") | |
def check_and_install_package( | |
package_name: str, | |
package_manager: Literal["pip", "conda"] = "pip", | |
version: Optional[str] = None, | |
upgrade: bool = False, | |
) -> bool: | |
""" | |
Check if a package is installed and install it if not found. | |
Args: | |
package_name: Name of the package to check/install | |
package_manager: Package manager to use ('pip' or 'conda') | |
version: Specific version to install (optional) | |
upgrade: Whether to upgrade the package if it exists | |
Returns: | |
bool: True if package is available after check/install, False if installation failed | |
Raises: | |
ValueError: If invalid package manager is specified | |
""" | |
try: | |
# Check if package exists | |
if package_manager == "pip": | |
try: | |
pkg_resources.get_distribution(package_name) | |
if not upgrade: | |
logger.info( | |
f"Package {package_name} is already installed" | |
) | |
return True | |
except pkg_resources.DistributionNotFound: | |
pass | |
# Construct installation command | |
cmd = [sys.executable, "-m", "pip", "install"] | |
if upgrade: | |
cmd.append("--upgrade") | |
if version: | |
cmd.append(f"{package_name}=={version}") | |
else: | |
cmd.append(package_name) | |
elif package_manager == "conda": | |
# Check if conda is available | |
try: | |
subprocess.run( | |
["conda", "--version"], | |
check=True, | |
capture_output=True, | |
) | |
except (subprocess.CalledProcessError, FileNotFoundError): | |
logger.error( | |
"Conda is not available. Please install conda first." | |
) | |
return False | |
# Construct conda command | |
cmd = ["conda", "install", "-y"] | |
if version: | |
cmd.append(f"{package_name}={version}") | |
else: | |
cmd.append(package_name) | |
else: | |
raise ValueError( | |
f"Invalid package manager: {package_manager}" | |
) | |
# Run installation | |
logger.info(f"Installing {package_name}...") | |
subprocess.run( | |
cmd, check=True, capture_output=True, text=True | |
) | |
# Verify installation | |
try: | |
importlib.import_module(package_name) | |
logger.info(f"Successfully installed {package_name}") | |
return True | |
except ImportError: | |
logger.error( | |
f"Package {package_name} was installed but cannot be imported" | |
) | |
return False | |
except subprocess.CalledProcessError as e: | |
logger.error(f"Failed to install {package_name}: {e.stderr}") | |
return False | |
except Exception as e: | |
logger.error( | |
f"Unexpected error while installing {package_name}: {str(e)}" | |
) | |
return False | |
def auto_check_and_download_package( | |
packages: Union[str, list[str]], | |
package_manager: Literal["pip", "conda"] = "pip", | |
upgrade: bool = False, | |
) -> bool: | |
""" | |
Ensure multiple packages are installed. | |
Args: | |
packages: Single package name or list of package names | |
package_manager: Package manager to use ('pip' or 'conda') | |
upgrade: Whether to upgrade existing packages | |
Returns: | |
bool: True if all packages are available, False if any installation failed | |
""" | |
if isinstance(packages, str): | |
packages = [packages] | |
success = True | |
for package in packages: | |
if ":" in package: | |
name, version = package.split(":") | |
if not check_and_install_package( | |
name, package_manager, version, upgrade | |
): | |
success = False | |
else: | |
if not check_and_install_package( | |
package, package_manager, upgrade=upgrade | |
): | |
success = False | |
return success | |