Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Subprocess – pip: pass package names dynamically

I am trying to download without installation some Python packages using pip with the shell command

$ python -m pip download --destination-directory path -r requirements.txt

What I’d like to do is to bypass the step of having a file, requirements.txt, which contains the list of packages to download and just pass the package names as parameters.
Here my attempt

import sys
import subprocess
from tempfile import NamedTemporaryFile


PIP = (sys.executable, '-m', 'pip')


def download(to_dir, *pkgs):
    with NamedTemporaryFile(mode="w+", suffix=".txt") as tmp:
        tmp.write('\n'.join(pkgs))
        
        # debugging info
        tmp.seek(0)
        print(tmp.read(), tmp.name)
        tmp.seek(0)

        return PIP + ('download', '--destination-directory', to_dir, '-r', tmp.name) 


pkg = "sphinx"        # example of package
to_dir = "valid path" # download directory

cmd = download(to_dir, pkg)
print(cmd)
p = subprocess.call(cmd)
print(p)

which raises the error

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

sphinx
/tmp/tmpmg3inbtu.txt
('path to python3.11', '-m', 'pip', 'download', '--destination-directory', 'valid path', '-r', '/tmp/tmpmg3inbtu.txt')
ERROR: Could not open requirements file: [Errno 2] No such file or directory: '/tmp/tmpmg3inbtu.txt'

>Solution :

The temporary file is deleted immediately when the function download() returns (actually when with is ended). To prevent:

    with NamedTemporaryFile(mode="w+", suffix=".txt", delete=False) as tmp:

But don’t forget to delete the file yourself using os.unlink(). See https://docs.python.org/3/library/tempfile.html#tempfile.NamedTemporaryFile

Another approach is to subprocess.call(cmd) inside with.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading