6

I'm trying to generate a requirements.txt file programatically. This way I can diff it against a second .txt file. So far I've tried the following, but they only output the requirements to console (No .txt file is generated).

So far I've tried

    import pip

    pip.main(["freeze",">","requirements.txt"])

and

    from subprocess import call

    call(["pip","freeze", ">","requirements.txt"])

If I attempt to run the same command manually in terminal though, the file is generated without issue. Any suggestions?

4 Answers 4

8

Ask pip to directly provide the list of distributions

Script myfreeze.py

import pip
with open("requirements.txt", "w") as f:
    for dist in pip.get_installed_distributions():
        req = dist.as_requirement()
        f.write(str(req) + "\n")

Then you get expected content in your requirements.txt file.

Sign up to request clarification or add additional context in comments.

Comments

4
subprocess.Popen(['pip', 'freeze'], stdout=open('/tmp/pip.log', 'w'))

Comments

3

Using pip for this is strongly discouraged by the developers of pip. It is also broken in more recent versions of pip. Here is a summary of the approach suggested on the linked Github issue. Very similar to the accepted answer but using the pkg_resources module instead.

import pkg_resources


def generate_pip_freeze() -> str:
    requirements = ""
    for dist in pkg_resources.working_set:
        req = dist.as_requirement()
        requirements += f"{req}\n"
    return requirements

or more succintly:

def generate_pip_freeze() -> str:
    return "\n".join(
        str(dist.as_requirement()) for dist in pkg_resources.working_set
    )

Comments

2

Now that pkg_resources is deprecated, you should do this with importlib.metadata (or importlib_metadata, its backport to earlier Python versions)

from importlib.metadata import packages_distributions, version
  
installed = {pkg for pkgs in packages_distributions().values() for pkg in pkgs}
req_str ="\n".join(f"{pkg}=='{version(pkg)}'" for pkg in installed)

with open("requirements.txt", "w") as f:
        f.write(req_str)

1 Comment

the single quotes around the version aren't accepted by pip if used with pip install -r requirements.txt, they should be removed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.