core/homeassistant/util/package.py

47 lines
1.4 KiB
Python
Raw Normal View History

"""Helpers to install PyPi packages."""
import logging
import os
import pkg_resources
import subprocess
import sys
import threading
from urllib.parse import urlparse
_LOGGER = logging.getLogger(__name__)
INSTALL_LOCK = threading.Lock()
def install_package(package, upgrade=True, target=None):
"""Install a package on PyPi. Accepts pip compatible package strings.
Return boolean if install successfull."""
# Not using 'import pip; pip.main([])' because it breaks the logger
with INSTALL_LOCK:
if check_package_exists(package, target):
return True
_LOGGER.info('Attempting install of %s', package)
args = [sys.executable, '-m', 'pip', 'install', '--quiet', package]
if upgrade:
args.append('--upgrade')
if target:
args += ['--target', os.path.abspath(target)]
try:
return 0 == subprocess.call(args)
except subprocess.SubprocessError:
return False
def check_package_exists(package, target):
"""Check if a package exists.
Returns True when the requirement is met.
Returns False when the package is not installed or doesn't meet req."""
try:
req = pkg_resources.Requirement.parse(package)
except ValueError:
# This is a zip file
req = pkg_resources.Requirement.parse(urlparse(package).fragment)
return any(dist in req for dist in
pkg_resources.find_distributions(target))