0
$\begingroup$

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?

$\endgroup$
7
  • $\begingroup$ Is this one helping? python - How to import SciPy in Blender? - Blender Stack Exchange $\endgroup$
    – HikariTW
    Sep 15, 2020 at 2:20
  • $\begingroup$ @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). $\endgroup$ Sep 15, 2020 at 12:56
  • $\begingroup$ 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 $\endgroup$
    – HikariTW
    Sep 15, 2020 at 13:11
  • $\begingroup$ I'm on KDE Neon but all I want is for Blender to recognize ```~/.local/lib/python3.7/site-packages````as a place to look for packages. $\endgroup$ Sep 15, 2020 at 13:33
  • $\begingroup$ 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? $\endgroup$
    – HikariTW
    Sep 15, 2020 at 13:41

2 Answers 2

1
$\begingroup$

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 = sys.executable

def add_user_site():
    # 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"])

user_site_added = add_user_site()
enable_pip()
# All the modules you need, that don't come shipped with Blender
modules = ["module1", "module2", ...] 
for module in modules:
    install_module(module)
# If there was no user-site before...
if not user_site_added:
    add_user_site()
$\endgroup$
2
  • 2
    $\begingroup$ 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. $\endgroup$
    – Robert Gützkow
    Sep 15, 2020 at 18:36
  • $\begingroup$ I'll be more than happy to drop this Frankenstein of a workaround as soon as Blender offers a more elegant solution :D $\endgroup$ Sep 15, 2020 at 22:46
1
$\begingroup$

The paths available in Blender 3.x include /home/my-user/.config/blender/3.3/scripts/addons/modules which is writable. It is possible to install your Python packages in this directory directly. For example:

pip install --target=$HOME/.config/blender/3.3/scripts/addons/modules/ my_package

Or on Windows:

pip install --target=%appdata%\Blender Foundation\Blender\3.5\scripts\addons\modules my_package
$\endgroup$
1
  • 1
    $\begingroup$ That's %appdata%\Blender Foundation\Blender\3.5\scripts\addons\modules in Windows. One can also simply copy the module directories to the directory, from wherever they get install with system Python like maybe %appdata%\Python\Python310\site-packages $\endgroup$ Jun 14, 2023 at 22:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .