jetforce
jetforce copied to clipboard
ModuleNotFoundError for packages pip installed system-wide
Given a Python CGI script, containing, e.g.
import qrcode
...Where qrcode was installed with sudo pip install qrcode
, and can be found in /usr/local/lib/python3.8/dist-packages
, where it is available to an interactive Python session or the same script executed from the command line;
When the CGI script is executed by Jetforce, a ModuleNotFoundError is triggered.
By placing the following code at the top of my script:
import sys
print('20 text/plain\r')
print(sys.path)
...I was able to determine that the Python environment looks like this:
/srv/gemini/cgi-bin/ /lib/python38.zip /lib/python3.8 /lib/python3.8/lib-dynload /lib/python3/dist-packages
See that /usr/local/lib/python3.8/dist-packages
is missing.
It seems to be impossible to modify the module search paths with the PYTHONPATH environment variable in the systemd service.
How might i be able to work around the problem and make use of Python modules not in the standard library in my CGI script?
Haven't tried this, but as a quick hack, you might be able to write a bash CGI script that calls python3
. You could do export PYTHONPATH=
there if needed as well.
Yea I think it's probably security best practice to not pass the whole environment from the server process to the child process, because the server process environment may contain sensitive information.
In addition to @makeworld-the-better-one 's suggestion, you could alternatively set a custom path at the top of your python script. it looks like your python install is kind of wonky because you shouldn't have to do this at all, but 🤷
import sys
sys.path.insert(0, "/usr/local/lib/python3.8/dist-packages")
Yes, that's a better and simpler solution. I forgot you could do that.
Thank you, this suggestion is what i ended up doing as a workaround, to have a working CGI script, until the reasons for the missing lookup path become apparent and can be dealt with.