Openpyxl module

It looks like you have it installed on a python instance (3.11) that is not being used by Dynamo
You can find the install location OUT = sys.path which will return a few paths

C:\Users\<username>\AppData\Local\python-3.8.3-embed-amd64\python38.zip,
C:\Users\<username>\AppData\Local\python-3.8.3-embed-amd64,
C:\Users\<username>\AppData\Local\python-3.8.3-embed-amd64\lib\site-packages

pip is not always the easiest module to install with Dynamo
Try this in a Python node with CPython3

import subprocess
import sysconfig
from pathlib import Path  # python3 library

# Get file / exe locations for running Python install
pypath = Path(sysconfig.get_path("data"))  # root path to python install
pyexe = pypath / "python.exe"
pipexe = pypath / "Scripts/pip.exe"


def getpip():
    """Install pip from the internets"""
    if pipexe.exists():
        return f"Pip already installed at {str(pipexe)}"
    # Fingers crossed the enterprise firewall lets this through
    comm = ["curl", "https://bootstrap.pypa.io/get-pip.py", "|", pyexe, "-"]
    return subprocess.run(comm, capture_output=True, shell=True)


OUT = getpip()

You may have to reload the Dynamo graph to get access to pip, you may also have to uncomment the import site line in the python<version>._pth file (e.g. python38._pth) located in the python root folder (pypath above)

Then you can install from a list or string of module names with a function something like this

def install(package):
    comm = [pyexe, "-m", "pip", "install"]
  
    if isinstance(package, str):
        comm += package.split()
    elif isinstance(package, list):
        comm += package
    else:
        raise TypeError("Input is not string or list of python modules")

    return subprocess.run(comm, capture_output=True, shell=True)
2 Likes