Without going through with the installation, I want to quickly see all the packages that pip install
would install.

- 21,378
- 10
- 65
- 88

- 3,955
- 5
- 26
- 25
-
1Related: http://stackoverflow.com/q/9232568/183791 – dusan Jun 21 '12 at 22:41
-
Another question including alternative answers for this problem: https://stackoverflow.com/questions/41816693/how-to-list-dependencies-for-a-python-library-without-installing – pgmank Sep 28 '19 at 14:43
11 Answers
Check out my project johnnydep!
Installation:
pip install johnnydep
Usage example:
$ johnnydep requests
name summary
------------------------- ----------------------------------------------------------------------
requests Python HTTP for Humans.
├── certifi>=2017.4.17 Python package for providing Mozilla's CA Bundle.
├── chardet<3.1.0,>=3.0.2 Universal encoding detector for Python 2 and 3
├── idna<2.7,>=2.5 Internationalized Domain Names in Applications (IDNA)
└── urllib3<1.23,>=1.21.1 HTTP library with thread-safe connection pooling, file post, and more.
A more complex tree:
$ johnnydep ipython
name summary
-------------------------------- -----------------------------------------------------------------------------
ipython IPython: Productive Interactive Computing
├── appnope Disable App Nap on OS X 10.9
├── decorator Better living through Python with decorators
├── jedi>=0.10 An autocompletion tool for Python that can be used for text editors.
│ └── parso==0.1.1 A Python Parser
├── pexpect Pexpect allows easy control of interactive console applications.
│ └── ptyprocess>=0.5 Run a subprocess in a pseudo terminal
├── pickleshare Tiny 'shelve'-like database with concurrency support
├── prompt-toolkit<2.0.0,>=1.0.4 Library for building powerful interactive command lines in Python
│ ├── six>=1.9.0 Python 2 and 3 compatibility utilities
│ └── wcwidth Measures number of Terminal column cells of wide-character codes
├── pygments Pygments is a syntax highlighting package written in Python.
├── setuptools>=18.5 Easily download, build, install, upgrade, and uninstall Python packages
├── simplegeneric>0.8 Simple generic functions (similar to Python's own len(), pickle.dump(), etc.)
└── traitlets>=4.2 Traitlets Python config system
├── decorator Better living through Python with decorators
├── ipython-genutils Vestigial utilities from IPython
└── six Python 2 and 3 compatibility utilities

- 338,267
- 99
- 616
- 750
-
I downloaded this and use it, it's a great package. BUT doesn't it require packages to be installed? The OP is specifically requesting an approach that doesn't require installation. Important to caveat. – so860 Aug 06 '19 at 16:28
-
8@so860 No, it does not require the packages to be installed. That's the whole point, it works in an isolated environment. – wim Aug 06 '19 at 16:37
-
4
-
3
-
1This seems like a nice package, but it *does* seem to install the packages. In a separate env, sure, but it still has to actually install the packages there, which is very slow when there are a lot of packages, and it fails if the installation of a package fails. So I do not think it fulfils the OP requirement to see the dependencies without going through the installation process. – Ben Farmer Dec 22 '20 at 01:31
-
4@BenFarmer That's incorrect. It doesn't install packages, it reads the metadata from [wheel](https://www.python.org/dev/peps/pep-0427/) files, which does require a package download- but not an installation. In the rare case that a project has published a source distribution but no compatible wheel is available, then pip will attempt to generate a wheel from the sdist (that is [the only reliable way to get package metadata](https://discuss.python.org/t/sdist-idea-specifying-static-metadata-that-can-be-trusted/4703/12) from sdist). In the most common case, there is no installation process. – wim Dec 22 '20 at 02:03
-
It is a slow process for large dep trees, unfortunately, because the PyPI json APIs don't provide the necessary information to do this without a package download. That's not something specific to johnnydep though, poetry and other projects all have the same slowness due to the package download requirements. – wim Dec 22 '20 at 02:09
-
Ah my mistake, I just saw output about setup.py, and "Failed to build scipy, Cleaning up..." and assumed it was doing an install. It's a bit absurd that this is so hard in Python. Or I guess pip. I guess maybe conda can do it more easily, if you only need to use that. – Ben Farmer Dec 22 '20 at 03:28
-
-
3@GPHemsley .. and it has quite some dependencies, see `pip show`: `Requires: structlog, wheel, setuptools, wimpy, cachetools, anytree, distlib, tabulate, colorama, pip, packaging, toml, pkginfo, oyaml` – Timo Jul 03 '21 at 05:48
This was tested with pip versions 8.1.2, 9.0.1, 10.0.1, and 18.1.
To get the output without cluttering your current directory on Linux use
pip download [package] -d /tmp --no-binary :all: -v
-d
tells pip the directory that download should put files in.
Better, just use this script with the argument being the package name to get only the dependencies as output:
#!/bin/sh
PACKAGE=$1
pip download $PACKAGE -d /tmp --no-binary :all:-v 2>&1 \
| grep Collecting \
| cut -d' ' -f2 \
| grep -Ev "$PACKAGE(~|=|\!|>|<|$)"
Also available here.
-
A very (*very*) crude reading of `requirements.txt` using this: `< requirements.txt egrep -v "^#" | egrep -v "^$" | xargs -L 1 -I % sh -c 'echo %; echo "======"; ./deps.sh %; echo "";` – Ian Clark Jun 11 '18 at 10:25
-
@hans-musgrave made a good point in another answer that I hadn't noticed previously, so updated the bash script to only exclude lines that match the package along with end of line or the start of a valid [version specifier](https://www.python.org/dev/peps/pep-0440/#version-specifiers) rather than any line that contains the package name. – Jmills Jun 25 '18 at 22:41
-
5Some packages *only* provide binary, so `--no-binary :all:` is not a good idea. A project which only shipped wheel and not sdist would fail. – wim Apr 19 '19 at 18:17
-
7This end up download and compile for all the dependence packages which can be very slow.... – Louis Yang Sep 04 '19 at 20:36
-
For those wanting a quick one-liner, here's an example for pandas, with files being stored in `~/pip-tmp`: `pip download pandas -d ~/pip-tmp -v 2>&1 | grep "Collecting"`. This gives you a quick overview of what the requirements are. Obviously you'd then want to delete the files from the `~/pip-tmp` directory. Also I guess it could take a while if there are a plethora of requirements. – jenniwren Jan 06 '20 at 23:42
-
1Since recent versions of pip can be using PEP 517 / PEP 518, this may also start to turn up false positives because of the build-system requirements. Unreliable. – wim Jan 29 '20 at 20:56
-
2Note that this does not list dependencies that are already installed (which is fine for OP). – GPHemsley May 01 '20 at 08:31
-
1What if I want to do this for a local package I am working on? e.g. that I would install with "pip install -e ./mypackage"? Sometimes I just want to know what the full dependency tree is for a project that I am working on. – Ben Farmer Dec 22 '20 at 03:37
If and only if the package is installed, you can use pip show <package>
. Look for the Requires:
field at the end of the output. Clearly, this breaks your requirement but might be useful nonetheless.
For example:
$ pip --version
pip 7.1.0 [...]
$ pip show pytest
---
Metadata-Version: 2.0
Name: pytest
Version: 2.7.2
Summary: pytest: simple powerful testing with Python
Home-page: http://pytest.org
Author: Holger Krekel, Benjamin Peterson, Ronny Pfannschmidt, Floris Bruynooghe and others
Author-email: holger at merlinux.eu
License: MIT license
Location: /home/usr/.tox/develop/lib/python2.7/site-packages
Requires: py

- 17,645
- 4
- 15
- 38

- 17,269
- 27
- 101
- 156
-
3This only shows the direct requirements, all the transitive dependencies would be missing. And it requires an installation. So, it doesn't really answer the question. – wim Jun 18 '19 at 13:58
Note: the feature used in this answer was deprecated in 2014 and removed in 2015. Please see other answers that apply to modern
pip
.
The closest you can get with pip directly is by using the --no-install
argument:
pip install --no-install <package>
For example, this is the output when installing celery:
Downloading/unpacking celery
Downloading celery-2.5.5.tar.gz (945Kb): 945Kb downloaded
Running setup.py egg_info for package celery
no previously-included directories found matching 'tests/*.pyc'
no previously-included directories found matching 'docs/*.pyc'
no previously-included directories found matching 'contrib/*.pyc'
no previously-included directories found matching 'celery/*.pyc'
no previously-included directories found matching 'examples/*.pyc'
no previously-included directories found matching 'bin/*.pyc'
no previously-included directories found matching 'docs/.build'
no previously-included directories found matching 'docs/graffles'
no previously-included directories found matching '.tox/*'
Downloading/unpacking anyjson>=0.3.1 (from celery)
Downloading anyjson-0.3.3.tar.gz
Running setup.py egg_info for package anyjson
Downloading/unpacking kombu>=2.1.8,<2.2.0 (from celery)
Downloading kombu-2.1.8.tar.gz (273Kb): 273Kb downloaded
Running setup.py egg_info for package kombu
Downloading/unpacking python-dateutil>=1.5,<2.0 (from celery)
Downloading python-dateutil-1.5.tar.gz (233Kb): 233Kb downloaded
Running setup.py egg_info for package python-dateutil
Downloading/unpacking amqplib>=1.0 (from kombu>=2.1.8,<2.2.0->celery)
Downloading amqplib-1.0.2.tgz (58Kb): 58Kb downloaded
Running setup.py egg_info for package amqplib
Successfully downloaded celery anyjson kombu python-dateutil amqplib
Admittedly, this does leave some cruft around in the form of temporary files, but it does accomplish the goal. If you're doing this with virtualenv (which you should be), the cleanup is as easy as removing the <virtualenv root>/build
directory.

- 33,737
- 11
- 83
- 111

- 755
- 4
- 8
-
8The reason for this is that the metadata doesn't exist outside of setup.py so unlike say with `rpm` or `dpkg` where you build a metadata index on top and query that `pip` and `pypi` don't work that way. So we have to pass over each requirement. – Jun 22 '12 at 15:40
-
-
12I tried `pip --no-install celery` but I receive the error `no such option: --no-install` (pip 1.2.1) – Colonel Panic Dec 13 '12 at 20:35
-
4
-
23
-
4
-
pip now displays a warning deprecating --download and --no-use-wheel as well. – Alison S Apr 27 '16 at 14:55
-
3Pip now says to use `pip download
`. They sure are deprecation happy! – Merlyn Morgan-Graham May 09 '16 at 00:54 -
`pip download
` technically works, but has the obvious disadvantage of polluting the current working directory with package cruft. See [The Card Cheat](https://stackoverflow.com/users/1210112/the-card-cheat)'s [one-liner and related shell script](https://stackoverflow.com/a/38531949/2809027) for clever alternatives. – Cecil Curry Aug 09 '16 at 05:01 -
-
3I'm glad a command ridiculous sounding as "pip install --no-install" was deprecated .. :) – wim Mar 07 '18 at 02:08
I quote an alternative solution from @onnovalkering:
PyPi provides a JSON endpoint with package metadata:
>>> import requests >>> url = 'https://pypi.org/pypi/{}/json' >>> json = requests.get(url.format('pandas')).json() >>> json['info']['requires_dist'] ['numpy (>=1.9.0)', 'pytz (>=2011k)', 'python-dateutil (>=2.5.0)'] >>> json['info']['requires_python'] '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*'
For a specific package version, add an additional version segment to the URL:
https://pypi.org/pypi/pandas/0.22.0/json
Also if you are using conda (as suggested by @ShpielMeister), you can use:
conda info package==X.X.X
to display information, including dependencies for a particular version or:
conda info package
to display information, including dependencies about all supported versions of that package.

- 5,303
- 5
- 36
- 52
-
2I downvoted because this json endpoint is not reliable. For an example look at [`boto3`](https://pypi.org/pypi/boto3/json), the requires_dist is null but that is a project which [certainly has dependencies in the metadata](https://github.com/boto/boto3/blob/develop/setup.py#L16-L20). – wim Dec 18 '19 at 03:07
-
1The example for boto3 contains the required packages (`curl -L 'https://pypi.python.org/pypi/boto3/json' | jq '.info.requires_dist'`). So I am not sure if the critique is still valid. – p13rr0m Jul 27 '22 at 08:40
Use pipdeptree ( pip install pipdeptree
). Needs the package to be installed.
$ pipdeptree -p pandas
pandas==1.2.2
- numpy [required: >=1.16.5, installed: 1.19.5]
- python-dateutil [required: >=2.7.3, installed: 2.8.1]
- six [required: >=1.5, installed: 1.15.0]
- pytz [required: >=2017.3, installed: 2021.1]
Use johnnydep (pip install johnnydep
). Slower because it download the wheels of the packages.
$ johnnydep pandas
2021-06-09 11:01:21 [info ] init johnnydist [johnnydep.lib] dist=pandas parent=None
2021-06-09 11:01:22 [info ] init johnnydist [johnnydep.lib] dist=numpy>=1.16.5 parent=pandas
2021-06-09 11:01:22 [info ] init johnnydist [johnnydep.lib] dist=python-dateutil>=2.7.3 parent=pandas
2021-06-09 11:01:23 [info ] init johnnydist [johnnydep.lib] dist=pytz>=2017.3 parent=pandas
2021-06-09 11:01:23 [info ] init johnnydist [johnnydep.lib] dist=six>=1.5 parent=python-dateutil>=2.7.3
name summary
-------------------------- -----------------------------------------------------------------------
pandas Powerful data structures for data analysis, time series, and statistics
├── numpy>=1.16.5 NumPy is the fundamental package for array computing with Python.
├── python-dateutil>=2.7.3 Extensions to the standard Python datetime module
│ └── six>=1.5 Python 2 and 3 compatibility utilities
└── pytz>=2017.3 World timezone definitions, modern and historical

- 874
- 1
- 8
- 17
Just an addendum on how to use johnnydep
.
- If you want to have the dependencies in requirements.txt format:
johnnydep pandas --output-format=pinned
pandas==1.4.1
numpy==1.22.3
python-dateutil==2.8.2
pytz==2021.3
six==1.16.0
Above list will be written to stdout
while the informational messages during collection are written to stderr
(if you want to capture the output using bash or subprocess).
- Calling it from Python instead of the CLI:
import sys, johnnydep.cli
sys.argv = ["", "pandas"]
johnnydep.cli.main()

- 12,848
- 6
- 67
- 89
-
Thanks for pointing that out. I was having troubles with appending the standard "human" format to a file because of character conversions. Your solution worked though – RexBarker Jul 14 '22 at 13:08
I think these answers are outdated and there's a better solution now. Original post here:
To generate requirements.txt
for packages listed in install_requires
in your setup.cfg
or setup.py
, you would need to install pip-tools
.
pip install pip-tools
pip-compile
To generate a requirements.txt
file that includes packages specified under extras_requires
for tests
and dev
:
pip-compile --extra tests --extra devrequirements.txt file with packages listed under
Furthermore, you can also use requirements.in
file instead of setup.cfg
or setup.py
to list your requirements.
pip-compile requirements.in

- 1,435
- 2
- 18
- 34
As an update to @Jmills answer, for newer pip versions that support the --dry-run
option:
#!/bin/sh
PACKAGE=$1
pip install $PACKAGE --dry-run --ignore-installed \
| grep Collecting \
| cut -d' ' -f2 \
| sed -E 's/([><=!]=|[><]).*//g'

- 2,708
- 2
- 22
- 21
-
This works, but this still downloads the packages. I have to run `pip cache purge` afterwards. I wish `--dry-run` would not actually download packages. – Al Conrad Jun 23 '23 at 15:15
The command pip install <package> --download <path>
should be used, as mentioned in comments by @radtek, since as of 7.0.0 (2015-05-21), --no-install is removed from pip
. This will download the dependencies needed into <path>
.

- 1,946
- 18
- 24
-
12Ridiculously, **`--download` has been deprecated as well.** The canonical command _now_ appears to be `pip download
-d /tmp --no-binary :all:` as [suggested](https://stackoverflow.com/a/38531949/2809027) by [The Card Cheat](https://stackoverflow.com/users/1210112/the-card-cheat). – Cecil Curry Aug 09 '16 at 05:03
Another option is to use a helper script similar to this one which uses the pip.req.parse_requirements
API to parse requirements.txt
files and a distutils.core.setup
replacement to parse setup.py
files.

- 28,386
- 6
- 101
- 146