How to check if python package is latest version programmatically?

后端 未结 7 1696
南旧
南旧 2020-12-18 18:42

How do you check if a package is at its latest version programmatically in a script and return a true or false?

I can check with a script like this:



        
7条回答
  •  攒了一身酷
    2020-12-18 18:56

    Edit: Remove pip search

    Thanks for the several suggestions. Here is a new version that doesn't use pip search but instead pulls the latest version directly from pypi as proposed by Daniel Hill. This also resolves the issue with the substring false matches.

    def check(name):
        import subprocess
        import sys
        import json
        import urllib.request
    
        # create dictionary of package versions
        pkgs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
        keys = [p.decode().split('==')[0] for p in pkgs.split()]
        values = [p.decode().split('==')[1] for p in pkgs.split()]
        d = dict(zip(keys, values)) # dictionary of all package versions
    
        # retrieve info on latest version
        contents = urllib.request.urlopen('https://pypi.org/pypi/'+name+'/json').read()
        data = json.loads(contents)
        latest_version = data['info']['version']
    
        if d[name]==latest_version:
            print('Latest version (' + d[name] + ') of '+str(name)+' is installed')
            return True
        else:
            print('Version ' + d[name] + ' of '+str(name)+' not the latest '+latest_version)
            return False
    
    print(check('gekko'))
    

    Original Response

    Here is a fast solution that retrieves latest version information on only the gekko package of interest.

    def check(name):
        import subprocess
        import sys
        # create dictionary of package versions
        pkgs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
        keys = [p.decode().split('==')[0] for p in pkgs.split()]
        values = [p.decode().split('==')[1] for p in pkgs.split()]
        d = dict(zip(keys, values)) # dictionary of all package versions
    
        # retrieve info on latest version
        s = subprocess.check_output([sys.executable, '-m', 'pip', 'search', name])
    
        if d[name] in s.decode():  # weakness
            print('Latest version (' + d[name] + ') of '+str(name)+' is installed')
            return True
        else:
            print(s.decode())
            return False
    
    print(check('gekko'))
    

    This produces the message Latest version (0.2.3) of gekko is installed and returns True to indicate latest version (or False if not the latest version). This may not be the best solution because it only checks for a version substring with if d[name] in s.decode(): but it is faster than pip list --outdated that checks all the packages. This isn't the most reliable method because it will return an incorrect True if current installed version is 0.2.3 but latest version is 0.2.30 or 0.2.3a. An improvement would be to programmatically get the latest version and do a direct comparison.

提交回复
热议问题