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()
--useroption 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-packageswhich is unfortunately read-only (otherwise I would have installed my modules there in the first place). – TheBeautifulOrc Sep 15 '20 at 12:56sys.path.append(R"~/.local/lib/python3.7/site-packages")might work? – HikariTW Sep 15 '20 at 13:41Raccomplish? – TheBeautifulOrc Sep 15 '20 at 15:35\\, it's python feature – HikariTW Sep 15 '20 at 15:39