Source code for pyphyschemtools.utils.pipManagement_202507_dev

#!/usr/bin/env python3
# coding: utf-8
import os
import sys
from datetime import datetime, timezone
import subprocess

pMversion = "20260304"


[docs] def run(): #adapt "PythonFolder" to your case PythonFolder = "Python3" PHome = "~" + "/" + PythonFolder + "/" PHomePython = os.path.expanduser('~') + "/" + PythonFolder + "/" #adapt "venv" to your case. These are virtual environments created with the virtualenv command (https://virtualenv.pypa.io/en/latest/index.html) # in the present case, 3 virtual environments were created: base, ML and ai4Chem. They will be addressed with the a, b and c characters venv = {"a":"base","b":"ML","c":"nmr","d":"ai4chem","e":"spektral","f":"DC","g":"base2","z":"test"} #venv = {"a":"base","b":"ML"} #VM string = "\n\033[91m\033[1mWhich command?\033[0m\n\ \033[1m# Output installed packages in requirements format\033[0m\n\ 1. pip freeze > requirements.txt\n\ \033[1m# Output installed packages in requirements format, but with no version number\033[0m\n\ 101. pip freeze | sed 's/==.*$/''/' > requirements.txt\n\ \033[1m# verify installed packages have compatible dependencies\033[0m\n\ 2. pip check\n\ \033[0m# List installed packages, including editables; possibility to list only packages that are not dependencies of installed packages\033[0m\n\ \033[32m3. pip list\033[0m\n\ 4. pip list --not-required\n\ \033[1m# display the installed python packages in form of a dependency tree\033[0m\n\ 5. pipdeptree\n\ \033[32m55. pipdeptree --reverse --packages package-name\033[0m\n\ \033[1m# pip-review is a convenience wrapper around pip. It can list available updates by deferring to pip list --outdated. It can also automatically or interactively install available updates for you by deferring to pip install\033[0m\n\ 6. pip list --outdated\n\ 7. pip list --outdated --not-required\n\ 8. pip-review\n\ \033[1m# pip-check gives a quick overview of all installed packages and their update status. Under the hood it calls ``pip list --outdated --format=columns``\033[0m\n\ 9. pip-check --hide-unchange\n\ \033[32m10. pip-check --hide-unchanged --show-updated\033[0m\n\ \033[32m11. pip-check --hide-unchanged --not-required --show-update\033[0m\n\ \033[1m# install a new package\033[0m\n\ \033[32m15. pip install package-name\033[0m\n\ \033[1m# uninstall a package\033[0m\n\ \033[32m16. pip uninstall package-name\033[0m\n\ \033[1m# upgrade packages\033[0m\n\ \033[32m20. pip install -r requirements.txt --upgrade\033[0m\n\ 21. pip install --upgrade package_name(s)\n\ 22. pip-review --local --interactive\n\ \n\ \033[1m# restore an environment\033[0m\n\ \033[32m23. pip uninstall $(pip freeze); pip install -r requirements.txt\033[0m\n\ \033[1m# list current environments\033[0m\n\ 30. ls -d */ " + PHome + "\n\ \033[1m# Clone one virtual environment into a new one, using a previously saved requirements.txt file\033[0m\n\ 40. virtualenv New_Env_Name; activate New_Env_Name; pip install -r requirements.txt \n\ \033[1m# Make a new empty virtual environment\033[0m\n\ 41. virtualenv New_Env_Name \n\ \n\ \033[1m# list pip cache contents\033[0m\n\ 50. pip cache list \n\ \033[1m# purge the pip cache\033[0m\n\ 51. pip cache purge \n\ \n\ \033[1m# Delete a virtual environment\033[0m\n\ \033[91m\033[1mD. rm -Rf Env_Name\033[0m\n\ \n\ \033[91m\033[1mx. Exit\033[0m" choice = "" catenvNN = "" listenv = "" for i in venv: catenvNN = catenvNN + i + " ," listenv = listenv + i + ": " + venv[i] + ". " print("-------------------------------------------------------------------------------------------") print(f"\033[34;1mpipManagement v.{pMversion}\033[0m") print() print(f"The python distribution is supposed to be in {PHomePython}") print("(if it is not the case, adapt the PythonFolder variable of pipManagement.py to your case)") print("-------------------------------------------------------------------------------------------") while choice != "x": print(f'{string}') print() now = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S") envNN = "" env = "" choice = input("enter a number (or x to terminate): ") if choice == "x": sys.exit() while envNN not in venv and choice not in ["30","40","41","50","51"]: strinput = "Which virtualenv environment? " + listenv envNN = input(strinput) if envNN in venv: env = venv[envNN] else: print(f"You must specify an existing environment ({catenvNN[:-2]})") pyAct = "source " + PHome + env + "/bin/activate;\n" pipCom = "" if choice == "1": pipCom = pyAct + "cd " + PHome + ";\n" pipCom = pipCom + "pip freeze > " + str(now) + "requirements_" + env + ".txt" if choice == "101": pipCom = pyAct + "cd " + PHome + ";\n" pipCom = pipCom + "pip freeze | sed 's/==.*$/''/' > " + str(now) + "requirements_" + env + "_noVersionNumber.txt" if choice == "2": pipCom = pyAct + "pip check" if choice == "3": pipCom = pyAct + "pip list" if choice == "4": pipCom = pyAct + "pip list --not-required" if choice == "5": pipCom = pyAct + "pipdeptree" if choice == "55": package_name = input("copy/paste the name of the package that other packages depend on: ") pipCom = pyAct + "pipdeptree --reverse --packages " + package_name if choice == "6": pipCom = pyAct + "pip list --outdated" if choice == "7": pipCom = pyAct + "pip list --outdated --not-required" if choice == "8": pipCom = pyAct + "pip-review" if choice == "9": pipCom = pyAct + "pip-check --hide-unchanged" if choice == "10": pipCom = pyAct + "pip-check --hide-unchanged --show-update" if choice == "11": pipCom = pyAct + "pip-check --hide-unchanged --not-required --show-update" if choice == "15": package_names = input("copy/paste the name of the package(s) you want to install (x = cancel operation): ") if package_names != "x": reqBefore = str(now) + "requirements_" + env + "_BeforeNewInstall.txt" pipCom = pyAct + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_BeforeNewInstall.txt;\n" pipCom = pipCom + "pip install " + package_names + " ;\n" pipCom = pipCom + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_AfterNewInstall.txt" else: pipCom = "echo operation cancelled" if choice == "16": package_names = input("copy/paste the name of the package(s) you want to uninstall (x = cancel operation): ") if package_names != "x": pipCom = pyAct + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_BeforeUninstall.txt;\n" pipCom = pipCom + "pip uninstall " + package_names + " -y ;\n" pipCom = pipCom + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_AfterUninstall.txt" else: pipCom = "echo operation cancelled" if choice == "20": systemCom = "cd " + PHome + ";\n ls -lrt *req*.txt |grep " + env subprocess.run(systemCom, shell=True) reqtxt = input("copy/paste the reference requirements/txt file: ") pipCom = pyAct + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_BeforeUpdate.txt;\n" os.chdir(PHomePython) print (os.getcwd()) reqtxtTmp = reqtxt + "_tmp" finp = open(reqtxt, "rt") fout = open(reqtxtTmp, "wt") for line in finp: fout.write(line.replace('==', '>=')) print(f"{reqtxtTmp} created after {reqtxt} with '==' replaced with '>='") finp.close() fout.close() pipCom = pipCom + "pip install -r " + PHome + reqtxtTmp + " --upgrade;\n" pipCom = pipCom + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_AfterUpdate.txt" if choice == "21": package_names = input("copy/paste the name of the package(s) you want to update (x = cancel operation): ") if package_names != "x": pipCom = pyAct + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_BeforeUpdate.txt;\n" pipCom = pipCom + "pip install --upgrade " + package_names + " ;\n" pipCom = pipCom + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_AfterUpdate.txt" else: pipCom = "echo operation cancelled" if choice == "22": pipCom = pyAct + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_BeforeUpdate.txt;\n" pipCom = pipCom + "pip-review --local --interactive;\n" pipCom = pipCom + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_AfterUpdate.txt" if choice == "23": systemCom = "cd " + PHome + ";\n ls -lrt *req*.txt |grep " + env subprocess.run(systemCom, shell=True) reqtxt = input("copy/paste the reference requirements/txt file you want to restore: ") pipCom = pyAct + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_BeforeRestoration.txt;\n" pipCom = pipCom + "pip uninstall $(pip freeze) -y;\n" pipCom = pipCom + "pip install -r " + PHome + reqtxt + ";\n" pipCom = pipCom + "pip freeze > " + PHome + str(now) + "requirements_" + env + "_AfterRestoration.txt" if choice == "30": pipCom = "cd " + PHome + ";\nls -d */" print() print(f"virtualenv defined in the present script: {listenv}") print() if choice == "40": NewEnvTxt = input("Name of the new environment: ") systemCom = "cd " + PHome + ";\nvirtualenv " + NewEnvTxt + ";\n ls -lrt *req*.txt" subprocess.run(systemCom, shell=True) ReqTxt = input(f"\033[33mcopy/paste from the previous list the reference requirements.txt file, i.e. the environment you want to clone: \033[0m") pyAct = "source " + PHome + NewEnvTxt + "/bin/activate;\n" pipCom = pyAct + " pip install -r " + PHome + ReqTxt + ";\n" if choice == "41": NewEnvTxt = input("Name of the new environment: ") systemCom = "cd " + PHome + ";\nvirtualenv " + NewEnvTxt subprocess.run(systemCom, shell=True) print() print(f"\033[33mActivate the environment with: source {PHome}{NewEnvTxt}/bin/activate\033[0m") if choice == "50": pipCom = "pip cache list" if choice == "51": pipCom = "pip cache purge" if choice == "D": YorN = input(f"\033[91m\033[1mAre you sure that you want to delete {env} (Y/N)?\033[0m ") if YorN == "Y": systemCom = "rm -Rf " + PHome + env subprocess.run(systemCom, shell=True) print(f"\033[94m\033[1m{pipCom}\033[0m") if choice in ["6","7","8","9","10","11"]: print(f"\033[31mWait...\033[0m") subprocess.run(pipCom, shell=True) if choice in ["20"]: print(f"Now deleting {reqtxtTmp}") os.remove(reqtxtTmp) if choice in ["15"]: print(f"\033[31mCheck carefully the previous installation messages. In case of any doubt, run command \033[31;1m#2\033[0m\033[31m (pip check)\033[0m") if choice in ["40"]: print(f"\033[31mDon't forget to add \033[31;1m{NewEnvTxt}\033[0m\033[31m in the venv variable of the present pipManagement.py script\033[0m") if choice in ["15","16","20","21","23"]: if choice in ["15","21"]: print(f"\033[31mCheck carefully the previous installation messages, as well as the foregoing \033[31;1mpip check command\033[0m") print(f"\033[31;1mNow checking if dependencies are still OK\033[0m (expecting 'No broken requirements found)'") pipCom = pyAct + "pip check" subprocess.run(pipCom, shell=True) if choice in ["15","21"]: print(f"\033[31mIf you want to revert to the previous configuration, run command \033[31;1m#23\033[0m\033[31m (pip install -r requirements.txt), with the \033[31;1m{reqBefore}\033[0m\033[31m file") choice = input(f"\n\033[32mPress Enter to continue or x to exit...\033[0m")
if __name__ == "__main__": run()