5

Say for example I add django to my venv with pip install django. The usual way to generate my requirements.txt file is with pip freeze > requirements.txt which produces:

asgiref==3.2.3
Django==3.0.2
pytz==2019.3
sqlparse==0.3.0

This is a lie. My only requirement is django and the (perfectly effective) requirements.txt I want is:

Django>=3.0.2, <4

There are times when this matters. With a real application I will end up with many packages that have overlapping dependencies. When upgrading this may or may not cause a problem but there will almost always be problems if I've pinned all those dependent packages I don't care about (in the example above, they are up to the django developers, not me).

In order to optimize a dependency bloated requirements.txt file I can manually inspect the source code (resulting in an empty requirements.txt above ;)) but for any real application this quickly becomes impractical.

Paul Whipp
  • 16,028
  • 4
  • 42
  • 54
  • 1
    Your setup.py/pyproject.toml should already list the immediate dependencies. The point of freezing and requirements.txt is to have a *complete* description of a working environment. – MisterMiyagi Jan 29 '20 at 06:51
  • @MisterMiyagi I agree that is the point of freezing but isn't the point of requirements.txt to list my application requirements? Say for example I intentionally pin Django to a version range in my requirements.txt. I have no interest in what Django developers do with their dependency versions within that range. In fact I can't know what versions they will move their dependencies to in that range or even what dependencies they might add and remove (I only know that their protocol for me wont change so I can rely on it). – Paul Whipp Jan 29 '20 at 07:42
  • 1
    Using ˋDjango==3.0.2ˋ doesn’t pin Django to a version range but to one clearly defined version. This one will never do anything with its secondary dependencies. – MisterMiyagi Jan 29 '20 at 08:09
  • True and although its not strictly relevant, I've edited the question to highlight the issue. – Paul Whipp Jan 29 '20 at 20:56
  • 1
    I believe this answer gives what you need: https://stackoverflow.com/a/31684470/9609843. – sanyassh Jan 29 '20 at 21:08
  • @sanyash pipreqs looks perfect but breaks with what looks like a failure to support python 3.7+ at present when I tried it on a couple of my recent projects. – Paul Whipp Jan 29 '20 at 21:22
  • @PaulWhipp it is strange. I use pipreqs for my current 3.7 project and there is no issues with it. – sanyassh Jan 30 '20 at 08:09

1 Answers1

2

pipreqs as suggested by http://stackoverflow.com/a/31684470/9609843 will be a good solution once it supports Python 3.7 and up.

Until then pipdeptree serves well for most purposes:

pipdeptree -l | grep -i '^[[:alnum:]]' > requirements.txt
Paul Whipp
  • 16,028
  • 4
  • 42
  • 54