1073

I would like to get a list of Python modules, which are in my Python installation (UNIX server).

How can you get a list of Python modules installed in your computer?

nbro
  • 12,226
  • 19
  • 85
  • 163
Léo Léopold Hertz 준영
  • 119,377
  • 159
  • 417
  • 655

31 Answers31

1117
help('modules')

in a Python shell/prompt.

ChristopheD
  • 100,699
  • 26
  • 154
  • 173
  • I get such a warning: FutureWarning: apt API not stable yet warnings.warn("apt API not stable yet", FutureWarning). I did not get a list of Python modules. I am using Python 2.5. – Léo Léopold Hertz 준영 Apr 11 '09 at 13:05
  • Could you paste the entire warning at for example http://paste.pocoo.org and post the link here? – ChristopheD Apr 11 '09 at 13:11
  • “/usr/lib/python2.5/site-packages/apt/__init__.py:18: FutureWarning: apt API not stable yet” is normal on Debian/Ubuntu Pythons, an artefact of attempting to graft apt packages into Python package management. I still see the (textual) list of modules. – bobince Apr 11 '09 at 13:17
  • 12
    @dF `pydoc modules` works. You should submit it as an answer. – Abizern Apr 11 '09 at 13:30
  • @dF: pydoc modules, gives me the exactly same output as in python shell: help('modules') – Léo Léopold Hertz 준영 Apr 11 '09 at 13:34
  • @Masi: matplotlib related problem according to http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=519965 Should be fixed in the latest version available from http://matplotlib.sourceforge.net/ @Abizern: pydoc modules and help('modules') do the same thing... – ChristopheD Apr 11 '09 at 13:38
  • @ChristopheD: How can I see the version of my matplotlib? I tried import matplotlib; matplotlib --version unsuccessfully. – Léo Léopold Hertz 준영 Apr 11 '09 at 16:20
  • WARNING: This killed my window manager (Ubuntu/Compiz) for some reason. – Brent Bradburn Nov 19 '12 at 06:33
  • 3
    nobar, zanbri, @Joe Frambach: on Ubuntu? There's a bug described here: https://bugs.launchpad.net/ubuntu/+source/python2.7/+bug/896836 – ChristopheD Apr 11 '13 at 17:30
  • FYI , the Ubuntu segfault bug per @ChristopheD is still unassigned. – AnneTheAgile Oct 31 '14 at 14:32
  • 2
    how can i get extra info about where the modules are installed and what is the current version? – curious Nov 07 '14 at 09:48
  • With Python 2.6.5 on Ubuntu Linux 10 this only works with root privileges (sudo pydoc modules). On my system it also tries to configure the output for speech synthesis, so answer "no" to the first two questions and a few seconds later it lists all the installed modules by name-only in a four-column format. – Andrew P. Apr 04 '18 at 16:49
  • MemoryError. Thx for that :P – StudySmarterNotHarder Apr 21 '19 at 07:08
  • 10
    `python -c 'help("modules")'` – kenorb Nov 18 '19 at 16:56
  • It seems this does not show modules installed via namespace packages. (while e.g. pip list does) – oh54 Mar 16 '20 at 19:45
641

Solution

Do not use with pip > 10.0!

My 50 cents for getting a pip freeze-like list from a Python script:

import pip
installed_packages = pip.get_installed_distributions()
installed_packages_list = sorted(["%s==%s" % (i.key, i.version)
     for i in installed_packages])
print(installed_packages_list)

As a (too long) one liner:

sorted(["%s==%s" % (i.key, i.version) for i in pip.get_installed_distributions()])

Giving:

['behave==1.2.4', 'enum34==1.0', 'flask==0.10.1', 'itsdangerous==0.24', 
 'jinja2==2.7.2', 'jsonschema==2.3.0', 'markupsafe==0.23', 'nose==1.3.3', 
 'parse-type==0.3.4', 'parse==1.6.4', 'prettytable==0.7.2', 'requests==2.3.0',
 'six==1.6.1', 'vioozer-metadata==0.1', 'vioozer-users-server==0.1', 
 'werkzeug==0.9.4']

Scope

This solution applies to the system scope or to a virtual environment scope, and covers packages installed by setuptools, pip and (god forbid) easy_install.

My use case

I added the result of this call to my flask server, so when I call it with http://example.com/exampleServer/environment I get the list of packages installed on the server's virtualenv. It makes debugging a whole lot easier.

Caveats

I have noticed a strange behaviour of this technique - when the Python interpreter is invoked in the same directory as a setup.py file, it does not list the package installed by setup.py.

Steps to reproduce:

Create a virtual environment
$ cd /tmp
$ virtualenv test_env
New python executable in test_env/bin/python
Installing setuptools, pip...done.
$ source test_env/bin/activate
(test_env) $ 
Clone a git repo with setup.py
(test_env) $ git clone https://github.com/behave/behave.git
Cloning into 'behave'...
remote: Reusing existing pack: 4350, done.
remote: Total 4350 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (4350/4350), 1.85 MiB | 418.00 KiB/s, done.
Resolving deltas: 100% (2388/2388), done.
Checking connectivity... done.

We have behave's setup.py in /tmp/behave:

(test_env) $ ls /tmp/behave/setup.py
/tmp/behave/setup.py
Install the python package from the git repo
(test_env) $ cd /tmp/behave && pip install . 
running install
...
Installed /private/tmp/test_env/lib/python2.7/site-packages/enum34-1.0-py2.7.egg
Finished processing dependencies for behave==1.2.5a1

If we run the aforementioned solution from /tmp

>>> import pip
>>> sorted(["%s==%s" % (i.key, i.version) for i in pip.get_installed_distributions()])
['behave==1.2.5a1', 'enum34==1.0', 'parse-type==0.3.4', 'parse==1.6.4', 'six==1.6.1']
>>> import os
>>> os.getcwd()
'/private/tmp'

