I am working under Blender 2.90 installed by snap.

If I try to run

subprocess.check_call([bpy.app.binary_path_python, "-m", "ensurepip"])


or

import ensurepip
ensurepip.bootstrap()


from within my Addon, I get told, that the site-packages of my Blender's Python are read-only. Is there any way to circumvent this?

• Is this one helping? python - How to import SciPy in Blender? - Blender Stack Exchange – HikariTW Sep 15 '20 at 2:20
• @HikariTW That thread was definitely interesting. However using the mentioned --user option installs the packages under ~/.local/lib/python3.7/site-packages. Is there any way to tell Blender to use those site-packages additionally to those installed under /snap/blender/45/2.90/python/lib/python3.7/site-packages which is unfortunately read-only (otherwise I would have installed my modules there in the first place). – TheBeautifulOrc Sep 15 '20 at 12:56
• Which OS/build are you aiming for? I don't think modify snap install folder is a good idea. And if addon need to deal with various OS/condition, ensure pip is definitely not enough – HikariTW Sep 15 '20 at 13:11
• I'm on KDE Neon but all I want is for Blender to recognize ~/.local/lib/python3.7/site-packagesas a place to look for packages. – TheBeautifulOrc Sep 15 '20 at 13:33
• Not familiar with kde neon, if you know exactly where the packages are: sys.path.append(R"~/.local/lib/python3.7/site-packages") might work? – HikariTW Sep 15 '20 at 13:41

Thanks to all the help, I was able to piece together a fully automatic solution that works at least on my system (tests on other Linux and Windows machines planned). It looks something like this:

import bpy
import sys
import importlib
import subprocess

# Blender's Python executable
pybin = bpy.app.binary_path_python

# Locate users site-packages (writable)
user_site = subprocess.check_output([pybin, "-m", "site", "--user-site"])
user_site = user_site.decode("utf8").rstrip("\n")   # Convert to string and remove line-break
# Add user packages to sys.path (if it exits)
user_site_exists = user_site is not None
if user_site not in sys.path and user_site_exists:
sys.path.append(user_site)
return user_site_exists

def enable_pip():
if importlib.util.find_spec("pip") is None:
subprocess.check_call([pybin, "-m", "ensurepip", "--user"])
subprocess.check_call([pybin, "-m", "pip", "install", "--upgrade", "pip", "--user"])

def install_module(module : str):
if importlib.util.find_spec(module) is None:
subprocess.check_call([pybin, "-m", "pip", "install", module, "--user"])


• Please note that automatic loading of user site-packages was intentionally disabled, see T76993. Manually appending to sys.path` works, but there may be a different preferred approach in the future if progress is made on T71420. Until then this approach is a viable alternative. – Robert Gützkow Sep 15 '20 at 18:36