forked from Github/Axter-Stash
127 lines
4.8 KiB
Python
127 lines
4.8 KiB
Python
# ModulesValidate (By David Maisonave aka Axter)
|
|
# Description:
|
|
# Checks if packages are installed, and optionally install packages if missing.
|
|
# The below example usage code should be plave at the very top of the scource code before any other imports.
|
|
# Example Usage:
|
|
# import ModulesValidate
|
|
# ModulesValidate.modulesInstalled(["watchdog", "schedule", "requests"])
|
|
# Testing:
|
|
# To test, uninstall packages via command line: pip uninstall -y watchdog schedule requests
|
|
import sys, os, pathlib, platform, traceback
|
|
# ToDo: Add logic to optionally pull package requirements from requirements.txt file.
|
|
|
|
def modulesInstalled(moduleNames, install=True, silent=False):
|
|
retrnValue = True
|
|
for moduleName in moduleNames:
|
|
try: # Try Python 3.3 > way
|
|
import importlib
|
|
import importlib.util
|
|
if moduleName in sys.modules:
|
|
if not silent: print(f"{moduleName!r} already in sys.modules")
|
|
elif isModuleInstalled(moduleName):
|
|
if not silent: print(f"Module {moduleName!r} is available.")
|
|
else:
|
|
if install and (results:=installModule(moduleName)) > 0:
|
|
if results == 1:
|
|
print(f"Module {moduleName!r} has been installed")
|
|
else:
|
|
if not silent: print(f"Module {moduleName!r} is already installed")
|
|
continue
|
|
else:
|
|
if install:
|
|
print(f"Can't find the {moduleName!r} module")
|
|
retrnValue = False
|
|
except Exception as e:
|
|
try:
|
|
i = importlib.import_module(moduleName)
|
|
except ImportError as e:
|
|
if install and (results:=installModule(moduleName)) > 0:
|
|
if results == 1:
|
|
print(f"Module {moduleName!r} has been installed")
|
|
else:
|
|
if not silent: print(f"Module {moduleName!r} is already installed")
|
|
continue
|
|
else:
|
|
if install:
|
|
tb = traceback.format_exc()
|
|
print(f"Can't find the {moduleName!r} module! Error: {e}\nTraceBack={tb}")
|
|
retrnValue = False
|
|
return retrnValue
|
|
|
|
def isModuleInstalled(moduleName):
|
|
try:
|
|
__import__(moduleName)
|
|
return True
|
|
except Exception as e:
|
|
pass
|
|
return False
|
|
|
|
def installModule(moduleName):
|
|
try:
|
|
if isLinux():
|
|
# Note: Linux may first need : sudo apt install python3-pip
|
|
# if error starts with "Command 'pip' not found"
|
|
# or includes "No module named pip"
|
|
results = os.popen(f"pip --version").read()
|
|
if results.find("Command 'pip' not found") != -1 or results.find("No module named pip") != -1:
|
|
results = os.popen(f"sudo apt install python3-pip").read()
|
|
results = os.popen(f"pip --version").read()
|
|
if results.find("Command 'pip' not found") != -1 or results.find("No module named pip") != -1:
|
|
return -1
|
|
if isFreeBSD():
|
|
print("Warning: installModule may NOT work on freebsd")
|
|
pipArg = ""
|
|
if isDocker():
|
|
pipArg = " --break-system-packages"
|
|
results = os.popen(f"{sys.executable} -m pip install {moduleName}{pipArg}").read() # May need to be f"{sys.executable} -m pip install {moduleName}"
|
|
results = results.strip("\n")
|
|
if results.find("Requirement already satisfied:") > -1:
|
|
return 2
|
|
elif results.find("Successfully installed") > -1:
|
|
return 1
|
|
elif modulesInstalled(moduleNames=[moduleName], install=False):
|
|
return 1
|
|
except Exception as e:
|
|
pass
|
|
return 0
|
|
|
|
def installPackage(package): # Should delete this. It doesn't work consistently
|
|
try:
|
|
import pip
|
|
if hasattr(pip, 'main'):
|
|
pip.main(['install', package])
|
|
else:
|
|
pip._internal.main(['install', package])
|
|
except Exception as e:
|
|
return False
|
|
return True
|
|
|
|
def isDocker():
|
|
cgroup = pathlib.Path('/proc/self/cgroup')
|
|
return pathlib.Path('/.dockerenv').is_file() or cgroup.is_file() and 'docker' in cgroup.read_text()
|
|
|
|
def isWindows():
|
|
if any(platform.win32_ver()):
|
|
return True
|
|
return False
|
|
|
|
def isLinux():
|
|
if platform.system().lower().startswith("linux"):
|
|
return True
|
|
return False
|
|
|
|
def isFreeBSD():
|
|
if platform.system().lower().startswith("freebsd"):
|
|
return True
|
|
return False
|
|
|
|
def isMacOS():
|
|
if sys.platform == "darwin":
|
|
return True
|
|
return False
|
|
|
|
def isWindows():
|
|
if any(platform.win32_ver()):
|
|
return True
|
|
return False
|