test installer

This commit is contained in:
KatKatKateryna
2024-02-12 17:41:42 +00:00
parent 782ac1d927
commit 2e1eb2efd0
6 changed files with 187 additions and 116 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ def patch_installer(tag):
conda_file = "speckle_arcgis_installer/conda_clone_activate.py" conda_file = "speckle_arcgis_installer/conda_clone_activate.py"
#toolbox_install_file = "speckle_arcgis_installer/toolbox_install.py" #toolbox_install_file = "speckle_arcgis_installer/toolbox_install.py"
toolbox_manual_install_file = "speckle_arcgis_installer/toolbox_install_manual.py" toolbox_manual_install_file = "speckle_arcgis_installer/toolbox_install_manual.py"
plugin_start_file = "speckle_toolbox/esri/toolboxes/speckle/speckle_arcgis.py" plugin_start_file = "speckle_toolbox/esri/toolboxes/speckle/speckle/speckle_arcgis.py"
#py_tag = get_specklepy_version() #py_tag = get_specklepy_version()
with open(iss_file, "r") as file: with open(iss_file, "r") as file:
+45 -30
View File
@@ -1,39 +1,54 @@
# to build an installer: run cmd from this folder or use terminal: "%PROGRAMFILES%\\ArcGIS\\Pro\\bin\\Python\\envs\\arcgispro-py3\\python.exe" # to build an installer: run cmd from this folder or use terminal: "%PROGRAMFILES%\\ArcGIS\\Pro\\bin\\Python\\envs\\arcgispro-py3\\python.exe"
# #
# 1) python patch_version.py 2.x.x # 1) python patch_version.py 2.x.x
# 2) python setup.py sdist bdist_wheel #C:\\Users\\username\\Documents\\00_Speckle\\GitHub\\speckle-arcgis\\setup.py sdist bdist_wheel # 2) python setup.py sdist bdist_wheel #C:\\Users\\username\\Documents\\00_Speckle\\GitHub\\speckle-arcgis\\setup.py sdist bdist_wheel
# copy .whl from "dist" to "speckle_arcgis_installer" # copy .whl from "dist" to "speckle_arcgis_installer"
# ref: https://pro.arcgis.com/en/pro-app/2.8/arcpy/geoprocessing_and_python/distributing-python-modules.htm # ref: https://pro.arcgis.com/en/pro-app/2.8/arcpy/geoprocessing_and_python/distributing-python-modules.htm
import os import os
from setuptools import setup from setuptools import setup
def read(fname): def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read() return open(os.path.join(os.path.dirname(__file__), fname)).read()
setup(name='speckle_toolbox',
author='SpeckleSystems', setup(
version="2.9.4", name="speckle_toolbox",
author_email="connectors@speckle.systems", author="SpeckleSystems",
url="https://speckle.systems/", version="2.9.9",
description=("Example for extending geoprocessing through Python modules"), author_email="connectors@speckle.systems",
long_description=read('Readme.md'), url="https://speckle.systems/",
python_requires='~=3.3', description=("Example for extending geoprocessing through Python modules"),
setup_requires=['wheel'], long_description=read("Readme.md"),
packages=['speckle_toolbox'], python_requires="~=3.3",
package_data={'speckle_toolbox':[ setup_requires=["wheel"],
'esri/arcpy/*', packages=["speckle_toolbox"],
'esri/help/gp/*', 'esri/help/gp/toolboxes/*', 'esri/help/gp/messages/*', package_data={
'esri/toolboxes/*','esri/toolboxes/speckle/*', "speckle_toolbox": [
'esri/toolboxes/speckle/converter/*', 'esri/toolboxes/speckle/converter/geometry/*', 'esri/toolboxes/speckle/converter/layers/*', 'esri/toolboxes/speckle/converter/features/*', "esri/arcpy/*",
'esri/toolboxes/speckle/plugin_utils/*', "esri/help/gp/*",
'esri/toolboxes/speckle/ui/*'] "esri/help/gp/toolboxes/*",
}, "esri/help/gp/messages/*",
) "esri/toolboxes/*",
"esri/toolboxes/speckle/*",
"esri/toolboxes/speckle/plugin_utils/*",
"esri/toolboxes/speckle/speckle/*",
"esri/toolboxes/speckle/speckle/converter/*",
"esri/toolboxes/speckle/speckle/converter/features/*",
"esri/toolboxes/speckle/speckle/converter/geometry/*",
"esri/toolboxes/speckle/speckle/converter/layers/*",
"esri/toolboxes/speckle/speckle/plugin_utils/*",
"esri/toolboxes/speckle/speckle/utils/*",
"esri/toolboxes/speckle/specklepy_qt_ui/*",
"esri/toolboxes/speckle/ui/*",
"esri/toolboxes/speckle/ui_widgets/*",
]
},
)
# then to install in ArcGIS: # then to install in ArcGIS:
# import sysconfig; import subprocess; x = sysconfig.get_paths()['data'] + r"\python.exe"; subprocess.run((x, '-m','pip', 'install', 'C:\\Users\\username\\Documents\\00_Speckle\\GitHub\\speckle-arcgis\\dist\\foo-0.1-py3-none-any.whl'), capture_output=True, text=True, shell=True, timeout=1000 ) # import sysconfig; import subprocess; x = sysconfig.get_paths()['data'] + r"\python.exe"; subprocess.run((x, '-m','pip', 'install', 'C:\\Users\\username\\Documents\\00_Speckle\\GitHub\\speckle-arcgis\\dist\\foo-0.1-py3-none-any.whl'), capture_output=True, text=True, shell=True, timeout=1000 )
# to uninstall: # to uninstall:
# "C:\\Users\\username\\AppData\\Local\\ESRI\\conda\\envs\\arcgispro-py3-speckle\\python.exe" -m pip uninstall C:\\Users\\username\\Documents\\00_Speckle\\GitHub\\speckle-arcgis\\dist\\foo-0.1-py3-none-any.whl # "C:\\Users\\username\\AppData\\Local\\ESRI\\conda\\envs\\arcgispro-py3-speckle\\python.exe" -m pip uninstall C:\\Users\\username\\Documents\\00_Speckle\\GitHub\\speckle-arcgis\\dist\\foo-0.1-py3-none-any.whl
+139 -83
View File
@@ -1,4 +1,4 @@
# clone env, install toolbox & dependencies into the cloned env; and into current one (if not default) # clone env, install toolbox & dependencies into the cloned env; and into current one (if not default)
import sys import sys
import sysconfig import sysconfig
import os.path import os.path
@@ -12,80 +12,139 @@ import sys
ENV_NEW_NAME = "arcgispro-py3-speckle" ENV_NEW_NAME = "arcgispro-py3-speckle"
def setup(): def setup():
pythonExec = get_python_path() # import numpy; import os; print(os.path.abspath(numpy.__file__)) pythonExec = (
return pythonExec # None if not successful get_python_path()
) # import numpy; import os; print(os.path.abspath(numpy.__file__))
return pythonExec # None if not successful
def get_default_python(): def get_default_python():
pythonExec = os.environ["ProgramFiles"] + r'\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe' #(r"%PROGRAMFILES%\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe") #os.path.dirname(sys.executable) + "\\python.exe" # default python.exe pythonExec = (
#print(pythonExec) os.environ["ProgramFiles"]
+ r"\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe"
) # (r"%PROGRAMFILES%\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe") #os.path.dirname(sys.executable) + "\\python.exe" # default python.exe
# print(pythonExec)
if not os.path.exists(pythonExec): if not os.path.exists(pythonExec):
pythonExec = os.getenv('APPDATA').replace("Roaming", "Local") + r'\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe' pythonExec = (
if not os.path.exists(pythonExec): return None os.getenv("APPDATA").replace("Roaming", "Local")
+ r"\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe"
)
if not os.path.exists(pythonExec):
return None
return pythonExec return pythonExec
def get_python_path(): # create a full copy of default env
#print("Get Python path") def get_python_path(): # create a full copy of default env
# print("Get Python path")
# or: import site; site.getsitepackages()[0] # or: import site; site.getsitepackages()[0]
# import specklepy; import os; print(os.path.abspath(specklepy.__file__)) ##currentPythonExec = sysconfig.get_paths()['data'] + r"\python.exe" # import specklepy; import os; print(os.path.abspath(specklepy.__file__)) ##currentPythonExec = sysconfig.get_paths()['data'] + r"\python.exe"
def_exec = get_default_python() def_exec = get_default_python()
#print(os.getenv('APPDATA') + r'\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe') # print(os.getenv('APPDATA') + r'\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe')
if sys.platform == "win32": if sys.platform == "win32":
newExec = clone_env(def_exec) # only if doesn't exist yet newExec = clone_env(def_exec) # only if doesn't exist yet
if not os.path.exists(newExec): return None if not os.path.exists(newExec):
return None
activate_env() activate_env()
return newExec return newExec
else: return None else:
return None
def clone_env(pythonExec_old: str):
install_folder = os.getenv('APPDATA').replace("\\Roaming","") + r"\Local\ESRI\conda\envs" #r"%LOCALAPPDATA%\ESRI\conda\envs"
if not os.path.exists(install_folder): os.makedirs(install_folder)
default_env = pythonExec_old.replace("Pro\\bin\\Python\\envs\\arcgispro-py3\\python.exe","Pro\\bin\\Python\\envs\\arcgispro-py3") # + "\\" + 'arcgispro-py3'
conda_exe = pythonExec_old.replace("Pro\\bin\\Python\\envs\\arcgispro-py3\\python.exe","Pro\\bin\\Python\\Scripts\\conda.exe") #%PROGRAMFILES%\ArcGIS\Pro\bin\Python\Scripts\conda.exe #base: %PROGRAMDATA%\Anaconda3\condabin\conda.bat
new_env = install_folder + "\\" + ENV_NEW_NAME # %LOCALAPPDATA%\ESRI\conda\envs\...
if os.path.exists(conda_exe) and os.path.exists(default_env) and os.path.exists(new_env) and not os.path.exists(new_env + "\\python.exe"): def clone_env(pythonExec_old: str):
# conda environment invalid: delete it's folder install_folder = (
os.getenv("APPDATA").replace("\\Roaming", "") + r"\Local\ESRI\conda\envs"
) # r"%LOCALAPPDATA%\ESRI\conda\envs"
if not os.path.exists(install_folder):
os.makedirs(install_folder)
default_env = pythonExec_old.replace(
"Pro\\bin\\Python\\envs\\arcgispro-py3\\python.exe",
"Pro\\bin\\Python\\envs\\arcgispro-py3",
) # + "\\" + 'arcgispro-py3'
conda_exe = pythonExec_old.replace(
"Pro\\bin\\Python\\envs\\arcgispro-py3\\python.exe",
"Pro\\bin\\Python\\Scripts\\conda.exe",
) # %PROGRAMFILES%\ArcGIS\Pro\bin\Python\Scripts\conda.exe #base: %PROGRAMDATA%\Anaconda3\condabin\conda.bat
new_env = install_folder + "\\" + ENV_NEW_NAME # %LOCALAPPDATA%\ESRI\conda\envs\...
# first check if venv invalid:
if (
os.path.exists(conda_exe)
and os.path.exists(default_env)
and os.path.exists(new_env)
):
# delete existing venv
print(f"Removing invalid environment {new_env}") print(f"Removing invalid environment {new_env}")
os.remove(new_env) os.remove(new_env)
elif (
if os.path.exists(conda_exe) and os.path.exists(default_env) and not os.path.exists(new_env): os.path.exists(conda_exe)
and os.path.exists(default_env)
and not os.path.exists(new_env)
):
print("Wait for the default ArcGIS Pro conda environment to be cloned") print("Wait for the default ArcGIS Pro conda environment to be cloned")
subprocess_call( [ conda_exe, 'config', '--set', 'ssl_verify', 'False'] ) subprocess_call([conda_exe, "config", "--set", "ssl_verify", "False"])
subprocess_call( [ conda_exe, 'create', '--clone', default_env, '-p', new_env] ) # will not execute if already exists subprocess_call(
subprocess_call( [ conda_exe, 'config', '--set', 'ssl_verify', 'True'] ) [conda_exe, "create", "--clone", default_env, "-p", new_env]
) # will not execute if already exists
subprocess_call([conda_exe, "config", "--set", "ssl_verify", "True"])
elif os.path.exists(new_env) and os.path.exists(new_env + "\\python.exe"): r"""
print(f"Environment {new_env} already exists, preparing to install packages..") # repair venv: https://pro.arcgis.com/en/pro-app/3.1/arcpy/get-started/repair-an-environment.htm
# upgrade venv with conda: https://pro.arcgis.com/en/pro-app/3.1/arcpy/get-started/upgrade-an-environment.htm
elif (
os.path.exists(conda_exe)
and os.path.exists(default_env)
and os.path.exists(new_env)
and os.path.exists(new_env + "\\python.exe")
):
print(f"Environment {new_env} already exists, upgrading ..")
subprocess_call([conda_exe, "proup", "-n", ENV_NEW_NAME])
"""
# final check
if os.path.exists(new_env) and os.path.exists(new_env + "\\python.exe"):
print("Preparing to install packages..")
print(new_env + "\\python.exe") print(new_env + "\\python.exe")
return new_env + "\\python.exe" return new_env + "\\python.exe"
def activate_env(): def activate_env():
# using Popen, because process does not return result; subprocess.run will hang indefinitely # using Popen, because process does not return result; subprocess.run will hang indefinitely
variable = subprocess.Popen((f'proswap {ENV_NEW_NAME}'),stdout = subprocess.PIPE,stderr = subprocess.PIPE,text = True,shell = True) variable = subprocess.Popen(
(f"proswap {ENV_NEW_NAME}"),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
shell=True,
)
# activate new env : https://support.esri.com/en/technical-article/000024206 # activate new env : https://support.esri.com/en/technical-article/000024206
def installToolbox(newExec: str): def installToolbox(newExec: str):
print("Installing Speckle Toolbox") print("Installing Speckle Toolbox")
whl_file = os.path.join(os.path.dirname(__file__), "speckle_toolbox-2.9.4-py3-none-any.whl" ) whl_file = os.path.join(
os.path.dirname(__file__), "speckle_toolbox-2.9.9-py3-none-any.whl"
)
print(whl_file) print(whl_file)
subprocess_call([newExec, '-m','pip','install','--upgrade', '--force-reinstall', whl_file]) subprocess_call(
[newExec, "-m", "pip", "install", "--upgrade", "--force-reinstall", whl_file]
)
# to uninstall: cmd.exe "X:\\xxx.whl # to uninstall: cmd.exe "X:\\xxx.whl
return return
def clearToolbox(pythonExec: str): def clearToolbox(pythonExec: str):
# install pip # install pip
print("CLEAR toolbox") print("CLEAR toolbox")
print(pythonExec) print(pythonExec)
try: try:
speckle_path = pythonExec.replace("python.exe","Lib\\site-packages\\") speckle_path = pythonExec.replace("python.exe", "Lib\\site-packages\\")
print(speckle_path) print(speckle_path)
paths = os.listdir(speckle_path) paths = os.listdir(speckle_path)
for p in paths: for p in paths:
@@ -96,77 +155,74 @@ def clearToolbox(pythonExec: str):
print(e) print(e)
pass pass
def installDependencies(pythonExec: str, pkgName: str, pkgVersion: str): def installDependencies(pythonExec: str, pkgName: str, pkgVersion: str):
# install pip # install pip
print(pythonExec) print(pythonExec)
try: try:
import pip import pip
except: except:
getPipFilePath = os.path.join(os.path.dirname(__file__), "get_pip.py") #TODO: give actual folder path getPipFilePath = os.path.join(
os.path.dirname(__file__), "get_pip.py"
) # TODO: give actual folder path
exec(open(getPipFilePath).read()) exec(open(getPipFilePath).read())
# just in case the included version is old # just in case the included version is old
subprocess_call([pythonExec, "-m", "pip", "install", "--upgrade", "pip"]) subprocess_call([pythonExec, "-m", "pip", "install", "--upgrade", "pip"])
# install package # install package
try: try:
#import importlib #importlib.import_module(pkgName) # import importlib #importlib.import_module(pkgName)
if pkgName == "specklepy": if pkgName == "specklepy":
import specklepy import specklepy
if pythonExec.replace("\\python.exe","") not in (os.path.abspath(specklepy.__file__)):
if pythonExec.replace("\\python.exe", "") not in (
os.path.abspath(specklepy.__file__)
):
print(f"Installing {pkgName} to {pythonExec}") print(f"Installing {pkgName} to {pythonExec}")
#subprocess_call( [pythonExec, "-m", "pip", "uninstall", f"{pkgName}"]) # subprocess_call( [pythonExec, "-m", "pip", "uninstall", f"{pkgName}"])
subprocess_call( [pythonExec, "-m", "pip", "install", f"{pkgName}=={pkgVersion}"]) subprocess_call(
[pythonExec, "-m", "pip", "install", f"{pkgName}=={pkgVersion}"]
)
elif pkgName == "panda3d": elif pkgName == "panda3d":
import panda3d import panda3d
if pythonExec.replace("\\python.exe","") not in (os.path.abspath(panda3d.__file__)):
if pythonExec.replace("\\python.exe", "") not in (
os.path.abspath(panda3d.__file__)
):
print(f"Installing {pkgName} to {pythonExec}") print(f"Installing {pkgName} to {pythonExec}")
subprocess_call( [pythonExec, "-m", "pip", "install", f"{pkgName}=={pkgVersion}"]) subprocess_call(
[pythonExec, "-m", "pip", "install", f"{pkgName}=={pkgVersion}"]
)
elif pkgName == "PyQt5": elif pkgName == "PyQt5":
import PyQt5 import PyQt5
if pythonExec.replace("\\python.exe","") not in (os.path.abspath(PyQt5.__file__)):
if pythonExec.replace("\\python.exe", "") not in (
os.path.abspath(PyQt5.__file__)
):
print(f"Installing {pkgName} to {pythonExec}") print(f"Installing {pkgName} to {pythonExec}")
subprocess_call( [pythonExec, "-m", "pip", "install", f"{pkgName}=={pkgVersion}"]) subprocess_call(
[pythonExec, "-m", "pip", "install", f"{pkgName}=={pkgVersion}"]
)
except Exception as e: except Exception as e:
print(f"{pkgName} not installed") print(f"{pkgName} not installed")
subprocess_call( [pythonExec, "-m", "pip", "install", f"{pkgName}=={pkgVersion}"]) subprocess_call(
[pythonExec, "-m", "pip", "install", f"{pkgName}=={pkgVersion}"]
# Check if package needs updating
r'''
try:
print(f"Attempting to update {pkgName} to {pkgVersion}")
result = subprocess_call(
[
pythonExec,
"-m",
"pip",
"install",
"--upgrade",
f"{pkgName}=={pkgVersion}",
]
) )
if result == True:
print(f"{pkgName} upgraded")
return True
else:
return False
except Exception as e:
print(e)
print(e.with_traceback)
'''
return True return True
pythonPath = setup() pythonPath = setup()
print(pythonPath) print(pythonPath)
if pythonPath is not None: if pythonPath is not None:
#def_exec = get_default_python() # def_exec = get_default_python()
#conda_exe = def_exec.replace("Pro\\bin\\Python\\envs\\arcgispro-py3\\python.exe","Pro\\bin\\Python\\Scripts\\conda.exe") #%PROGRAMFILES%\ArcGIS\Pro\bin\Python\Scripts\conda.exe #base: %PROGRAMDATA%\Anaconda3\condabin\conda.bat # conda_exe = def_exec.replace("Pro\\bin\\Python\\envs\\arcgispro-py3\\python.exe","Pro\\bin\\Python\\Scripts\\conda.exe") #%PROGRAMFILES%\ArcGIS\Pro\bin\Python\Scripts\conda.exe #base: %PROGRAMDATA%\Anaconda3\condabin\conda.bat
#subprocess_call([conda_exe, 'proup','-n', ENV_NEW_NAME]) # subprocess_call([conda_exe, 'proup','-n', ENV_NEW_NAME])
clearToolbox(pythonPath) clearToolbox(pythonPath)
installToolbox(pythonPath) installToolbox(pythonPath)
installDependencies(pythonPath, "specklepy", "2.17.12" ) installDependencies(pythonPath, "specklepy", "2.17.17")
installDependencies(pythonPath, "panda3d", "1.10.11" ) installDependencies(pythonPath, "panda3d", "1.10.11")
installDependencies(pythonPath, "PyQt5", "5.15.9" ) installDependencies(pythonPath, "PyQt5", "5.15.9")
# manual: import sysconfig; import subprocess; x = sysconfig.get_paths()['data'] + r"\python.exe"; subprocess.run((x, "-m", "pip", "install", "PyQt5==5.15.9"), capture_output=True, text=True, shell=True, timeout=1000 ) # manual: import sysconfig; import subprocess; x = sysconfig.get_paths()['data'] + r"\python.exe"; subprocess.run((x, "-m", "pip", "install", "PyQt5==5.15.9"), capture_output=True, text=True, shell=True, timeout=1000 )
@@ -20,7 +20,7 @@ def installToolbox(newExec: str):
onlyfiles = [f for f in listdir(mypath) if (isfile(join(mypath, f)) and "py3-none-any.whl" in str(f))] onlyfiles = [f for f in listdir(mypath) if (isfile(join(mypath, f)) and "py3-none-any.whl" in str(f))]
onlyfiles.sort(key = lambda x: int(x.replace("speckle_toolbox-","").replace("-py3-none-any.whl","").split(".")[1]) ) onlyfiles.sort(key = lambda x: int(x.replace("speckle_toolbox-","").replace("-py3-none-any.whl","").split(".")[1]) )
whl_file = mypath + "\\" + onlyfiles[len(onlyfiles)-1] whl_file = mypath + "\\" + onlyfiles[len(onlyfiles)-1]
#whl_file = os.path.join(os.path.dirname(__file__), "speckle_toolbox-2.11.3-py3-none-any.whl" ) #whl_file = os.path.join(os.path.dirname(__file__), "speckle_toolbox-2.9.9-py3-none-any.whl" )
subprocess_call([newExec, '-m','pip','install','--upgrade', '--force-reinstall', whl_file]) subprocess_call([newExec, '-m','pip','install','--upgrade', '--force-reinstall', whl_file])
return return
@@ -182,7 +182,7 @@ class SpeckleGIS:
def __init__(self): def __init__(self):
"""Constructor.""" """Constructor."""
print("Start SpeckleGIS") print("Start SpeckleGIS")
self.version = "0.0.99" self.version = "2.9.9"
try: try:
version = arcpy.GetInstallInfo()["Version"] version = arcpy.GetInstallInfo()["Version"]
python_version = f"python {'.'.join(map(str, sys.version_info[:2]))}" python_version = f"python {'.'.join(map(str, sys.version_info[:2]))}"