Skip to content

Commit

Permalink
feat(paraview): add paraview to sys.path when requested
Browse files Browse the repository at this point in the history
Trame can now find and add the paraview python library path to the sys.path if `trame.env.paraview`
was imported and the path to paraview was specified. It can be specified either via the
`TRAME_PARAVIEW` environment variable or a `--paraview <path>` argument on the command line. This
enables paraview to be imported and used.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
  • Loading branch information
psavery committed Apr 7, 2022
1 parent 23d0d51 commit 7438f44
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
Empty file added trame/env/__init__.py
Empty file.
59 changes: 59 additions & 0 deletions trame/env/paraview.py
@@ -0,0 +1,59 @@
"""Set up sys.path to include ParaView, if available
This checks the TRAME_PARAVIEW environment variable and the --paraview
argument in sys.argv. The specified path will then be automatically
searched for the python library directory and, if found, it will be
added to the sys.path so that the ParaView libraries may be imported.
To use: specify one of the following, and then import this file:
- `--paraview /path/to/paraview/release` argument
- environment variable `TRAME_PARAVIEW=/path/to/paraview/release`
"""
import platform
import sys

from .utils import prepend_python_path, find_env_setting

PV_LOADED = False

PV_HOME = find_env_setting("--paraview", "TRAME_PARAVIEW")

if PV_HOME is None:
msg = (
"trame.env.paraview was imported, but the paraview location was not "
"defined. Define it with either the argument '--paraview <path>' or "
"the TRAME_PARAVIEW environment variable"
)
raise Exception(msg)


# Each of the following functions returns a list of paths to try
# for the specified OS.
def linux_paths():
py_major, py_minor = sys.version_info[:2]
return [f"lib/python{py_major}.{py_minor}/site-packages"]


def mac_paths():
return ["Contents/Python"]


def windows_paths():
return ["bin/Lib/site-packages"]


search_paths_dict = {
"Linux": linux_paths,
"Darwin": mac_paths,
"Windows": windows_paths,
}

if platform.system() == "Darwin":
# We haven't been able to successfully run this on the Mac yet. So warn
# the user that it might fail.
print("WARNING: prepending the ParaView environment on Mac has not been "
"demonstrated to work successfully. It will likely fail.")

PV_LOADED = prepend_python_path(PV_HOME, search_paths_dict)
if not PV_LOADED:
raise Exception(f"Failed to add paraview python libraries at {PV_HOME}")
66 changes: 66 additions & 0 deletions trame/env/utils.py
@@ -0,0 +1,66 @@
import os
import platform
import site
import sys


def find_env_setting(arg, env_var_name):
# We check sys.argv for the arg, and os.environ for the env_var_name
# The argument gets precedence
if arg in sys.argv:
return os.path.abspath(sys.argv[sys.argv.index(arg) + 1])

if os.environ.get(env_var_name):
return os.path.abspath(os.environ.get(env_var_name))


def prepend_python_path(root_dir, search_paths_dict):
# root_dir is the root directory which we will search
# search_paths_dict is a dictionary with "Linux", "Darwin" (Mac),
# and "Windows" keys, with niladic functions for the values that
# returns a list of the paths to search. The paths for the current
# OS will be used.

# Returns True on success, False on failure

# Make sure the python lib dir can be found
python_lib_path = find_python_path(root_dir, search_paths_dict)
if python_lib_path is None:
# A warning should be printed already from find_python_path()
return False

# Use site.addsitedir() to automatically process .pth files.
# This also appends the paths to sys.path. We will move the new
# paths to the front of sys.path.
prev_length = len(sys.path)
site.addsitedir(python_lib_path)
sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]

return True


def find_python_path(root_dir, search_paths_dict):
# Returns the python path, or None if it was not found

if not os.path.exists(root_dir):
print(f"Warning: path '{root_dir}' does not exist")
return None

if platform.system() not in search_paths_dict:
raise Exception(f"Unhandled system: {platform.system()}")

paths_to_try = search_paths_dict[platform.system()]()
found = False
for path in paths_to_try:
full_path = os.path.join(root_dir, path)
if os.path.exists(full_path):
found = True
break

if not found:
paths_str = "\n".join(paths_to_try)
print("Warning: python library path could not be found in "
f"'{root_dir}'. Tried:\n{paths_str}\n")
return None

return full_path

0 comments on commit 7438f44

Please sign in to comment.