Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify Python/PIP to automatically install modules when failed to import

Is there a way to modify python/pip to, whenever an import fails at runtime, it would try to install the module (by the same name) from pip and then import the module?

I'd say it would be a nicer default than to just throw an error. If after loading the module from pip any problems happen, then it would also throw an error, similar to when I notice I cannot import something, try pip install and then come to the same exact error message.

I know we can use requirements.txt for bundling a package, but I'm talking from a "client" (person running the script) rather than "provider" (person providing the script) perspective; that is, I, as a client, would like to be able to import any script and have dependencies be solved automatically.

I understand that this could potentially cause trouble, but whenever I see an ImportError I'd just try to pip install the module anyway. Only if the module wouldn't work after pip installation "would I ask further questions".

I thought of something like this snippet that would be "built in" to the python process:

def getDirectoryOfInterpreter(p):
    return "someway to return the directory"

try:
    import somemodule
except ImportError:
    os.system(getDirectoryOfInterpreter('THIS_INTERPRETER_BINARY') + ' pip install ' + "MODULE_NAME")
    import somemodule
like image 988
PascalVKooten Avatar asked Mar 31 '15 08:03

PascalVKooten


1 Answers

You can do this with pipimport, when using virtualenv. It probably works with the system python if you have appropriate privileges to write the necessary directories (at least site-packages, but your import might have some command that pip will try to put somewhere in the PATH). Since it is good practice to always use virtualenvs for you own development anyway, I never tried using pipimport with the system python.

You need to import pipimport into your virtualenv by hand:

virtualenv venv
source venv/bin/activate
pip install pipimport

Then create a file autopipimport.py that you import first in any module:

# import and install pipimport
import pipimport
pipimport.install()

Now in any other .py file you can do:

import autopipimport
import some.package.installable.by.pip

I once tried (auto of curiosity) to add the two pipimport related lines to venv/lib/python2.7/site.py to be automatically "loaded", but that was to early in the chain and did not work.

pipimport will only try to use pip to install a particular module once, storing information about what has been tried in a .pipimport-ignore file (should be under venv unless that is not writeable).

like image 100
Anthon Avatar answered Oct 18 '22 18:10

Anthon