Blurb:
I found the step by step description to install Python modules a bit cumbersome, so I automated it, at least for a Windows environment. Comments welcome:
#https://github-wiki-see.page/m/DynamoDS/Dynamo/wiki/Customizing-Dynamo%27s-Python-3-installation
import platform, os, subprocess, importlib.util, sys
from System import Environment
from System.Net import WebClient
dirName = f'python-{platform.python_version()}-embed-amd64'
localappdatapath = os.getenv(r'LOCALAPPDATA')
dirPath = os.path.join(localappdatapath, dirName)
assert os.path.isdir(dirPath)
bootstrapPipFilePath = os.path.join(dirPath, 'get-pip.py')
if not os.path.isfile(bootstrapPipFilePath):
WebClient().DownloadFile('https://bootstrap.pypa.io/get-pip.py', bootstrapPipFilePath)
pthFilePath = os.path.join(dirPath, 'python38._pth')
assert os.path.isfile(pthFilePath)
replace = False
with open(pthFilePath, 'r') as f:
lines = f.readlines()
if '#' in lines[-1]:
lines[-1] = lines[-1].replace('#','')
replace = True
if replace:
with open(pthFilePath, 'w') as f:
f.writelines(lines)
pipDirPath = os.path.join(dirPath, 'Scripts')
if not os.path.isdir(pipDirPath):
OUT = f'installing pip in local Python environment: {dirPath}'
batPath = os.path.join(localappdatapath,'Temp', 'pipInstall.bat')
with open(batPath, 'w') as f:
f.write(f'cd {dirPath}\n')
f.write('python get-pip.py')
try: subprocess.run(batPath, check = True) #check argument raises exception when an error occurs
except Exception as ex:
OUT += '\n error while installing pip:'
OUT += '\n' + str(ex)
else:
os.remove(batPath)
OUT += '\n pip succesfully installed'
else: OUT = 'pip was already installed for this local Python environment'
installPackages = IN[0]
if installPackages:
sys.path.append(os.path.join(localappdatapath, r'python-3.8.3-embed-amd64\Lib\site-packages'))
for packageName in installPackages:
spec = importlib.util.find_spec( packageName )
if spec is None:
OUT += f'\n installing {packageName} in local Python environment: {dirPath}'
batPath = os.path.join(localappdatapath,'Temp', packageName+'Install.bat')
with open(batPath, 'w') as f:
f.write(f'cd {dirPath}\n')
f.write('.\Scripts\pip install '+packageName)
try: subprocess.run(batPath, check = True) #check argument raises exception when an error occurs
except Exception as ex:
OUT += f'\n error while installing {packageName}:'
OUT += '\n' + str(ex)
else:
os.remove(batPath)
OUT += f'\n{packageName} succesfully installed'
else: OUT += f'\n{packageName} was already installed for this local Python environment'
and improved by the second submitter here:
# More info here
# https://github-wiki-see.page/m/DynamoDS/Dynamo/wiki/Customizing-Dynamo%27s-Python-3-installation
import sys
import clr
import System
import re
pyEngineName = sys.implementation.name
if pyEngineName != "ironpython":
reDir = System.IO.DirectoryInfo(re.__file__)
path_py3_lib = reDir.Parent.Parent.FullName
clr.AddReference("System.Windows.Forms")
import System.Windows.Forms
from System.Windows.Forms import MessageBox, MessageBoxButtons, MessageBoxIcon
init_setup = False
import platform, os, subprocess, importlib.util
from System import Environment
from System.Net import WebClient
#
# get paths
assert os.path.isdir(path_py3_lib)
pipDirPath = os.path.join(path_py3_lib, 'Scripts')
pipfilePath = pipDirPath + "\\pip"
get_pip_path = os.path.join(path_py3_lib, 'get-pip.py')
site_packagepath = os.path.join(path_py3_lib, 'Lib\site-packages')
#
if not os.path.isfile(get_pip_path):
client = WebClient()
client.DownloadFile('https://bootstrap.pypa.io/get-pip.py', get_pip_path)
pthFilePath = os.path.join(path_py3_lib, 'python38._pth')
assert os.path.isfile(pthFilePath)
with open(pthFilePath, 'r+') as f:
lines = f.readlines()
if re.match(r'#import site', lines[-1]) is not None:
lines[-1] = re.sub(r'#', '', lines[-1])
f.writelines(lines)
if not os.path.isdir(pipDirPath):
print(f'installing pip in local Python environment: {path_py3_lib}')
subprocess.Popen(["python", get_pip_path])
# try to update pip
try:
#subprocess.run(['python', '-m', pipfilePath, 'install', '--upgrade pip'], cwd = path_py3_lib)
subprocess.Popen(["python", '-m', pipfilePath, 'install', '--upgrade pip'], cwd = path_py3_lib)
except Exception as ex:
print(str(ex))
init_setup = True
MessageBox.Show("Initialization in Progress...\nWhen installation finished, close Dynamo and relaunch this script to install packages", "Initialization In Progress...", MessageBoxButtons.OK, MessageBoxIcon.Warning)
else:
print('pip was already installed for this local Python environment')
init_setup = False
#
installPackages = IN[0]
if installPackages and not init_setup:
sys.path.append(site_packagepath)
for packageName in installPackages:
spec = importlib.util.find_spec( packageName )
if spec is None:
try:
subprocess.run([pipfilePath, 'install', '--target='+ site_packagepath, packageName], cwd = path_py3_lib)
print(f'{packageName} succesfully installed')
except Exception as ex:
print(f'error while installing {packageName}')
print(str(ex))
else:
print(f"package {packageName} is already installed")