How to find a Python package's dependencies

Solution 1:

In addition to the pip show [package name] command, there is pipdeptree.

Just do

$ pip install pipdeptree

then run

$ pipdeptree

and it will show you your dependencies in a tree form, e.g.,

flake8==2.5.0
  - mccabe [required: >=0.2.1,<0.4, installed: 0.3.1]
  - pep8 [required: !=1.6.0,>=1.5.7,!=1.6.1,!=1.6.2, installed: 1.5.7]
  - pyflakes [required: >=0.8.1,<1.1, installed: 1.0.0]
ipdb==0.8
  - ipython [required: >=0.10, installed: 1.1.0]

The project is located at https://github.com/naiquevin/pipdeptree, where you will also find usage information.

Solution 2:

Try to use show command in pip, for example:

$ pip show tornado
---
Name: tornado
Version: 4.1
Location: *****
Requires: certifi, backports.ssl-match-hostname

Update (retrieve deps with specified version):

from pip._vendor import pkg_resources


_package_name = 'somepackage'
_package = pkg_resources.working_set.by_key[_package_name]

print([str(r) for r in _package.requires()])  # retrieve deps from setup.py

Output: ['kombu>=3.0.8', 
         'billiard>=3.3.0.13', 
         'boto>=2.26']

Solution 3:

Brief summary about the methods that are found and tested on the Windows machine:

  1. Parse the json file of PyPI: https://pypi.org/pypi/<package>/<version>/json (#7)

  2. Check /site-packages/<package-version>.dist-info/METADATA (#13, pre-installation required)

  3. pip install --no-install <package>: deprecated (#11)

  4. pip install --download <package>: deprecated (#12)

  5. pip show <package> (#1, #2, pre-installation required)

  6. Write a script with import pip and pip._vendor.pkg_resources: deprecated (#6)

  7. Write a script with import pkg_resources of setuptools package (#4, pre-installation required)

  8. https://libraries.io/ (#5)

  9. Use pipdeptree package (#3, #8, pre-installation required)

  10. Use Johnnydep package (#10): Test hangs in many cases.

  11. conda info [package_name]: deprecated (#9)

  12. conda search [package_name] --info

  • Note that additional packages can be listed: vc2015_runtime, python_abi, libflang, and etc.
  • Note that this method can list different packages depending on the build and channel.
    e.g. conda search "Django==3.2" --info -c conda-forge
django 3.2 pyhd3eb1b0_0
-----------------------
file name   : django-3.2-pyhd3eb1b0_0.conda
...
timestamp   : 2021-04-06 20:19:41 UTC
dependencies:
  - asgiref
  - psycopg2
  - python
  - pytz
  - sqlparse

django 3.2 pyhd8ed1ab_0
-----------------------
file name   : django-3.2-pyhd8ed1ab_0.tar.bz2
...
timestamp   : 2021-04-07 21:15:25 UTC
dependencies:
  - asgiref >=3.3.2,<4
  - python >=3.6
  - pytz
  - sqlparse >=0.2.2

One more thing to note is that each method can provide a different result.

For example, requests/setup.py identifies chardet, idna, urllib3, and certifi are required. Moreover, extra packages pyOpenSSL, cryptography, socks, PySocks, win-inet-pton can be needed.

  • Methods 1 and 2 agree with it.
  • Method 8 just list all of them (pressing the explore dependencies button just hangs).
  • Method 12 just list chardet, idna, urllib3, and certifi.
  • Method 5 and 7 does not list any dependency if requests is installed using pip in the Linux docker.
  • Method 5, 7, 9, and 10 list chardet, idna, urllib3, and certifi if requests is installed in the conda environment of the Windows machine.

Solution 4:

Quite a few answers here show pip being imported for use in programs. The documentation for pip strongly advises against this usage of pip.

Instead of accessing pkg_resources via the pip import, you can actually just import pkg_resources directly and use the same logic (which is actually one of the suggested solutions in the pip docs linked for anyone wanting to see package meta information programmatically) .

import pkg_resources

_package_name = 'yourpackagename'
  
def get_dependencies_with_semver_string():
    package = pkg_resources.working_set.by_key[_package_name]
    return [str(r) for r in package.requires()]

If you're having some trouble finding out exactly what your package name is, the WorkingSet instance returned by pkg_resources.working_set implements __iter__ so you can print all of them and hopefully spot yours in there :)

i.e.

import pkg_resources

def print_all_in_working_set():
    ws = pkg_resources.working_set
    for package_metadata in ws:
        print(package_metadata)

This works with both python 2 and 3 (though you'll need to adjust the print statements for python2).

Solution 5:

Use https://libraries.io/. It is a good place to explore dependencies before installing using pip.

Eg. Type google-cloud-storage and search, then you can find the page for the library (https://libraries.io/rubygems/google-cloud-storage). Select the version for which you want to explore the dependencies from the 'Releases' (default is the latest), Under 'Dependencies' you can find the dependency list and their supported versions.