If we run the aforementioned solution from /tmp/behave

>>> import pip
>>> sorted(["%s==%s" % (i.key, i.version) for i in pip.get_installed_distributions()])
['enum34==1.0', 'parse-type==0.3.4', 'parse==1.6.4', 'six==1.6.1']
>>> import os
>>> os.getcwd()
'/private/tmp/behave'

behave==1.2.5a1 is missing from the second example, because the working directory contains behave's setup.py file.

I could not find any reference to this issue in the documentation. Perhaps I shall open a bug for it.

Matt
  • 24,656
  • 6
  • 74
  • 72
Adam Matan
  • 107,447
  • 124
  • 346
  • 512
  • 5
    Thank you for this answer! I think it better answers the question because I ask "locally" installed Python modules. Pip freeze is also not always the way to go. This works better - I think. – Léo Léopold Hertz 준영 May 27 '14 at 10:54
  • `pkgutil.iter_modules()` works (see @Johnysweb's answer); this pip solution above doesn't list all packages, just the ones installed via pip – metaperture May 29 '14 at 20:07
  • @metaperture `pip.get_installed_distributions()` displays packages installed by `pip`, `easy_install`, and `setuptools` (`python setup.py install`). The only exception - not sure if it's a bug - is that it does not show a package if it's called in the same directory of its `setup.py`. – Adam Matan Jun 03 '14 at 05:30
  • I awarded the bounty to this new answer because it works in the entire system or a virtual environment. Johnsyweb mentions some useful points, but I still see that this answer is better in the entire system or virtual. Please, provide me examples if Johnsyweb or any other answer is better than this. – Léo Léopold Hertz 준영 Jun 03 '14 at 17:22
  • Please, let me know if you understand this better" I have noticed a strange behaviour of this technique - when the Python interpreter is invoked in the same directory as a setup.py file, it does not list the package installed by setup.py". It may be related to same issues which I have had in different runtimes and warmup situations. – Léo Léopold Hertz 준영 Jun 03 '14 at 17:26
  • @Masi Thanks for the bounty. I will update my answer with an example. – Adam Matan Jun 03 '14 at 20:12
  • 3
    @Masi Just added a detailed explanation of the caveat of this solution. It is indeed a strange one. – Adam Matan Jun 04 '14 at 06:41
  • @AdamMatan Just open a bug for it so we get better understanding in it. – Léo Léopold Hertz 준영 Jun 04 '14 at 07:23
  • 2
    @AdamMatan Actually, if you're using multiple python installs with site-packages in several directories, this will fail. It works assuming all your installs have been registered on the same python instance (via pip/easy_install/setuptools) but fails if you've modified your python path to include other installs (or custom libraries). For a normal workflow, this is probably fine, but it may not be robust. – metaperture Jun 04 '14 at 18:33
  • @metaperture Interesting - I did not think of that scenario. Does it mean that there can be a package that's available to the calling script, but will not be listed? – Adam Matan Jun 04 '14 at 18:36
  • 2
    @AdamMatan yes, entire directories can be added manually to $PYTHONPATH (or equivalently sys.path) and this method will never notice them. In a clean setup, this probably won't happen, but my work has severe permissions restrictions so many of us run on a mashup of "canonical environment" with proprietary libs and "custom environment" where we have complete permissions. When I tested your method on either environment packages from the other didn't show up. – metaperture Jun 05 '14 at 04:13
  • There must be a workaround for this. @AdamMatan Have you thought about it? I think the PYTHONPATH should be included somewhere. Checking it first, and then doing similar thing as you do here. – Léo Léopold Hertz 준영 Jun 06 '14 at 16:09
  • 1
    Filed bug upstream at https://github.com/pypa/pip/issues/3091, copying the bugs.python.org issue above – David Fraser Sep 10 '15 at 15:08
  • missed "import pip; " before one-liner in second code sample :) – Denis Barmenkov Apr 05 '16 at 14:29
  • 1
    @DenisBarmenkov Right, and the `print` command is also missing. I figured out it would be clear from context. – Adam Matan Apr 05 '16 at 14:44
  • 1
    `print '\n'.join(installed_packages_list)` gave a prettier, easier to read list in 2.7 – ViFI Jul 12 '16 at 18:22
  • 28
    An alternative: `import pkg_resources; installed_packages = [(d.project_name, d.version) for d in pkg_resources.working_set]` – ebolyen Sep 14 '16 at 17:45
  • The import can go on the front, like so: import pip;sorted(["%s==%s" % (i.key, i.version) for i in pip.get_installed_distributions()]) – David A. Gray Jul 27 '17 at 21:04
  • 1
    My next goal is to figure out how to format the listing with one item per line. – David A. Gray Jul 27 '17 at 21:05
  • 1
    Improving on the excellent one-line script posted by @Adam Matan, I made an improved script that iterates the sequence returned by sorted, yielding a much more digestible listing. The script, ListInstalledPackages.py, is at https://p6lists-my.sharepoint.com/personal/dagray_p6lists_com/_layouts/15/guestaccess.aspx?docid=184919bbb2a214b33956de3a1b5b53a0b&authkey=ATSPl5golpQ0yRjf1tuaC2I, along with sample output at https://p6lists-my.sharepoint.com/personal/dagray_p6lists_com/_layouts/15/guestaccess.aspx?docid=130e554b3388645cca5b2f9da1ad157f9&authkey=Aeeat2w1ZTLZmYrymDCuAsA. – David A. Gray Jul 28 '17 at 06:03
  • 1
    Since I'm still new to writing in Python, the script that I just mentioned is a bit more than one line (10 altogether, 3 providing the core functionality, to which the other 7 add some beautification. Even so, it's one line from a shell, since you have only to invoke the script, and pipe its output to a file. – David A. Gray Jul 28 '17 at 06:07
  • 16
    As of pip 10, this answer will no longer work. The comment from @ebolyen shows alternative commands that do work. I came to the same conclusion and posted the complete revised code below. – Big_Al_Tx Apr 25 '18 at 03:06
  • 10
    In recent versions of pip, this won't work, yielding an error message saying `AttributeError: module 'pip' has no attribute 'get_installed_distributions'`. – HelloGoodbye Dec 28 '18 at 15:12
  • I want to run your code. But I received this error: AttributeError: module 'pip' has no attribute 'get_installed_distributions' – BarzanHayati Aug 12 '19 at 17:08
  • 1
    No. This is not recommended, see here: https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program – sinoroc Dec 12 '19 at 14:24
  • @ebolyen what about system packages? (like os) They do not show up with your method. Any ideas about how to integrate them in the result? – Michele Piccolini Feb 03 '20 at 15:50
