Rex Hardin
Rex Hardin

Reputation: 2189

How to retrieve pip requirements (freeze) within Python?

I posted this question on the git issue tracker: https://github.com/pypa/pip/issues/2969

Can we have some manner of calling pip freeze/list within python, i.e. not a shell context?

I want to be able to import pip and do something like requirements = pip.freeze(). Calling pip.main(['freeze']) writes to stdout, doesn't return str values.

Upvotes: 35

Views: 18081

Answers (6)

Primoz
Primoz

Reputation: 1492

Since it is not recommended to rely on a private function such as pip._internal.operatons and also pkg_resources suggested as an alternative is now deprecated, I suggest using importlib.metadata instead.

from importlib import metadata

dists = metadata.distributions()
for dist in dists:
    name = dist.metadata["Name"]
    version = dist.version
    print(name, version)

Upvotes: 4

Joe Jacobs
Joe Jacobs

Reputation: 361

To build off of sedeh and Marvin's answers above, I found an as_requirements() method, so this worked for me to get the almost equivalent of pip freeze.

excluded_packages = ['wheel', 'setuptools', 'pip']
modules = [str(p.as_requirement()) for p in pkg_resources.working_set if p and p.key not in excluded_packages]

The only other issue I had was 'typing-extensions' vs 'typing_extensions'. Both seem to pip install so doesn't appear to be a big issue.

Upvotes: 0

Rex Hardin
Rex Hardin

Reputation: 2189

There's a pip.operation.freeze in newer releases (>1.x):

try: from pip._internal.operations import freeze
except ImportError: # pip < 10.0
    from pip.operations import freeze

pkgs = freeze.freeze()
for pkg in pkgs: print(pkg)

Output is, as expected:

amqp==1.4.6
anyjson==0.3.3
billiard==3.3.0.20
defusedxml==0.4.1
Django==1.8.1
django-picklefield==0.3.1
docutils==0.12
... etc

Upvotes: 61

sedeh
sedeh

Reputation: 7313

It's not recommended to rely on a "private" function such as pip._internal.operatons. You can do the following instead:

import pkg_resources
env = dict(tuple(str(ws).split()) for ws in pkg_resources.working_set)

Upvotes: 10

Zak
Zak

Reputation: 982

The other answers here are unsupported by pip: https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program

According to pip developers:

If you're directly importing pip's internals and using them, that isn't a supported usecase.

try

reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])

Upvotes: 15

ankostis
ankostis

Reputation: 9473

Actually from pip >= 10.0.0 package operations.freeze has moved to pip._internal.operations.freeze.

So the safe way to import freeze is:

try:
    from pip._internal.operations import freeze
except ImportError:
    from pip.operations import freeze

Upvotes: 2

Related Questions