I have recently been programming in QGIS plugin with python using an extension from pip package management. I installed this extension "browserhistory" manually via the OSGeo4W shell. However, when I now want to pass this plugin to someone else, he gets the error message: "No module named browser-history". How can I modify the code of the plugin in such a way that this pip extension is automatically installed when the plugin is installed on another computer? So that the other person does not have to install pip manually.
2 Answers
A QGIS plugin, written in python is a same as writing a python package, but it has no installation like a package usually has (pip, setuptools). So plugin developer, who wanted to include third-party-modules/packages can't resolve that dependencies.
Though there are functions within a python standard installation, that can be used from within python code to "install" third-party modules. You may use one of the solutions discussed here: https://stackoverflow.com/questions/12332975/installing-python-module-within-code, so each time the plugin is loaded by QGIS, you'll check if it can be imported, otherwise you install it.
For the specific package, browser-history, a simpler solution exists. Because that package has no further dependencies, you can integrate it into your Python plugin, by copying the whole package directory as a subfolder into the plugin folder. By doing this you'll get a package containing another package. So when importing browser_history
inside your main plugin module you'll use a relative import (https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time).
This looks like this, for example:
from . import browser_history
To generalize the problem: each python module or packages which has no further dependencies, can be integrated into a Python plugin, but it is not more than a workaround with advantages and disadvantages. Furthermore, if you try using pip inside your code, especially under Windows, using OSGeo4W, the use of pip may fail, when dependent modules use a C-Compiler for installation for example. That's why many python packages can be installed using the setup utility that comes with QGIS.
You could create a stand-alone Python executable. This will work for libraries that are not proprietary (like arcpy) See this link. Unfortunately, this will result in a rather large file since the entire Python interpreter will be packaged as well. Furthermore, you will need to locate the EXE inside the resulting file structure.
Better would be to package your project as a Python installation. Here are some links to get you started. This works if the libraries you want to pass on are available at PyPI and you have those setup.py and requirements.txt file correct. Still, the user would need to download your installer folder. Navigate to that location at the command line, and enter the python setup.py install
stuff to get that stuff installed.
-
QGIS plugins are python packages with an Interface to Qgis, so the "executable option" does not work. Furthermore the plugin will be called from a fixed place inside the user profile. At least the plugin has no installation routine, it is just unpacked into the profile path. Commented Apr 12, 2021 at 17:38
-
Yeah thats true. I think converting my plugin into an "exe"-file won't solve the problem ! Commented Apr 12, 2021 at 18:32
-
from . import browserhistory
.