305

Now, these methods I tried myself, and I got exactly what was advertised: All the modules.

Alas, really you don't care much about the stdlib, you know what you get with a python install.

Really, I want the stuff that I installed.

What actually, surprisingly, worked just fine was:

pip freeze

Which returned:

Fabric==0.9.3
apache-libcloud==0.4.0
bzr==2.3b4
distribute==0.6.14
docutils==0.7
greenlet==0.3.1
ipython==0.10.1
iterpipes==0.4
libxml2-python==2.6.21

I say "surprisingly" because the package install tool is the exact place one would expect to find this functionality, although not under the name 'freeze' but python packaging is so weird, that I am flabbergasted that this tool makes sense. Pip 0.8.2, Python 2.7.

chiggsy
  • 7,405
  • 5
  • 31
  • 42
  • 4
    I guess the idea behind the name is that you get a "frozen" snapshot of what is installed right now, which you can later feed back into pip to get exactly the same modules installed in a different environment. – Ryan C. Thompson Dec 16 '11 at 01:25
  • Arash, you can install pip in Windows too! First install setuptools and then use easy_install to install pip :) – gawbul May 08 '12 at 10:02
  • This is excellent, but it seems to miss some of the libraries I installed. For example, it doesn't list PyQt. – Junuxx Jun 02 '12 at 10:27
  • 9
    Starting from pip 1.3 there's the [list](http://www.pip-installer.org/en/latest/usage.html#pip-list) command. – Piotr Dobrogost Mar 13 '13 at 22:00
  • it works. What a mess python is. Why can they not get their act together and come up with solutions similar to what exists in Rails? (Gemfile, bundler, rvm) – Dimitris Jul 23 '13 at 11:38
  • Note that even if you didn't install your packages using pip, pip will still be able to list most of your modules along with their versions, which is great! An alternative script I made: https://gist.github.com/lrq3000/6175522 – gaborous Aug 07 '13 at 16:15
  • Also you can get the same result as "pip freeze" in a Python shell using: pip.get_installed_distributions() – gaborous Aug 07 '13 at 16:16
  • @Dimitris rvm only works on Linux, and it's not as flexible as virtualenv. You can now distribute packages using source distributions or wheels. pip can create a bundle of packages, if you really want. It took some time to sort everything out, but Python *has* it's act together now, and better than Ruby. – jpmc26 Mar 16 '16 at 00:32
  • Actually, this does NOT return a complete list of installed modules on my system, although I can't tell if it's related to the version of pip being used (I'm running pip 10). – Big_Al_Tx Apr 25 '18 at 02:51
117

Since pip version 1.3, you've got access to:

pip list

Which seems to be syntactic sugar for "pip freeze". It will list all of the modules particular to your installation or virtualenv, along with their version numbers. Unfortunately it does not display the current version number of any module, nor does it wash your dishes or shine your shoes.

Bryce
  • 7,335
  • 6
  • 51
  • 71
91
  • In ipython you can type "importTab".

  • In the standard Python interpreter, you can type "help('modules')".

  • At the command-line, you can use pydoc modules.

  • In a script, call pkgutil.iter_modules().

Johnsyweb
  • 121,480
  • 23
  • 172
  • 229
  • 6
    `pkgutil.iter_modules()` works, the pip solution above doesn't list all packages, just the ones installed via pip. – metaperture May 29 '14 at 20:07
  • 2
    Awesome! I think they have improved documentation, since the question was asked. **pydoc modules spam** searches spam in docs of modules. The last point seems to give you the sufficient information to use the module. @metaperture Can you, please, give an example how you list all local modules installed (not the massive list of stlib by help('modules')) by **pkgutil.iter_modules()**. – Léo Léopold Hertz 준영 May 29 '14 at 21:17
  • 2
    @LéoLéopoldHertz준영 Try this snippet: `python -c 'import pkgutil;print [x[1] for x in list(pkgutil.iter_modules())]'`. It should dump all the module names as one really big Python list. The `x[1]` bit is used to pluck the module name out of the tuples generated by `pkgutil.iter_modules()`. – Philip Conrad Feb 09 '17 at 08:08
85

I just use this to see currently used modules:

import sys as s
s.modules.keys()

which shows all modules running on your python.

For all built-in modules use:

s.modules

Which is a dict containing all modules and import objects.

caesarsol
  • 1,661
  • 1
  • 15
  • 19
Dan Evans
  • 967
  • 6
  • 6
  • 2
    # After you import sys "import sys as s" you can print with: print sys.modules.keys() – Dan Evans Jun 22 '12 at 23:44
  • Not sure why my post was edited, but thank you for using the info I posted to correct the mistakes in prior posts. You will return errors if you use help() vs help(''). This goes for dir('') & sys('') etc. as well. Hope this helps & is not removed. – Dan Evans Jun 24 '12 at 21:03
  • Ignore my last post, this post was not edited. I was thinking of a similar post found here: http://stackoverflow.com/questions/139180/listing-all-functions-in-a-python-module/11173131#11173131 Sorry for the confusion. – Dan Evans Jun 24 '12 at 22:56
  • 8
    Upvoted, because this is the only method that seems to work on constrained systems which have neither `pydoc` nor `pip` installed (a NAS in my case). – Thomas Oct 23 '16 at 10:09
  • 1
    Agreed with Thomas. I'm using repl.it , for example, which is also a constrained type of environment. `help('modules')` just hangs without response for me. But this approach with `sys` works perfectly – Sergiy Kolodyazhnyy Jan 20 '17 at 19:47
  • This works in Python 2.6, too, without having to start the Python shell with root privileges ("sudo python") on Linux, as does "help('modules')". Output is on one long, messy line, but can easily be cleaned up for viewing by copying it into a text editor and replacing all commas with a newline. – Andrew P. Apr 04 '18 at 16:37
64

In normal shell just use

pydoc modules
DrkNess
  • 656
  • 5
  • 4
  • It appears that the above works only on 'nix platforms. In any case, I found and ran the script, adapting the command as follows: c:\bin\pythos_2.7\lib\pydoc.py modules - that list took forever to build, the format sucks, and it omits the installed version number. I'll pass. – David A. Gray Jul 28 '17 at 05:38
  • 2
    @DavidA.Gray Just tried this on a Windows machine with Python 3, and it does in fact work. Using the python windows launcher you can do `py -m pydoc modules` in cmd or Powershell. – VKK Mar 17 '18 at 19:12
  • `pydoc modules` didn't work for me in Windows 10 with Python 3.6, but @VKK modification: `py -m pydoc modules` does work in cmd/Powershell. – Martin Apr 18 '19 at 18:54
52

As of pip 10, the accepted answer will no longer work. The development team has removed access to the get_installed_distributions routine. There is an alternate function in the setuptools for doing the same thing. Here is an alternate version that works with pip 10:

import pkg_resources
installed_packages = pkg_resources.working_set
installed_packages_list = sorted(["%s==%s" % (i.key, i.version)
     for i in installed_packages])
print(installed_packages_list)

Please let me know if it will or won't work in previous versions of pip, too.

Big_Al_Tx
  • 824
  • 8
  • 13
  • 2
    I have been searching for this solution and wracking my brain trying to figure out pkg_resources. If I could upvote this more than once I would. Thank you, @Big_Al_Tx ! Update: Except.... when I do a 'pip freeze' in my virtual environment and compare it to the output of this, there are packages that are missing. Any thoughts on why that could/would happen? – numberwhun Jul 04 '18 at 19:40
  • @numberwhun - I'm glad this worked for you. I'm sorry, but I don't have an answer for the discrepancy with `pip freeze`; the depth of my knowledge on this topic is rather limited. I sort-of fumbled my way to the solution when the accepted answer didn't work for me and I tried combining it with an answer related to `setuptools` and got it to work. – Big_Al_Tx Jul 05 '18 at 20:59
  • https://github.com/pypa/pip/issues/5243 - The talk of development team about removed access to the `get_installed_distributions routine`. – bl79 Jul 26 '18 at 16:52
  • @bl79 - I think that's the exact place where I got the reference for `setuptools`. – Big_Al_Tx Jul 27 '18 at 17:55
  • @Big_Al_Tx: Well, I sort of worked around the setuptools option (which was waaaay to obfuscated for my needs) and I went with this: installed_pkgs = subprocess.check_output(['pip', 'freeze']) It does exactly what I needed it to do.... Yay!! – numberwhun Aug 15 '18 at 23:12
  • @numberwhun - Thanks for the follow-up. I'll have to check that out myself! – Big_Al_Tx Aug 17 '18 at 00:37
  • This works for me. It returns all installed packages in a Python list format. HOW CAN THIS BE MOVED UP TO THE TOP OF THIS POST AND BECOME THE ACCEPTED ANSWER FOR PYTHON 3.7.1 AND PIP > v10+ – Rich Lysakowski PhD Jul 08 '19 at 23:53
  • @RichLysakowskiPhD -- It only moves up higher in the list of responses as it gets more user "up" votes. The original poster accepted the answer above when they got that answer back in 2014, and I don't think it can be changed now. But I'm glad it worked for you and thanks for the support! – Big_Al_Tx Jul 10 '19 at 14:08
  • this should be the answer here. – petey m Jul 25 '19 at 13:44
31

If we need to list the installed packages in the Python shell, we can use the help command as follows

>>> help('modules package')
Black Thunder
  • 5,331
  • 5
  • 22
  • 52
Sadheesh
  • 695
  • 6
  • 6
  • Only returns modules which has the word `package` in it's name or in it's docstring, which a lot of modules does not have. – Mandera Jan 15 '21 at 09:04
24

I normally use pip list to get a list of packages (with version).

This works in a virtual environment too, of course. To show what's installed in only the virtual environment (not global packages), use pip list --local.

Here's documentation showing all the available pip list options, with several good examples.

James
  • 1,318
  • 1
  • 12
  • 21
24

Works Regardless of Pip Version

Run the following in your python editor or IPython:

import pkg_resources
installed_packages = {d.project_name: d.version for d in pkg_resources.working_set}
print(installed_packages)

Read other answers and pulled together this combo, which is quickest and easiest inside Python.

Find the specific Packages

Conveniently you can then get items from your dict easily, i.e.

installed_packages['pandas'] >> '1.16.4'

Using Pip List Well

!pip list will run inside your jupyter notebook if working there, simplifying the 'quick check' Combine with other utilities like grep(if you have installed) pip list | grep pandas will get you your current pandas version for example

jabberwocky
  • 584
  • 3
  • 15
  • `pkg_resources` is part of _setuptools_. It has not much to do with _pip_. – sinoroc Jun 10 '20 at 14:46
  • Yep @sinoroc, but the accepted answer doesn't work beyond pip 10 which was the intent of the title – jabberwocky Jun 10 '20 at 15:02
  • 1
    Then I don't understand the logic of your title, since your solution is not limited to recent versions of pip. It should work for any version of _pip_ since it doesn't use _pip_ at all. Also you might want to look at `importlib.metadata` from Python's standard library since 3.8: https://docs.python.org/3/library/importlib.metadata.html – sinoroc Jun 10 '20 at 15:53
17

This will help

In terminal or IPython, type:

help('modules')

then

In [1]: import                      #import press-TAB
Display all 631 possibilities? (y or n)
ANSI                   audiodev               markupbase
AptUrl                 audioop                markupsafe
ArgImagePlugin         avahi                  marshal
BaseHTTPServer         axi                    math
Bastion                base64                 md5
BdfFontFile            bdb                    mhlib
BmpImagePlugin         binascii               mimetools
BufrStubImagePlugin    binhex                 mimetypes
CDDB                   bisect                 mimify
CDROM                  bonobo                 mmap
CGIHTTPServer          brlapi                 mmkeys
Canvas                 bsddb                  modulefinder
CommandNotFound        butterfly              multifile
ConfigParser           bz2                    multiprocessing
ContainerIO            cPickle                musicbrainz2
Cookie                 cProfile               mutagen
Crypto                 cStringIO              mutex
CurImagePlugin         cairo                  mx
DLFCN                  calendar               netrc
DcxImagePlugin         cdrom                  new
Dialog                 cgi                    nis
DiscID                 cgitb                  nntplib
DistUpgrade            checkbox               ntpath
Community
  • 1
  • 1
X Personified
  • 336
  • 4
  • 8
16

Try these

pip list

or

pip freeze
Amit Gupta
  • 1,636
  • 1
  • 17
  • 30
14

Very simple searching using pkgutil.iter_modules

from pkgutil import iter_modules
a=iter_modules()
while True:
    try: x=a.next()
    except: break
    if 'searchstr' in x[1]: print x[1]
stuudent
  • 352
  • 3
  • 11
  • 1
    is there any reason to use while instead of a for loop? I wrote using `for m in iter_modules()` and it did work as well. – Joao Ponte May 11 '20 at 14:12
13

on windows, Enter this in cmd

c:\python\libs>python -m pip freeze
Léo Léopold Hertz 준영
  • 119,377
  • 159
  • 417
  • 655
Saurabh
  • 6,001
  • 3
  • 38
  • 40
12

I ran into a custom installed python 2.7 on OS X. It required X11 to list modules installed (both using help and pydoc).

To be able to list all modules without installing X11 I ran pydoc as http-server, i.e.:

pydoc -p 12345

Then it's possible to direct Safari to http://localhost:12345/ to see all modules.

Qiau
  • 5,078
  • 3
  • 27
  • 40
9

This solution is primary based on modules importlib and pkgutil and work with CPython 3.4 and CPython 3.5, but has no support for the CPython 2.


Explanation

  1. sys.builtin_module_names - names all built-in modules (look my answer here)
  2. pkgutil.iter_modules() - returns an information about all available modules
  3. importlib.util.find_spec() - returns an information about importing module, if exists
  4. BuiltinImporter - an importer for built-in modules (docs)
  5. SourceFileLoader - an importer for a standard Python module (by default has extension *.py) (docs)
  6. ExtensionFileLoader - an importer for modules as shared library (written on the C or C++)

Full code

import sys
import os
import shutil
import pkgutil
import importlib
import collections

if sys.version_info.major == 2:
    raise NotImplementedError('CPython 2 is not supported yet')


def main():

    # name this file (module)
    this_module_name = os.path.basename(__file__).rsplit('.')[0]

    # dict for loaders with their modules
    loaders = collections.OrderedDict()

    # names`s of build-in modules
    for module_name in sys.builtin_module_names:

        # find an information about a module by name
        module = importlib.util.find_spec(module_name)

        # add a key about a loader in the dict, if not exists yet
        if module.loader not in loaders:
            loaders[module.loader] = []

        # add a name and a location about imported module in the dict
        loaders[module.loader].append((module.name, module.origin))

    # all available non-build-in modules
    for module_name in pkgutil.iter_modules():

        # ignore this module
        if this_module_name == module_name[1]:
            continue

        # find an information about a module by name
        module = importlib.util.find_spec(module_name[1])

        # add a key about a loader in the dict, if not exists yet
        loader = type(module.loader)
        if loader not in loaders:
            loaders[loader] = []

        # add a name and a location about imported module in the dict
        loaders[loader].append((module.name, module.origin))

    # pretty print
    line = '-' * shutil.get_terminal_size().columns
    for loader, modules in loaders.items():
        print('{0}\n{1}: {2}\n{0}'.format(line, len(modules), loader))
        for module in modules:
            print('{0:30} | {1}'.format(module[0], module[1]))


if __name__ == '__main__':
    main()

Usage

For the CPython3.5 (truncated)

$ python3.5 python_modules_info.py 
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
30: <class '_frozen_importlib.BuiltinImporter'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_ast                           | built-in
_codecs                        | built-in
_collections                   | built-in
_functools                     | built-in
_imp                           | None
_io                            | built-in
_locale                        | built-in
_operator                      | built-in
_signal                        | built-in
_sre                           | built-in
_stat                          | built-in
_string                        | built-in
_symtable                      | built-in
_thread                        | built-in
(****************************truncated*******************************)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
227: <class '_frozen_importlib_external.SourceFileLoader'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__future__                     | /usr/local/lib/python3.5/__future__.py
_bootlocale                    | /usr/local/lib/python3.5/_bootlocale.py
_collections_abc               | /usr/local/lib/python3.5/_collections_abc.py
_compat_pickle                 | /usr/local/lib/python3.5/_compat_pickle.py
_compression                   | /usr/local/lib/python3.5/_compression.py
_dummy_thread                  | /usr/local/lib/python3.5/_dummy_thread.py
_markupbase                    | /usr/local/lib/python3.5/_markupbase.py
_osx_support                   | /usr/local/lib/python3.5/_osx_support.py
_pydecimal                     | /usr/local/lib/python3.5/_pydecimal.py
_pyio                          | /usr/local/lib/python3.5/_pyio.py
_sitebuiltins                  | /usr/local/lib/python3.5/_sitebuiltins.py
(****************************truncated*******************************)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
64: <class '_frozen_importlib_external.ExtensionFileLoader'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_bisect                        | /usr/local/lib/python3.5/lib-dynload/_bisect.cpython-35m-x86_64-linux-gnu.so
_bz2                           | /usr/local/lib/python3.5/lib-dynload/_bz2.cpython-35m-x86_64-linux-gnu.so
_codecs_cn                     | /usr/local/lib/python3.5/lib-dynload/_codecs_cn.cpython-35m-x86_64-linux-gnu.so
_codecs_hk                     | /usr/local/lib/python3.5/lib-dynload/_codecs_hk.cpython-35m-x86_64-linux-gnu.so
_codecs_iso2022                | /usr/local/lib/python3.5/lib-dynload/_codecs_iso2022.cpython-35m-x86_64-linux-gnu.so
(****************************truncated*******************************)

For the CPython3.4 (truncated)

$ python3.4 python_modules_info.py
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
54: <class '_frozen_importlib.BuiltinImporter'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_ast                           | built-in
_bisect                        | built-in
_codecs                        | built-in
_collections                   | built-in
_datetime                      | built-in
_elementtree                   | built-in
_functools                     | built-in
_heapq                         | built-in
_imp                           | None
_io                            | built-in
_locale                        | built-in
_md5                           | built-in
_operator                      | built-in
_pickle                        | built-in
_posixsubprocess               | built-in
_random                        | built-in
(****************************truncated*******************************)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
246: <class '_frozen_importlib.SourceFileLoader'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__future__                     | /usr/lib/python3.4/__future__.py
_bootlocale                    | /usr/lib/python3.4/_bootlocale.py
_collections_abc               | /usr/lib/python3.4/_collections_abc.py
_compat_pickle                 | /usr/lib/python3.4/_compat_pickle.py
_dummy_thread                  | /usr/lib/python3.4/_dummy_thread.py
_markupbase                    | /usr/lib/python3.4/_markupbase.py
_osx_support                   | /usr/lib/python3.4/_osx_support.py
_pyio                          | /usr/lib/python3.4/_pyio.py
(****************************truncated*******************************)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
44: <class '_frozen_importlib.ExtensionFileLoader'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_bz2                           | /usr/lib/python3.4/lib-dynload/_bz2.cpython-34m-x86_64-linux-gnu.so
_codecs_cn                     | /usr/lib/python3.4/lib-dynload/_codecs_cn.cpython-34m-x86_64-linux-gnu.so
_codecs_hk                     | /usr/lib/python3.4/lib-dynload/_codecs_hk.cpython-34m-x86_64-linux-gnu.so
_codecs_iso2022                | /usr/lib/python3.4/lib-dynload/_codecs_iso2022.cpython-34m-x86_64-linux-gnu.so
_codecs_jp                     | /usr/lib/python3.4/lib-dynload/_codecs_jp.cpython-34m-x86_64-linux-gnu.so
_codecs_kr                     | /usr/lib/python3.4/lib-dynload/_codecs_kr.cpython-34m-x86_64-linux-gnu.so
_codecs_tw                     | /usr/lib/python3.4/lib-dynload/_codecs_tw.cpython-34m-x86_64-linux-gnu.so
_crypt                         | /usr/lib/python3.4/lib-dynload/_crypt.cpython-34m-x86_64-linux-gnu.so
(****************************truncated*******************************)
Community
  • 1
  • 1
PADYMKO
  • 3,291
  • 2
  • 31
  • 36
  • Can you please compare your approach to Adam's approach here http://stackoverflow.com/a/23885252/54964 – Léo Léopold Hertz 준영 Mar 08 '17 at 16:03
  • @Léo Léopold Hertz, why are you need it? – PADYMKO Mar 08 '17 at 16:39
  • To understand how your approach is better/worser than Adam's approach. – Léo Léopold Hertz 준영 Mar 08 '17 at 20:40
  • 1
    @Léo Léopold Hertz. A short answer: try it yourself in a production and draw conclusions yourself. Long answer: the Adam's approach is based on the `pip` - package management system used to install and manage software packages written in Python and a result `pip.get_installed_distributions()` returns modules installed with the pip. My answer entirely based on the Python`s standard library and cover all modules available for import. A biggest drawback my answer - no a support for the the CPython 2. – PADYMKO Mar 09 '17 at 13:16
  • 1
    @Léo Léopold Hertz you are mistaken, it does it. I tested it on my computer. My answer contains special meaning `**truncated**`, where a output is truncated. Maybe you not careful, but if it does not it, so to send me an information about your system and the Python implementation, I will make addition research for fix it. – PADYMKO Mar 09 '17 at 13:29
  • Excellent, this should be in PyPI! – kyrill May 21 '20 at 19:11
9

Warning: Adam Matan discourages this use in pip > 10.0. Also, read @sinoroc's comment below

This was inspired by Adam Matan's answer (the accepted one):

import tabulate
try:
  from pip import get_installed_distributions
except:
  from pip._internal.utils.misc import get_installed_distributions

tabpackages = []
for _, package in sorted([('%s %s' % (i.location, i.key), i) for i in get_installed_distributions()]):
  tabpackages.append([package.location, package.key, package.version])

print(tabulate.tabulate(tabpackages))

which then prints out a table in the form of

19:33 pi@rpi-v3 [iot-wifi-2] ~/python$ python installed_packages.py
-------------------------------------------  --------------  ------
/home/pi/.local/lib/python2.7/site-packages  enum-compat     0.0.2
/home/pi/.local/lib/python2.7/site-packages  enum34          1.1.6
/home/pi/.local/lib/python2.7/site-packages  pexpect         4.2.1
/home/pi/.local/lib/python2.7/site-packages  ptyprocess      0.5.2
/home/pi/.local/lib/python2.7/site-packages  pygatt          3.2.0
/home/pi/.local/lib/python2.7/site-packages  pyserial        3.4
/usr/local/lib/python2.7/dist-packages       bluepy          1.1.1
/usr/local/lib/python2.7/dist-packages       click           6.7
/usr/local/lib/python2.7/dist-packages       click-datetime  0.2
/usr/local/lib/python2.7/dist-packages       construct       2.8.21
/usr/local/lib/python2.7/dist-packages       pyaudio         0.2.11
/usr/local/lib/python2.7/dist-packages       tabulate        0.8.2
-------------------------------------------  --------------  ------

which lets you then easily discern which packages you installed with and without sudo.


A note aside: I've noticed that when I install a packet once via sudo and once without, one takes precedence so that the other one isn't being listed (only one location is shown). I believe that only the one in the local directory is then listed. This could be improved.

Daniel F
  • 11,845
  • 6
  • 75
  • 100
  • 2
    No. This is not recommended, see here: https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program – sinoroc Dec 12 '19 at 14:20
  • 1
    @sinoroc Thank you for pointing this out. Points 1 to 3 don't seem to be applicable to this solution, as this script has the sole purpose of using `pip` once and then exiting. It appears to be more of a problem that the behavior could change. – Daniel F Dec 12 '19 at 15:51
  • Agreed, the reasons why there is no public API do not apply to this particular piece of code. But since pip is not bound to guarantee a public API it is free to change its internal APIs, code structure, etc. in a later release, like it already did before. This is why this code has a try/except, to catch the previous internal code reorganization that was meant to clarify that internal APIs are internal APIs not public ones (`_internal`). All in all, it obviously works but is bad practice. There are better alternatives, some are in the other answers to this question. – sinoroc Dec 12 '19 at 16:12
  • 1
    this script wont work if the "pip" module is not there. – Alexander Stohr Jan 24 '20 at 16:59
8

Aside from using pip freeze I have been installing yolk in my virtual environments.

Tomasz Jakub Rup
  • 9,464
  • 7
  • 44
  • 47
jdsantiagojr
  • 456
  • 7
  • 10
7

In case you have an anaconda python distribution installed, you could also use

$conda list

in addition to solutions described above.

Shreyas
  • 337
  • 3
  • 9
6
  1. to get all available modules, run sys.modules
  2. to get all installed modules (read: installed by pip), you may look at pip.get_installed_distributions()

For the second purpose, example code:

import pip
for package in pip.get_installed_distributions():
    name = package.project_name # SQLAlchemy, Django, Flask-OAuthlib
    key = package.key # sqlalchemy, django, flask-oauthlib
    module_name = package._get_metadata("top_level.txt") # sqlalchemy, django, flask_oauthlib
    location = package.location # virtualenv lib directory etc.
    version = package.version # version number
yegle
  • 5,565
  • 6
  • 35
  • 59
  • The command **sys.modules** does not work in the newest OSX's Python. **NameError: name 'system' is not defined**. – Léo Léopold Hertz 준영 Jan 21 '14 at 09:17
  • @Masi Did you mean `/usr/bin/python` or the one come from http://python.org ? For the former one, I can use `sys.modules` without a problem. – yegle Jan 21 '14 at 15:38
  • I mean **/usr/bin/python**. – Léo Léopold Hertz 준영 Jan 21 '14 at 19:21
  • @Masi Not sure if you are still interested in this problem. Apparently you are using `system.modules` instead of `sys.modules`. – yegle Sep 03 '14 at 17:51
  • Lol. My mistake was that I did not originally import sys -package. So running instead **import sys; sys.modules** work as expected. – Léo Léopold Hertz 준영 Sep 03 '14 at 18:10
  • No. This is not recommended, see here: https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program – sinoroc Dec 12 '19 at 14:22
  • Note the answer was from 2014 and thus is outdated. @sinoroc could you add an answer with your comment? I will upvote yours instead. Not sure how I should deal with the existing answer... – yegle Mar 30 '20 at 20:47
  • @yegle Thanks for coming back on this. I am wondering how to deal with outdated answers as well. In many cases voting them down is far from enough, they still either have too many votes or are the accepted one. Maybe add a prominent "**OUTDATED**" note right at the beginning (better than deleting, since maybe the user would lose their points, and since it might still have some "_historical_" value). I wouldn't add another answer of mine since there are too many high-voted answers already, but I would maybe recommend this one: https://stackoverflow.com/a/50013400/11138259 – sinoroc Mar 30 '20 at 20:58
5

There are many way to skin a cat.

  • The most simple way is to use the pydoc function directly from the shell with:
    pydoc modules

  • But for more information use the tool called pip-date that also tell you the installation dates.
    pip install pip-date


enter image description here

not2qubit
  • 10,014
  • 4
  • 72
  • 101
4

pip freeze does it all finding packages however one can simply write the following command to list all paths where python packages are.

>>> import site; site.getsitepackages()
['/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']
Pavan Gupta
  • 12,493
  • 4
  • 16
  • 27
3

There are many ideas, initially I am pondering on these two:

pip

cons: not always installed

help('modules')

cons: output to console; with broken modules (see ubuntu...) can segfault

I need an easy approach, using basic libraries and compatible with old python 2.x

And I see the light: listmodules.py

Hidden in the documentation source directory in 2.5 is a small script that lists all available modules for a Python installation.

Pros:

uses only imp, sys, os, re, time

designed to run on Python 1.5.2 and newer

the source code is really compact, so you can easy tinkering with it, for example to pass an exception list of buggy modules (don't try to import them)

Community
  • 1
  • 1
Massimo
  • 2,114
  • 2
  • 24
  • 35
3

I needed to find the specific version of packages available by default in AWS Lambda. I did so with a mashup of ideas from this page. I'm sharing it for posterity.

import pkgutil

__version__ = '0.1.1'

def get_ver(name):
    try:
        return str(__import__(name).__version__)
    except:
        return None

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': [{
                   'path': m.module_finder.path,
                   'name': m.name,
                   'version': get_ver(m.name),
                 } for m in list(pkgutil.iter_modules())
                 #if m.module_finder.path == "/var/runtime" # Uncomment this if you only care about a certain path
                ],
    }

