Substance Painter Python pip installs

I’m trying to import a module (numpy) within substance painter using pip within a python plugin. That’s if it does not exist.

I thought you could import pip and use pip.main([“install”, “numpy”])

import pip
    try:
        __import__("numpy")
    except:
        pip.main(["install", "numpy"]) 

It installs but I get a warning regarding having an older version of pip.

Any cleaner way of doing this would really help.

Note: I have never install a pip module before. :slightly_smiling_face:

Afaik, it’s generally frowned upon (and also not “supported” )

I’d probably suggest packaging the pip’d module with your plugin instead and just have your script add it to PATH on startup? (or if this is for an internal company thing, just make sure you add it on Painter startup. Should work fine (as that’s what we do as well).

1 Like

That’s good to know. I’m going to take the same route as you suggested.

Thanks for the update, really does help. :slightly_smiling_face: :+1:

1 Like

You can still run pip from within your code in order to install numpy if you don’t want to bundle it with your Substance plugin. You just need to call it as an external process.

(make sure sys.executable is the python.exe and not substance.exe)

import sys
import subprocess

subprocess.check_call(
    [sys.executable, "-m", "pip", "install", "numpy"], creationflags=subprocess.CREATE_NEW_CONSOLE
)
1 Like

I found packaging the pip module with the plugin wont work with p4pthon pip. This is due to the .pyd that comes with P4.py file needing to be in appData\Roaming. So subprocess would be the way forward. Using that approach has worked. Thanks @ross-g

Below shows code to check p4pthyon is present in Painter before my bespoke menu is built. If it’s not present to user, then it will be intsalled with pip.

import sys
import subprocess


class SubstancePainterP4_Setup:
    """
    Description: Checks and installs  p4python!
    """

    @staticmethod
    def install_p4python():
        try:
            __import__("P4")
        except:
            substance_exe_path = sys.executable  # Get Substance Painter .exe path
            substance_exe_name = substance_exe_path.split("/")[-1]  # Get substance painter .exe name
            python_exe = substance_exe_path.replace(substance_exe_name,
                                                    "resources/pythonsdk/python.exe")
            subprocess.check_call([python_exe, "-m", "pip", "install", "p4python"],
                                  creationflags=subprocess.CREATE_NEW_CONSOLE)
            print("p4python installed!")



def start_plugin():
    SubstancePainterP4_Setup.install_p4python()