Python: Programmatically Running "pip List"
Solution 1:
The top answers as of 2/1/2019 are outdated and no longer work with newer versions of pip.
But no worries - it's still possible to get a list of packages programmatically:
Options:
A. _internal.main
from pip import _internal
_internal.main(['list'])
This will print out three columns with Package. Version, and Location
Note that usage of pip's internal api is not recommended.
B. pkg_resources
import pkg_resources
print([p.project_name for p in pkg_resources.working_set])
# note that thisis same as calling pip._vendor.pkg_resources.working_set
C. iter_modules
Takes a long time to execute (~300ms on computer w/ I5 CPU, SSD, & 8 gigs ram). The benefit is that it will have a far more extensive list of modules and it will output importable names.
Ex: python-dateutil is imported as dateutil, but iter_modules will give you the importable name: dateutil
from pkgutil import iter_modules
print([p.name for p in iter_modules()])
D. Call pip in command line via subprocess
The solution to this is trivial and I'll leave this as an exercise to the reader
aka I'm too lazy to do this, good luck! :D
Solution 2:
Update for Python 3.6 and Pip 19.0.1
> from pip._internal.utils.miscimport get_installed_distributions
> p = get_installed_distributions()
> pprint.pprint(p)
[wheel 0.32.3 (/usr/local/lib/python3.7/site-packages),
wcwidth 0.1.7 (/usr/local/lib/python3.7/site-packages),
virtualenv 16.0.0 (/usr/local/lib/python3.7/site-packages),
virtualenv-clone 0.3.0 (/usr/local/lib/python3.7/site-packages),
urllib3 1.24.1 (/usr/local/lib/python3.7/site-packages),
typing 3.6.6 (/usr/local/lib/python3.7/site-packages),
terminaltables 3.1.0 (/usr/local/lib/python3.7/site-packages),
...
Original Answer
Pip is just python module, so just import it and call list
:
import pip
pip.main(['list'])
# you can get details on package using show:
pip.main(['show', 'wheel'])
Ok so there is better way:
pip.utils.get_installed_distributions()
returns you list of packages installed.
packages = pip.utils.get_installed_distributions()
p = packages[0]
p.project_name
p.version
p.egg_name
p.location
You can see what pip list
is doing from the source code here
Also get_installed_distributions
accept whole bunch of parameters to return only local packages (from current virtualenv) etc. Please see help here.
There is also underlying low level command from _vendor
module:
[p for p in pip._vendor.pkg_resources.working_set]
However get_installed_distributions
provide simplier api.
Solution 3:
Use os module or system module
import os
import subprocess as su
os.system("pip list")
su.call(["pip","list"])
Solution 4:
For completeness, here's vittore's pip.main()
idea fleshed out with the capture of stdout. Of course using get_installed_distributions()
is the preferred solution.
import contextlib
@contextlib.contextmanager
def capture():
import sys
from cStringIO import StringIO
oldout,olderr = sys.stdout, sys.stderr
try:
out=[StringIO(), StringIO()]
sys.stdout,sys.stderr = outyieldoutfinally:
sys.stdout,sys.stderr = oldout, olderr
out[0] = out[0].getvalue()
out[1] = out[1].getvalue()
withcapture() asout:
import pip
pip.main(['list'])
print out
['awscli (1.7.45)\nboto (2.38.0) ...
Post a Comment for "Python: Programmatically Running "pip List""