What I discovered is that the provided boto3 library was way out of date and it wasn't my fault that my code was failing. I just needed to add boto3 and botocore to my project. But without this I would have been banging my head thinking my code was bad.

{
  "statusCode": 200,
  "body": [
    {
      "path": "/var/task",
      "name": "lambda_function",
      "version": "0.1.1"
    },
    {
      "path": "/var/runtime",
      "name": "bootstrap",
      "version": null
    },
    {
      "path": "/var/runtime",
      "name": "boto3",
      "version": "1.9.42"
    },
    {
      "path": "/var/runtime",
      "name": "botocore",
      "version": "1.12.42"
    },
    {
      "path": "/var/runtime",
      "name": "dateutil",
      "version": "2.7.5"
    },
    {
      "path": "/var/runtime",
      "name": "docutils",
      "version": "0.14"
    },
    {
      "path": "/var/runtime",
      "name": "jmespath",
      "version": "0.9.3"
    },
    {
      "path": "/var/runtime",
      "name": "lambda_runtime_client",
      "version": null
    },
    {
      "path": "/var/runtime",
      "name": "lambda_runtime_exception",
      "version": null
    },
    {
      "path": "/var/runtime",
      "name": "lambda_runtime_marshaller",
      "version": null
    },
    {
      "path": "/var/runtime",
      "name": "s3transfer",
      "version": "0.1.13"
    },
    {
      "path": "/var/runtime",
      "name": "six",
      "version": "1.11.0"
    },
    {
      "path": "/var/runtime",
      "name": "test_bootstrap",
      "version": null
    },
    {
      "path": "/var/runtime",
      "name": "test_lambda_runtime_client",
      "version": null
    },
    {
      "path": "/var/runtime",
      "name": "test_lambda_runtime_marshaller",
      "version": null
    },
    {
      "path": "/var/runtime",
      "name": "urllib3",
      "version": "1.24.1"
    },
    {
      "path": "/var/lang/lib/python3.7",
      "name": "__future__",
      "version": null
    },
...

What I discovered was also different from what they officially publish. At the time of writing this:

  • Operating system – Amazon Linux
  • AMI – amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2
  • Linux kernel – 4.14.77-70.59.amzn1.x86_64
  • AWS SDK for JavaScript – 2.290.0\
  • SDK for Python (Boto 3) – 3-1.7.74 botocore-1.10.74
Bruno Bronosky
  • 54,357
  • 9
  • 132
  • 120
2

Here is a python code solution that will return a list of modules installed. One can easily modify the code to include version numbers.

import subprocess
import sys
from pprint import pprint

installed_packages = reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze']).decode('utf-8')
installed_packages = installed_packages.split('\r\n')
installed_packages = [pkg.split('==')[0] for pkg in installed_packages if pkg != '']
pprint(installed_packages)
Eli
  • 979
  • 8
  • 19
1

Installation

pip install pkgutil

Code

import pkgutil

for i in pkgutil.iter_modules(None): # returns a tuple (path, package_name, ispkg_flag)
    print(i[1]) #or you can append it to a list

Sample Output:

multiprocessing
netrc
nntplib
ntpath
nturl2path
numbers
opcode
pickle
pickletools
pipes
pkgutil
Sachin Prabhu
  • 122
  • 1
  • 8
1
pip install pip-chill 
pip-chill
dbc
  • 80,875
  • 15
  • 141
  • 235
Santle Camilus
  • 777
  • 1
  • 11
  • 19
0

If none of the above seem to help, in my environment was broken from a system upgrade and I could not upgrade pip. While it won't give you an accurate list you can get an idea of which libraries were installed simply by looking inside your env>lib>python(version here)>site-packages> . Here you will get a good indication of modules installed.

Josh
  • 1,132
  • 15
  • 20
-2

For anyone wondering how to call pip list from a Python program you can use the following:

import pip
pip.main(['list])  # this will print all the packages
  • 1
    No. This is not recommended, see here: https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program – sinoroc Dec 12 '19 at 14:19
-10

From the shell

ls site-packages

If that's not helpful, you can do this.

import sys
import os
for p in sys.path:
    print os.listdir( p )

And see what that produces.

S.Lott
  • 359,791
  • 75
  • 487
  • 757
  • which site-packages directory? This might do better: ls /usr/{local/,}lib/python$(python -V 2>&1|cut -d" " -f2 |cut -d. -f1-2)/site-packages – vezult Apr 11 '09 at 13:04
  • Also this will not show built-in modules, or modules in a custom PYTHONPATH, or ones installed in setuptools "development mode" etc. – dF. Apr 11 '09 at 13:06
  • My /usr/local/lib/python2.5/site-packages is empty, although I have installed modules. – Léo Léopold Hertz 준영 Apr 11 '09 at 13:08
  • @dF: While true, I don't see how any of those alternatives are relevant to the question. – S.Lott Apr 11 '09 at 18:37
  • @Masi: Interesting. You'll have to look at sys.path to see all the places they might have been put. – S.Lott Apr 11 '09 at 18:37
  • 15
    Kudos for not deleting this downvoted answer. It's helpful to the community to be able to see why a common answer is considered wrong. – Jeremy Stein Oct 18 '12 at 13:09
  • 2
    @JeremyStein A better strategy (more helpful and probably less rep-damaging) would probably be to edit the question to explain why it's wrong, once this has been explained in the comments... – Kyle Strand Dec 03 '14 at 18:32