816

Given the name of a Python package that can be installed with pip, is there any way to find out a list of all the possible versions of it that pip could install? Right now it's trial and error.

I'm trying to install a version for a third party library, but the newest version is too new, there were backwards incompatible changes made. So I'd like to somehow have a list of all the versions that pip knows about, so that I can test them.

wim
  • 338,267
  • 99
  • 616
  • 750
Amandasaurus
  • 58,203
  • 71
  • 188
  • 248
  • 1
    The accepted answer is not equivalent to the other one with the script as they do not generate the same output. – oligofren Apr 12 '13 at 12:04
  • 31
    Please update the selected answer. Yolk is broken and unneeded. The answer with `pip install pylibmc==` is perfect. – Jonathan Sep 11 '17 at 18:25
  • 1
    Please update the accepted answer as @Jonathan suggests. I wouldn't call it perfect because it won't work on earlier versions of pip (v7 or v8), but is great otherwise. – Antony Hatchkins Sep 28 '17 at 08:23
  • 3
    @Rory please update the accepted answer, yolk is dead. Chris Montanaro's answer is the best method currently IMO. – Ryan Fisher Dec 06 '17 at 17:50
  • there's also extras - e.g. `pip install ipython[notebook]` - as I mentioned over at https://stackoverflow.com/questions/44507781/what-does-the-notebook-in-pip-install-ipythonnotebook-mean#comment85688290_44508042 there's a proposal to expose them in the pip cli: [Add support for outputting a list of extras and their requirements](https://github.com/pypa/pip/issues/4824) – Ben Creasy Mar 18 '18 at 03:06
  • First find the latest version available with `pip search `. Then try to install the next (unavailable version) `pip install ==x.y.z`. Use an `x.y.z` that's too high. `pip` will complain and tell you all versions that are available. – Josh Albert Sep 23 '19 at 22:16
  • 6
    @Rory Please change the accepted answer for the benefit of future visitors to this popular question. Yolk project is no longer maintained and it simply doesn't work as that answer claims. – wim Nov 01 '19 at 15:35
  • It's worth noting that PyPI package versions with details can be found online. For example here you see all the available Numpy versions https://pypi.org/project/numpy/#history – JStrahl Oct 06 '22 at 15:35

29 Answers29

1369

For pip >= 21.2 use:

pip index versions pylibmc

Note that this command is experimental, and might change in the future!

For pip >= 21.1 use:

pip install pylibmc==

For pip >= 20.3 use:

pip install --use-deprecated=legacy-resolver pylibmc==

For pip >= 9.0 use:

$ pip install pylibmc==
Collecting pylibmc==
  Could not find a version that satisfies the requirement pylibmc== (from 
  versions: 0.2, 0.3, 0.4, 0.5.1, 0.5.2, 0.5.3, 0.5.4, 0.5.5, 0.5, 0.6.1, 0.6, 
  0.7.1, 0.7.2, 0.7.3, 0.7.4, 0.7, 0.8.1, 0.8.2, 0.8, 0.9.1, 0.9.2, 0.9, 
  1.0-alpha, 1.0-beta, 1.0, 1.1.1, 1.1, 1.2.0, 1.2.1, 1.2.2, 1.2.3, 1.3.0)
No matching distribution found for pylibmc==

The available versions will be printed without actually downloading or installing any packages.

For pip < 9.0 use:

pip install pylibmc==blork

where blork can be any string that is not a valid version number.

Community
  • 1
  • 1
Chris Montanaro
  • 16,948
  • 4
  • 20
  • 29
  • With Python 2.6 I get `Could not find a version that satisfies the requirement twisted==1234567 (from version: )` even though `twisted` by itself is available, and currently installs version 16.0.0 (or it would, if it supported 2.6). – tripleee Mar 18 '16 at 07:49
  • @tripleee is it possible that you have another package that is making a conflict? Do you get the same results in a fresh virtualenv? – Chris Montanaro Mar 19 '16 at 16:19
  • This *is* a fresh virtualenv. – tripleee Mar 19 '16 at 20:05
  • @tripleee `(p26)monty-macbook:test spartzdev$ python -V Python 2.6.9 (p26)monty-macbook:test spartzdev$ pip install twisted==1234567 ... Could not find a version that satisfies the requirement twisted==1234567 (from versions: 2.1.0, 9.0.0, 10.0.0, 10.1.0, 10.2.0, 11.0.0, 11.1.0, 12.0.0, 12.1.0, 12.2.0, 12.3.0, 13.0.0, 13.1.0, 13.2.0, 14.0.0, 14.0.1, 14.0.2, 15.0.0, 15.1.0, 15.2.0, 15.2.1, 15.3.0, 15.4.0, 15.5.0, 16.0.0) No distributions matching the version for twisted==1234567` – Chris Montanaro Mar 21 '16 at 17:14
  • @ChrisMontanaro merely extrapolated from this answer =D – Jan Kyu Peblik Aug 24 '16 at 22:03
  • Does not work with pip 7.1.0, but works with pip 8.1.2 – Elouan Keryell-Even Sep 29 '16 at 12:19
  • @justarandomguy I updated my answer, add something after the == that is unlikely to be an install candidate `pip install django==blork` – Chris Montanaro Sep 30 '16 at 16:21
  • @justarandomguy heed the dev warning "You are using pip version 7.1.0, however version 8.1.2 is available. You should consider upgrading via the 'pip install --upgrade pip' command." – Chris Montanaro Sep 30 '16 at 16:23
  • 2
    Another nice property of this solution is that it works with all the normal flags to limit installation sources. For example `pip install --only-binary :all: pylibmc` will list all the versions of pylibmc available as binary packages. – pavon Nov 07 '16 at 20:42
  • 5
    `pip install pylibmc==9999999 | tr ', ' "\n" | sort -n` – Vikas Apr 06 '17 at 01:01
  • 41
    This should be marked as the correct answer as it does not necessitate any other packages to be installed. – Yves Dorfsman Jan 02 '18 at 04:10
  • 1
    Unfortunately this kind of thing is par for the course with package managers that are reinventing the wheel like pip does. – keithzg Oct 21 '20 at 00:38
  • 13
    I've submitted an issue for 20.3: https://github.com/pypa/pip/issues/9252 – Att Righ Dec 09 '20 at 17:28
  • awaiting a better solution for 20.3, I've got this silly function in my bashrc that works with pip 20.3: piplist() { pip install -v ${1}==alskdjflaksjdfl 2>/dev/null | grep "Found link" | awk -F 'version: ' '{print $2}' | tr '\n' ' ' ;} (for example: piplist apache-airflow) – user3017842 Dec 10 '20 at 09:55
  • 9
    Better way to get the old behavior back: `pip install django== --use-deprecated=legacy-resolver` – wim Dec 29 '20 at 21:45
  • @wim your answer is the only one that worked for me. – Fijoy Vadakkumpadan Feb 10 '21 at 16:05
  • 1
    This doesn't seem to work at all anymore, on any version of pip. Pip > 20.3 or 9.0.1 -- they will install version 0.0.0 of the dependency now – Jon Feb 24 '21 at 00:35
  • Since #9139 was closed, here's the summary: The warning of @BłażejMichalik has not yet come to pass - the developers did not remove the functionality in 21.0.1. Also, current status of the two PRs to fix this: https://github.com/pypa/pip/issues/9139 and https://github.com/pypa/pip/pull/9405. The first now has merge conflicts, the second has been merged to `master`, so hopefully in the pip 21.1 release soon. This restores functionality of `pip install flask==` without the legacy resolver, but long term, that isn't the CLI format the developers want (with good reason IMO) – Jake Stevens-Haas Apr 20 '21 at 19:12
  • 2
    To summarize: [#9405](https://github.com/pypa/pip/pull/9405) is merged, and so the functionality is working again on the `main` branch. Use `pip install git+https://github.com/pypa/pip.git; pip install flask==` to find out for yourself. Next versions of pip might remove the support for `xyz==` (see [packaging#321](https://github.com/pypa/packaging/issues/321)), so you might need to use `xyz==0` instead. Legacy resolver is a separate issue now, and will be removed with [#9631](https://github.com/pypa/pip/pull/9631). Jake said nothing bad, I misread his comment. I'm dumb. – Błażej Michalik Apr 20 '21 at 22:35
  • 1
    `pip install pylibmc==` brilliant – Joabe Lucena Oct 21 '21 at 17:38
  • This does not work. ERROR: unknown command "index" –  Feb 23 '22 at 18:17
  • Is there a way to get this to work with Python itself? – Adrian Keister Oct 12 '22 at 16:29
  • This should be the accepted answer. This is the BEST answer (where "BEST" = shortest, easiest to type, and easiest to remember). I use "conda search " all the time. "pip index " is the closest thing to "conda search". I would be afraid to use "pip install ==" in a script. I don't like the "pip install " approach because I only want a list of available versions, NOT to attempt an installation. When will the pip-sisters learn from the conda-men? – Rich Lysakowski PhD Nov 30 '22 at 04:58
194

(update: As of March 2020, many people have reported that yolk, installed via pip install yolk3k, only returns latest version. Chris's answer seems to have the most upvotes and worked for me)

The script at pastebin does work. However it's not very convenient if you're working with multiple environments/hosts because you will have to copy/create it every time.

A better all-around solution would be to use yolk3k, which is available to install with pip. E.g. to see what versions of Django are available:

$ pip install yolk3k
$ yolk -V django
Django 1.3
Django 1.2.5
Django 1.2.4
Django 1.2.3
Django 1.2.2
Django 1.2.1
Django 1.2
Django 1.1.4
Django 1.1.3
Django 1.1.2
Django 1.0.4

yolk3k is a fork of the original yolk which ceased development in 2012. Though yolk is no longer maintained (as indicated in comments below), yolk3k appears to be and supports Python 3.

Note: I am not involved in the development of yolk3k. If something doesn't seem to work as it should, leaving a comment here should not make much difference. Use the yolk3k issue tracker instead and consider submitting a fix, if possible.

JL Peyret
  • 10,917
  • 2
  • 54
  • 73
m000
  • 5,932
  • 3
  • 31
  • 28
  • It doesn't sounds like such a minor caveat. May be a problem - meaning? – m0she Mar 11 '13 at 11:06
  • 7
    The answer below (using the script from pastebin) is more cumbersome, but at least works in my case (searching for versions of scipy). yolk only shows the last version being available, the other script shows all versions dating back to 0.8.0. – oligofren Apr 12 '13 at 12:02
  • Just using pip install -v -d (as described below) shows all versions. Yolk didn't show everything when I tried it. – mlissner May 10 '14 at 01:11
  • 42
    Most of the time it will only return newest version – PawelRoman Dec 23 '14 at 11:49
  • 1
    @PawelRoman Yolk only returns whatever is listed on PyPi. Have you found a case where a version is listed on PyPi but not returned by yolk? If something is not listed on PyPi it should probably considered deprecated. – m000 Dec 23 '14 at 12:18
  • 17
    Fir python3 just use pip install yolk3k. The yolk command will be available. – Pierre Criulanscy Apr 03 '15 at 14:32
  • 15
    Like yolk, most of the time yolk3k only return newest version. – diabloneo May 26 '15 at 06:47
  • According to yolk's site this is for ALREADY installed packages. The question is about AVAILABLE packages, would this work? It looks like it does, thanks! – eco Jun 10 '16 at 00:16
  • 3
    @Flimm: shtuff.it changed their display name to Chris Montanaro. Link to the answer: http://stackoverflow.com/a/26664162/473899 – Esteis Aug 04 '16 at 13:01
  • This didn't even work for me on ubuntu. Gives `yolk: command not found`. – wordsforthewise Aug 07 '16 at 07:18
  • 2
    @Esteis: This is shorter: `pip install somepackage==-1`. Or 0 at one's own risk. – wdscxsj Nov 28 '16 at 13:49
  • 2
    yolk gives urllib2.HTTPError: HTTP Error 403: Must access using HTTPS instead of HTTP – Tagar Mar 14 '17 at 19:24
  • @Ruslan This has already been reported in the yolk issue tracker. I added a link to it at the end of my answer. – m000 Mar 16 '17 at 01:55
  • Downvoting since it doesn't work anymore. I would remove downvote if you mention this in the answer and tells people to look at the most popular answer. – Jonathan Sep 11 '17 at 18:29
  • Just thought I'd let you know how my first experience with yolk was. Needless to say perhaps but I found the == method to be more reliable. https://bpaste.net/show/d95ad0bdd708 – Stefan Midjich Nov 03 '17 at 10:09
  • 2
    Doesn't work in my environment of python 2.6 and python 2.7: yolk -V elasticsearch Traceback (most recent call last): File "/usr/lib64/python2.6/urllib2.py", line 518, in http_error_default raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) urllib2.HTTPError: HTTP Error 403: Must access using HTTPS instead of HTTP – Amro Younes Nov 14 '17 at 17:49
  • 2
    yolk is dead, the maintainer has vanished. As Tagar said it doesn't use HTTPS which is now required by PyPi. Use ChrisMontanaro's answer below. – Ryan Fisher Dec 06 '17 at 17:48
  • 11
    yolk is broken / no longer maintained. delete this answer. – wim Nov 01 '19 at 15:05
  • 1
    wrong answer : does not work anymore, only last version returned – John Doe Mar 04 '20 at 11:20
110

You don't need a third party package to get this information. pypi provides simple JSON feeds for all packages under

https://pypi.org/pypi/{PKG_NAME}/json

Here's some Python code using only the standard library which gets all versions.

import requests
from distutils.version import LooseVersion

def versions(package_name, limit_releases=10):
    url = f"https://pypi.org/pypi/{package_name}/json"
    data = requests.get(url).json()
    versions = list(data["releases"].keys())
    versions.sort(key=LooseVersion, reverse=True)
    return versions[:limit_releases]

print("\n".join(versions("typeguard")))

That code prints (as of 21/Jul/2023):

4.0.0rc6
4.0.0rc5
4.0.0rc4
4.0.0rc3
4.0.0rc2
4.0.0rc1
4.0.0
3.0.2
3.0.1
3.0.0rc2
chrimaho
  • 580
  • 4
  • 22
eric chiang
  • 2,575
  • 2
  • 20
  • 23
  • 2
    The JSON has a fair amount of nesting. I used `versions = [x for x in data["releases"] if any([y["python_version"] in ['cp26', '2.6'] for y in data["releases"][x]])]` to find versions compatible with Python 2.6. (I didn't see `cp26` anywhere, but some packages had `cp27` so I speculate that this might exist in other packages.) – tripleee Mar 18 '16 at 08:17
  • 4
    Here's a way to do it with curl, jq, and sort (a "one-liner"!): `curl -s https://pypi.python.org/pypi/{PKG_NAME}/json | jq -r '.releases | keys[]' | sort -t. -k 1,1n -k 2,2n -k 3,3n` – Alan Ivey Jun 08 '16 at 15:33
  • 3
    This throws a `ValueError` exception for some packages that follow not so strict versioning schemes. To fix it for these packages, [see this gist](https://gist.github.com/trinitronx/026574839d96a0c0efe1e9f2fd300f03). – TrinitronX Feb 07 '17 at 17:50
  • [outdated](https://github.com/alexmojaki/outdated/) will do this for you. – Shadi Oct 08 '19 at 14:48
  • 1
    Annoyingly StrictVersion doesn't work with packages with `dev` in their names. –  Jun 23 '20 at 10:25
  • In Py3.9 I have lot of minor problems with versions() function. I add the changed code as separate answer. – mirek Feb 12 '21 at 11:40
  • 1
    The comment from @AlanIvey now fails with "parse error: Invalid numeric literal at line 1, column 23" because pypi.python.org became pypi.org, per eg the answer from Timofey Stolbov or add -L to curl, as others have said – Martin Dorey Mar 12 '21 at 02:22
  • Thanks! UpVoted. Very useful method with JSON API of PIP. It is the only method that worked out for me. Because all other methods listed only Release versions of package, and I needed alpha/beta/rc versions. For example `pip index versions gmpy2` lists only release versions while JSON API [gives](https://pypi.org/pypi/gmpy2/json) hidden versions like `2.1.0b5` or `2.1.0rc1`. – Arty Nov 01 '21 at 09:59
66

Update:
As of Sep 2017 this method no longer works: --no-install was removed in pip 7

Use pip install -v, you can see all versions that available

root@node7:~# pip install web.py -v
Downloading/unpacking web.py
  Using version 0.37 (newest of versions: 0.37, 0.36, 0.35, 0.34, 0.33, 0.33, 0.32, 0.31, 0.22, 0.2)
  Downloading web.py-0.37.tar.gz (90Kb): 90Kb downloaded
  Running setup.py egg_info for package web.py
    running egg_info
    creating pip-egg-info/web.py.egg-info

To not install any package, use one of following solution:

root@node7:~# pip install --no-deps --no-install flask -v                                                                                                      
Downloading/unpacking flask
  Using version 0.10.1 (newest of versions: 0.10.1, 0.10, 0.9, 0.8.1, 0.8, 0.7.2, 0.7.1, 0.7, 0.6.1, 0.6, 0.5.2, 0.5.1, 0.5, 0.4, 0.3.1, 0.3, 0.2, 0.1)
  Downloading Flask-0.10.1.tar.gz (544Kb): 544Kb downloaded

or

root@node7:~# cd $(mktemp -d)
root@node7:/tmp/tmp.c6H99cWD0g# pip install flask -d . -v
Downloading/unpacking flask
  Using version 0.10.1 (newest of versions: 0.10.1, 0.10, 0.9, 0.8.1, 0.8, 0.7.2, 0.7.1, 0.7, 0.6.1, 0.6, 0.5.2, 0.5.1, 0.5, 0.4, 0.3.1, 0.3, 0.2, 0.1)
  Downloading Flask-0.10.1.tar.gz (544Kb): 4.1Kb downloaded

Tested with pip 1.0

root@node7:~# pip --version
pip 1.0 from /usr/lib/python2.7/dist-packages (python 2.7)
Antony Hatchkins
  • 31,947
  • 10
  • 111
  • 111
HVNSweeting
  • 2,859
  • 2
  • 35
  • 30
  • 11
    `pip 1.5.4` gives `DEPRECATION: --no-install, --no-download, --build, and --no-clean are deprecated. See https://github.com/pypa/pip/issues/906.` and doesn't show available versions for packages that are already installed. – int_ua Mar 24 '15 at 16:22
  • 2
    to show all of versions, it just needs ``-v``. The rest of my answer is for avoiding addition effect (install/download). For installed pkg, just add --upgrade. Anw, you can create a separate virtualenv to make everything simpler. – HVNSweeting Mar 25 '15 at 08:18
  • 2
    pip 9.0.1 barks: `no such option: --no-install` – moin moin Jan 17 '17 at 15:40
  • "newest of versions:" from -v excludes some versions. – mmacvicar Jun 08 '17 at 18:38
36

I came up with dead-simple bash script. Thanks to jq's author.

#!/bin/bash
set -e

PACKAGE_JSON_URL="https://pypi.org/pypi/${1}/json"

curl -L -s "$PACKAGE_JSON_URL" | jq  -r '.releases | keys | .[]' | sort -V

Update:

  • Add sorting by version number.
  • Add -L to follow redirects.
Timofey Stolbov
  • 4,501
  • 3
  • 40
  • 45
  • I was unable to get `curl` to work, possibly because of certificate errors. `wget --no-check-certificate` works, but even `curl -k --insecure` produces nothing. The warning I get with `wget` says `ERROR: certificate common name \`www.python.org´ doesn´t match requested host name \`pypi.python.org´.` – tripleee Mar 18 '16 at 07:57
  • The `sort -V` doesn't work on OSX with homebrew's version of `jq` – deepelement May 08 '17 at 10:09
  • @deepelement See [my answer](https://stackoverflow.com/a/64866883/5649639) for a workaround when `sort -V` is not available. – SebMa Nov 16 '20 at 22:54
  • To get this working add -L to curl. (Follow redirects) – Hielke Walinga Dec 06 '20 at 17:14
  • 1
    Oneliner format: `PACKAGE=; curl -L -s "https://pypi.org/pypi/${PACKAGE}/json" | jq -r '.releases | keys | .[]' | sort -Vr | head -n 10` – Arthur Alvim Sep 10 '22 at 14:56
22

You can use this small Python 3 script (using only standard library modules) to grab the list of available versions for a package from PyPI using JSON API and print them in reverse chronological order. Unlike some other Python solutions posted here, this doesn't break on loose versions like django's 2.2rc1 or uwsgi's 2.0.17.1:

#!/usr/bin/env python3

import json
import sys
from urllib import request    
from pkg_resources import parse_version    

def versions(pkg_name):
    url = f'https://pypi.python.org/pypi/{pkg_name}/json'
    releases = json.loads(request.urlopen(url).read())['releases']
    return sorted(releases, key=parse_version, reverse=True)    

if __name__ == '__main__':
    print(*versions(sys.argv[1]), sep='\n')

Save the script and run it with the package name as an argument, e.g.:

python versions.py django
3.0a1
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2
2.2rc1
...
Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
19

After looking at pip's code for a while, it looks like the code responsible for locating packages can be found in the PackageFinder class in pip.index. Its method find_requirement looks up the versions of a InstallRequirement, but unfortunately only returns the most recent version.

The code below is almost a 1:1 copy of the original function, with the return in line 114 changed to return all versions.

The script expects one package name as first and only argument and returns all versions.

http://pastebin.com/axzdUQhZ

I can't guarantee for the correctness, as I'm not familiar with pip's code. But hopefully this helps.

Sample output

python test.py pip
Versions of pip
0.8.2
0.8.1
0.8
0.7.2
0.7.1
0.7
0.6.3
0.6.2
0.6.1
0.6
0.5.1
0.5
0.4
0.3.1
0.3
0.2.1
0.2 dev

The code:

import posixpath
import pkg_resources
import sys
from pip.download import url_to_path
from pip.exceptions import DistributionNotFound
from pip.index import PackageFinder, Link
from pip.log import logger
from pip.req import InstallRequirement
from pip.util import Inf


class MyPackageFinder(PackageFinder):

    def find_requirement(self, req, upgrade):
        url_name = req.url_name
        # Only check main index if index URL is given:
        main_index_url = None
        if self.index_urls:
            # Check that we have the url_name correctly spelled:
            main_index_url = Link(posixpath.join(self.index_urls[0], url_name))
            # This will also cache the page, so it's okay that we get it again later:
            page = self._get_page(main_index_url, req)
            if page is None:
                url_name = self._find_url_name(Link(self.index_urls[0]), url_name, req) or req.url_name

        # Combine index URLs with mirror URLs here to allow
        # adding more index URLs from requirements files
        all_index_urls = self.index_urls + self.mirror_urls

        def mkurl_pypi_url(url):
            loc = posixpath.join(url, url_name)
            # For maximum compatibility with easy_install, ensure the path
            # ends in a trailing slash.  Although this isn't in the spec
            # (and PyPI can handle it without the slash) some other index
            # implementations might break if they relied on easy_install's behavior.
            if not loc.endswith('/'):
                loc = loc + '/'
            return loc
        if url_name is not None:
            locations = [
                mkurl_pypi_url(url)
                for url in all_index_urls] + self.find_links
        else:
            locations = list(self.find_links)
        locations.extend(self.dependency_links)
        for version in req.absolute_versions:
            if url_name is not None and main_index_url is not None:
                locations = [
                    posixpath.join(main_index_url.url, version)] + locations

        file_locations, url_locations = self._sort_locations(locations)

        locations = [Link(url) for url in url_locations]
        logger.debug('URLs to search for versions for %s:' % req)
        for location in locations:
            logger.debug('* %s' % location)
        found_versions = []
        found_versions.extend(
            self._package_versions(
                [Link(url, '-f') for url in self.find_links], req.name.lower()))
        page_versions = []
        for page in self._get_pages(locations, req):
            logger.debug('Analyzing links from page %s' % page.url)
            logger.indent += 2
            try:
                page_versions.extend(self._package_versions(page.links, req.name.lower()))
            finally:
                logger.indent -= 2
        dependency_versions = list(self._package_versions(
            [Link(url) for url in self.dependency_links], req.name.lower()))
        if dependency_versions:
            logger.info('dependency_links found: %s' % ', '.join([link.url for parsed, link, version in dependency_versions]))
        file_versions = list(self._package_versions(
                [Link(url) for url in file_locations], req.name.lower()))
        if not found_versions and not page_versions and not dependency_versions and not file_versions:
            logger.fatal('Could not find any downloads that satisfy the requirement %s' % req)
            raise DistributionNotFound('No distributions at all found for %s' % req)
        if req.satisfied_by is not None:
            found_versions.append((req.satisfied_by.parsed_version, Inf, req.satisfied_by.version))
        if file_versions:
            file_versions.sort(reverse=True)
            logger.info('Local files found: %s' % ', '.join([url_to_path(link.url) for parsed, link, version in file_versions]))
            found_versions = file_versions + found_versions
        all_versions = found_versions + page_versions + dependency_versions
        applicable_versions = []
        for (parsed_version, link, version) in all_versions:
            if version not in req.req:
                logger.info("Ignoring link %s, version %s doesn't match %s"
                            % (link, version, ','.join([''.join(s) for s in req.req.specs])))
                continue
            applicable_versions.append((link, version))
        applicable_versions = sorted(applicable_versions, key=lambda v: pkg_resources.parse_version(v[1]), reverse=True)
        existing_applicable = bool([link for link, version in applicable_versions if link is Inf])
        if not upgrade and existing_applicable:
            if applicable_versions[0][1] is Inf:
                logger.info('Existing installed version (%s) is most up-to-date and satisfies requirement'
                            % req.satisfied_by.version)
            else:
                logger.info('Existing installed version (%s) satisfies requirement (most up-to-date version is %s)'
                            % (req.satisfied_by.version, applicable_versions[0][1]))
            return None
        if not applicable_versions:
            logger.fatal('Could not find a version that satisfies the requirement %s (from versions: %s)'
                         % (req, ', '.join([version for parsed_version, link, version in found_versions])))
            raise DistributionNotFound('No distributions matching the version for %s' % req)
        if applicable_versions[0][0] is Inf:
            # We have an existing version, and its the best version
            logger.info('Installed version (%s) is most up-to-date (past versions: %s)'
                        % (req.satisfied_by.version, ', '.join([version for link, version in applicable_versions[1:]]) or 'none'))
            return None
        if len(applicable_versions) > 1:
            logger.info('Using version %s (newest of versions: %s)' %
                        (applicable_versions[0][1], ', '.join([version for link, version in applicable_versions])))
        return applicable_versions


if __name__ == '__main__':
    req = InstallRequirement.from_line(sys.argv[1], None)
    finder = MyPackageFinder([], ['http://pypi.python.org/simple/'])
    versions = finder.find_requirement(req, False)
    print 'Versions of %s' % sys.argv[1]
    for v in versions:
        print v[1]
GabLeRoux
  • 16,715
  • 16
  • 63
  • 81
Reiner Gerecke
  • 11,936
  • 1
  • 49
  • 41
  • This worked a whole lot better than the answer above. skinny $ yolk -V scipy scipy 0.12.0 skinny $ python test.py scipy Versions of scipy 0.12.0 0.12.0 0.11.0 0.11.0 0.10.1 0.10.1 0.10.0 0.10.0 0.9.0 0.9.0 0.8.0 – oligofren Apr 12 '13 at 12:02
  • 1
    This usage is explicitly discouraged in [the docs](https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program): "***you must not use pip’s internal APIs in this way***" – wim Nov 01 '19 at 15:03
17

You could the yolk3k package instead of yolk. yolk3k is a fork from the original yolk and it supports both python2 and 3.

https://github.com/myint/yolk

pip install yolk3k
GabLeRoux
  • 16,715
  • 16
  • 63
  • 81
ykyuen
  • 225
  • 2
  • 3
12

My project luddite has this feature.

Example usage:

>>> import luddite
>>> luddite.get_versions_pypi("python-dateutil")
('0.1', '0.3', '0.4', '0.5', '1.0', '1.1', '1.2', '1.4', '1.4.1', '1.5', '2.0', '2.1', '2.2', '2.3', '2.4.0', '2.4.1', '2.4.2', '2.5.0', '2.5.1', '2.5.2', '2.5.3', '2.6.0', '2.6.1', '2.7.0', '2.7.1', '2.7.2', '2.7.3', '2.7.4', '2.7.5', '2.8.0')

It lists all versions of a package available, by querying the JSON API of https://pypi.org/

wim
  • 338,267
  • 99
  • 616
  • 750
  • It would be more instructive if you would tell us what your package is doing, otherwise you are just promoting your software :) – user228395 Nov 16 '19 at 22:04
  • 1
    @user228395 I thought it was obvious enough, but it list all versions of a package that's available, which was exactly what the title of the question asks about. Edited - better? – wim Nov 16 '19 at 22:33
  • Its workings of course. So it is essentially wrapping the solution presented by @Timofey Stolbov? – user228395 Nov 16 '19 at 22:52
  • 2
    @user228395 I would not call it "wrapping", since that answer uses bash, curl and jq - whereas luddite just uses the Python standard library (urllib). But the solution from Stolbov does use the same endpoint on https://pypi.org. May I ask what is the reason for your downvote? – wim Nov 16 '19 at 23:02
  • Because I consider a black-box software package, that does a couple of lines of code - similar to what was already presented, not a proper solution. It could've been a comment to Stolbov's, or you could have given the lines if they were substantially new. – user228395 Nov 16 '19 at 23:18
  • 1
    If you followed the link to the project detail page, you could see that the project's main feature is about checking [`requirements.txt`](https://user-images.githubusercontent.com/6615374/43939075-feec4530-9c2c-11e8-9770-6f7f762c72e4.png) files for out-of date packages. It is more than a couple of lines of code. In order to check a `requirements.txt` file, you need the functionality to list all package versions. This part is intentionally decoupled, and part of luddite's public API. And it's source Apache License 2.0, I think it's not really fair to call that a "black-box" software package. – wim Nov 16 '19 at 23:27
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/202491/discussion-between-user228395-and-wim). – user228395 Nov 16 '19 at 23:28
12

You can try to install package version that does to exist. Then pip will list available versions

pip install hell==99999
ERROR: Could not find a version that satisfies the requirement hell==99999
(from versions: 0.1.0, 0.2.0, 0.2.1, 0.2.2, 0.2.3, 0.2.4, 0.3.0,
0.3.1, 0.3.2, 0.3.3, 0.3.4, 0.4.0, 0.4.1)
ERROR: No matching distribution found for hell==99999
9

This works for me on OSX:

pip install docker-compose== 2>&1 \
| grep -oE '(\(.*\))' \
| awk -F:\  '{print$NF}' \
| sed -E 's/( |\))//g' \
| tr ',' '\n'

It returns the list one per line:

1.1.0rc1
1.1.0rc2
1.1.0
1.2.0rc1
1.2.0rc2
1.2.0rc3
1.2.0rc4
1.2.0
1.3.0rc1
1.3.0rc2
1.3.0rc3
1.3.0
1.3.1
1.3.2
1.3.3
1.4.0rc1
1.4.0rc2
1.4.0rc3
1.4.0
1.4.1
1.4.2
1.5.0rc1
1.5.0rc2
1.5.0rc3
1.5.0
1.5.1
1.5.2
1.6.0rc1
1.6.0
1.6.1
1.6.2
1.7.0rc1
1.7.0rc2
1.7.0
1.7.1
1.8.0rc1
1.8.0rc2
1.8.0
1.8.1
1.9.0rc1
1.9.0rc2
1.9.0rc3
1.9.0rc4
1.9.0
1.10.0rc1
1.10.0rc2
1.10.0

Or to get the latest version available:

pip install docker-compose== 2>&1 \
| grep -oE '(\(.*\))' \
| awk -F:\  '{print$NF}' \
| sed -E 's/( |\))//g' \
| tr ',' '\n' \
| gsort -r -V \
| head -1
1.10.0rc2

Keep in mind gsort has to be installed (on OSX) to parse the versions. You can install it with brew install coreutils

GabLeRoux
  • 16,715
  • 16
  • 63
  • 81
grandma
  • 263
  • 3
  • 6
9

Update:

Maybe the solution is not needed anymore, check comments to this answer.

Original Answer

With pip versions above 20.03 you can use the old solver in order to get back all the available versions:

$ pip install  --use-deprecated=legacy-resolver pylibmc==
ERROR: Could not find a version that satisfies the requirement pylibmc== (from    
versions: 0.2, 0.3, 0.4, 0.5, 0.5.1, 0.5.2, 0.5.3, 0.5.4, 0.5.5, 0.6, 0.6.1,
0.7, 0.7.1, 0.7.2, 0.7.3, 0.7.4, 0.8, 0.8.1, 0.8.2, 0.9, 0.9.1, 0.9.2, 1.0a0, 
1.0b0, 1.0, 1.1, 1.1.1, 1.2.0, 1.2.1, 1.2.2, 1.2.3, 1.3.0, 1.4.0, 1.4.1, 
1.4.2, 1.4.3, 1.5.0, 1.5.1, 1.5.2, 1.5.100.dev0, 1.6.0, 1.6.1)

ERROR: No matching distribution found for pylibmc==
Vincenzo Lavorini
  • 1,884
  • 2
  • 15
  • 26
  • 1
    It is no longer required in pip >= 21.1 (see [issue](https://github.com/pypa/pip/issues/9139)), may as well delete this answer now. – wim Jun 02 '21 at 15:07
7

The pypi-version package does an excellent job:

$ pip3 install pip-versions

$ pip-versions latest rsyncy
0.0.4

$ pip-versions list rsyncy
0.0.1
0.0.2
0.0.3
0.0.4

And this even works behind a Nexus (sonatype) proxy!

laktak
  • 57,064
  • 17
  • 134
  • 164
  • **This appears to have stopped working** with the death of `pip search` (https://stackoverflow.com/questions/65307988/error-using-pip-search-pip-search-stopped-working/65350324) I'm getting `urllib.error.HTTPError: HTTP Error 404: Not Found` – Att Righ Nov 16 '21 at 18:02
7

I usually run pip install packagename==somerandomstring. This returns error saying Could not find a version that satisfies the requirement packagename==somerandomstring and along with that error, pip will also list available versions on the server.

e.g.

$ pip install flask==aksjflashd
Collecting flask==aksjflashd
  Could not find a version that satisfies the requirement flask==aksjflashd 
(from versions: 0.1, 0.2, 0.3, 0.3.1, 0.4, 0.5, 0.5.1, 0.5.2, 0.6, 0.6.1, 0.7, 0.7.1, 0.7.2, 0.8, 0.8.1, 0.9, 0.10, 0.10.1, 0.11, 0.11.1, 0.12, 0.12.1, 
0.12.2, 0.12.3, 0.12.4, 0.12.5, 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4, 1.1.0, 1.1.1, 1.1.2)
No matching distribution found for flask==aksjflashd
$

You have to be extremely unlucky if the random string like 'aksjflashd' turns out to be actual package version!

Of course, you can use this trick with pip download too.

Tejas Sarade
  • 1,144
  • 12
  • 17
6

https://pypi.python.org/pypi/Django/ - works for packages whose maintainers choose to show all packages https://pypi.python.org/simple/pip/ - should do the trick anyhow (lists all links)

m0she
  • 444
  • 1
  • 4
  • 9
4

Alternative solution is to use the Warehouse APIs:

https://warehouse.readthedocs.io/api-reference/json/#release

For instance for Flask:

import requests
r = requests.get("https://pypi.org/pypi/Flask/json")
print(r.json()['releases'].keys())

will print:

dict_keys(['0.1', '0.10', '0.10.1', '0.11', '0.11.1', '0.12', '0.12.1', '0.12.2', '0.12.3', '0.12.4', '0.2', '0.3', '0.3.1', '0.4', '0.5', '0.5.1', '0.5.2', '0.6', '0.6.1', '0.7', '0.7.1', '0.7.2', '0.8', '0.8.1', '0.9', '1.0', '1.0.1', '1.0.2'])
GabLeRoux
  • 16,715
  • 16
  • 63
  • 81
Charlie
  • 1,750
  • 15
  • 20
3

Here's my answer that sorts the list inside jq (for those who use systems where sort -V is not avalable) :

$ pythonPackage=certifi
$ curl -Ls https://pypi.org/pypi/$pythonPackage/json | jq -r '.releases | keys_unsorted | sort_by( split(".") | map(tonumber) )'
  ............. 
  "2019.3.9",
  "2019.6.16",
  "2019.9.11",
  "2019.11.28",
  "2020.4.5",
  "2020.4.5.1",
  "2020.4.5.2",
  "2020.6.20",
  "2020.11.8"
]

And to fetch the last version number of the package :

$ curl -Ls https://pypi.org/pypi/$pythonPackage/json | jq -r '.releases | keys_unsorted | sort_by( split(".") | map(tonumber) )[-1]'
2020.11.8

or a bit faster :

$ curl -Ls https://pypi.org/pypi/$pythonPackage/json | jq -r '.releases | keys_unsorted | max_by( split(".") | map(tonumber) )'
2020.11.8

Or even more simple :) :

$ curl -Ls https://pypi.org/pypi/$pythonPackage/json | jq -r .info.version
2020.11.8
SebMa
  • 4,037
  • 29
  • 39
2

Simple bash script that relies only on python itself (I assume that in the context of the question it should be installed) and one of curl or wget. It has an assumption that you have setuptools package installed to sort versions (almost always installed). It doesn't rely on external dependencies such as:

  • jq which may not be present;
  • grep and awk that may behave differently on Linux and macOS.
curl --silent --location https://pypi.org/pypi/requests/json | python -c "import sys, json, pkg_resources; releases = json.load(sys.stdin)['releases']; print(' '.join(sorted(releases, key=pkg_resources.parse_version)))"

A little bit longer version with comments.

Put the package name into a variable:

PACKAGE=requests

Get versions (using curl):

VERSIONS=$(curl --silent --location https://pypi.org/pypi/$PACKAGE/json | python -c "import sys, json, pkg_resources; releases = json.load(sys.stdin)['releases']; print(' '.join(sorted(releases, key=pkg_resources.parse_version)))")

Get versions (using wget):

VERSIONS=$(wget -qO- https://pypi.org/pypi/$PACKAGE/json | python -c "import sys, json, pkg_resources; releases = json.load(sys.stdin)['releases']; print(' '.join(sorted(releases, key=pkg_resources.parse_version)))")

Print sorted versions:

echo $VERSIONS
Andrey Semakin
  • 2,032
  • 1
  • 23
  • 50
1

I didn't have any luck with yolk, yolk3k or pip install -v but so I ended up using this (adapted to Python 3 from eric chiang's answer):

import json
import requests
from distutils.version import StrictVersion

def versions(package_name):
    url = "https://pypi.python.org/pypi/{}/json".format(package_name)
    data = requests.get(url).json()
    return sorted(list(data["releases"].keys()), key=StrictVersion, reverse=True)

>>> print("\n".join(versions("gunicorn")))
19.1.1
19.1.0
19.0.0
18.0
17.5
0.17.4
0.17.3
...
Andrew Magee
  • 6,506
  • 4
  • 35
  • 58
  • 1
    `StrictVersion` won't work for many packages (`django`, `uwsgi`, `psycopg2` to name a few). You can use `parse_version()` from `setuptools` (see my [answer](http://stackoverflow.com/a/40745656/244297) for an example). – Eugene Yarmash Nov 22 '16 at 15:37
1

Works with recent pip versions, no extra tools necessary:

pip install pylibmc== -v 2>/dev/null | awk '/Found link/ {print $NF}' | uniq
Michel de Ruiter
  • 7,131
  • 5
  • 49
  • 74
  • This one is better than many alternatives here as it uses the new resolver that might differ from the legacy one. – lorenzo Mar 23 '21 at 10:09
1

To find all available (even incompatible) versions as well, use the -vv flag with pip >= 21.x.

pip install sklearn== --dry-run -vv

Incompatible versions will be listed in the log like this:

Skipping link: none of the wheel's tags (cp27-cp27m-win32) are compatible
aedm
  • 5,596
  • 2
  • 32
  • 36
0

This is Py3.9+ version of Limmy+EricChiang 's solution.

import json
import urllib.request
from distutils.version import StrictVersion


# print PyPI versions of package
def versions(package_name):
    url = "https://pypi.org/pypi/%s/json" % (package_name,)
    data = json.load(urllib.request.urlopen(url))
    versions = list(data["releases"])
    sortfunc = lambda x: StrictVersion(x.replace('rc', 'b').translate(str.maketrans('cdefghijklmn', 'bbbbbbbbbbbb')))
    versions.sort(key=sortfunc)
    return versions
mirek
  • 1,140
  • 11
  • 10
0

As of what I understood from this and this, the releases key will be dropped in a near future so solutions using GET "https://pypi.python.org/pypi/{package_name}/json" will not work anymore.

0

The easiest way to get the latest dependency version nowadays, using just curl and jq:

curl -sL https://pypi.org/pypi/${PACKAGE}/json | jq -r .info.version
Markus Unterwaditzer
  • 7,992
  • 32
  • 60
-1

My take is a combination of a couple of posted answers, with some modifications to make them easier to use from within a running python environment.

The idea is to provide a entirely new command (modeled after the install command) that gives you an instance of the package finder to use. The upside is that it works with, and uses, any indexes that pip supports and reads your local pip configuration files, so you get the correct results as you would with a normal pip install.

I've made an attempt at making it compatible with both pip v 9.x and 10.x.. but only tried it on 9.x

https://gist.github.com/kaos/68511bd013fcdebe766c981f50b473d4

#!/usr/bin/env python
# When you want a easy way to get at all (or the latest) version of a certain python package from a PyPi index.

import sys
import logging

try:
    from pip._internal import cmdoptions, main
    from pip._internal.commands import commands_dict
    from pip._internal.basecommand import RequirementCommand
except ImportError:
    from pip import cmdoptions, main
    from pip.commands import commands_dict
    from pip.basecommand import RequirementCommand

from pip._vendor.packaging.version import parse as parse_version

logger = logging.getLogger('pip')

class ListPkgVersionsCommand(RequirementCommand):
    """
    List all available versions for a given package from:

    - PyPI (and other indexes) using requirement specifiers.
    - VCS project urls.
    - Local project directories.
    - Local or remote source archives.

    """
    name = "list-pkg-versions"
    usage = """
      %prog [options] <requirement specifier> [package-index-options] ...
      %prog [options] [-e] <vcs project url> ...
      %prog [options] [-e] <local project path> ...
      %prog [options] <archive url/path> ..."""

    summary = 'List package versions.'

    def __init__(self, *args, **kw):
        super(ListPkgVersionsCommand, self).__init__(*args, **kw)

        cmd_opts = self.cmd_opts

        cmd_opts.add_option(cmdoptions.install_options())
        cmd_opts.add_option(cmdoptions.global_options())
        cmd_opts.add_option(cmdoptions.use_wheel())
        cmd_opts.add_option(cmdoptions.no_use_wheel())
        cmd_opts.add_option(cmdoptions.no_binary())
        cmd_opts.add_option(cmdoptions.only_binary())
        cmd_opts.add_option(cmdoptions.pre())
        cmd_opts.add_option(cmdoptions.require_hashes())

        index_opts = cmdoptions.make_option_group(
            cmdoptions.index_group,
            self.parser,
        )

        self.parser.insert_option_group(0, index_opts)
        self.parser.insert_option_group(0, cmd_opts)

    def run(self, options, args):
        cmdoptions.resolve_wheel_no_use_binary(options)
        cmdoptions.check_install_build_global(options)

        with self._build_session(options) as session:
            finder = self._build_package_finder(options, session)

            # do what you please with the finder object here... ;)
            for pkg in args:
                logger.info(
                    '%s: %s', pkg,
                    ', '.join(
                        sorted(
                            set(str(c.version) for c in finder.find_all_candidates(pkg)),
                            key=parse_version,
                        )
                    )
                )


commands_dict[ListPkgVersionsCommand.name] = ListPkgVersionsCommand

if __name__ == '__main__':
    sys.exit(main())

Example output

./list-pkg-versions.py list-pkg-versions pika django
pika: 0.5, 0.5.1, 0.5.2, 0.9.1a0, 0.9.2a0, 0.9.3, 0.9.4, 0.9.5, 0.9.6, 0.9.7, 0.9.8, 0.9.9, 0.9.10, 0.9.11, 0.9.12, 0.9.13, 0.9.14, 0.10.0b1, 0.10.0b2, 0.10.0, 0.11.0b1, 0.11.0, 0.11.1, 0.11.2, 0.12.0b2
django: 1.1.3, 1.1.4, 1.2, 1.2.1, 1.2.2, 1.2.3, 1.2.4, 1.2.5, 1.2.6, 1.2.7, 1.3, 1.3.1, 1.3.2, 1.3.3, 1.3.4, 1.3.5, 1.3.6, 1.3.7, 1.4, 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.4.8, 1.4.9, 1.4.10, 1.4.11, 1.4.12, 1.4.13, 1.4.14, 1.4.15, 1.4.16, 1.4.17, 1.4.18, 1.4.19, 1.4.20, 1.4.21, 1.4.22, 1.5, 1.5.1, 1.5.2, 1.5.3, 1.5.4, 1.5.5, 1.5.6, 1.5.7, 1.5.8, 1.5.9, 1.5.10, 1.5.11, 1.5.12, 1.6, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.6.6, 1.6.7, 1.6.8, 1.6.9, 1.6.10, 1.6.11, 1.7, 1.7.1, 1.7.2, 1.7.3, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9, 1.7.10, 1.7.11, 1.8a1, 1.8b1, 1.8b2, 1.8rc1, 1.8, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.8.5, 1.8.6, 1.8.7, 1.8.8, 1.8.9, 1.8.10, 1.8.11, 1.8.12, 1.8.13, 1.8.14, 1.8.15, 1.8.16, 1.8.17, 1.8.18, 1.8.19, 1.9a1, 1.9b1, 1.9rc1, 1.9rc2, 1.9, 1.9.1, 1.9.2, 1.9.3, 1.9.4, 1.9.5, 1.9.6, 1.9.7, 1.9.8, 1.9.9, 1.9.10, 1.9.11, 1.9.12, 1.9.13, 1.10a1, 1.10b1, 1.10rc1, 1.10, 1.10.1, 1.10.2, 1.10.3, 1.10.4, 1.10.5, 1.10.6, 1.10.7, 1.10.8, 1.11a1, 1.11b1, 1.11rc1, 1.11, 1.11.1, 1.11.2, 1.11.3, 1.11.4, 1.11.5, 1.11.6, 1.11.7, 1.11.8, 1.11.9, 1.11.10, 1.11.11, 1.11.12, 2.0, 2.0.1, 2.0.2, 2.0.3, 2.0.4
GabLeRoux
  • 16,715
  • 16
  • 63
  • 81
Kaos
  • 984
  • 7
  • 17
  • 1
    this usage is explicitly discouraged in [the docs](https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program): "***you must not use pip’s internal APIs in this way***" – wim Nov 01 '19 at 15:01
-1
pypi-has() { set -o pipefail; curl -sfL https://pypi.org/pypi/$1/json | jq -e --arg v $2 'any( .releases | keys[]; . == $v )'; }

Usage:

$ pypi-has django 4.0x ; echo $?
false
1

$ pypi-has djangos 4.0x ; echo $?
22

$ pypi-has djangos 4.0 ; echo $?
22

$ pypi-has django 4.0 ; echo $?
true
0
expelledboy
  • 2,033
  • 18
  • 18
-1

Providing a programmatic approach to Chris's answer using pip install <package_name>==

import re
import subprocess
from packaging.version import VERSION_PATTERN as _VRESION_PATTERN

VERSION_PATTERN = re.compile(_VRESION_PATTERN , re.VERBOSE | re.IGNORECASE)


def get_available_versions(package_name):
    process = subprocess.run(['pip', 'install', f'{package_name}=='], stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
    versions = []
    for line in process.stderr.decode('utf-8').splitlines():
        if 'Could not find a version that satisfies the requirement' in line:
            for match in VERSION_PATTERN.finditer(line.split('from versions:')[1]):
                versions.append(match.group(0))
    return versions

It can be used like

>>> get_available_versions('tensorflow')
['2.2.0rc1', '2.2.0rc2', '2.2.0rc3', '2.2.0rc4', '2.2.0', '2.2.1', '2.2.2', '2.2.3', '2.3.0rc0', '2.3.0rc1', '2.3.0rc2', '2.3.0', '2.3.1', '2.3.2', '2.3.3', '2.3.4', '2.4.0rc0', '2.4.0rc1', '2.4.0rc2', '2.4.0rc3', '2.4.0rc4', '2.4.0', '2.4.1', '2.4.2', '2.4.3', '2.4.4', '2.5.0rc0', '2.5.0rc1', '2.5.0rc2', '2.5.0rc3', '2.5.0', '2.5.1', '2.5.2', '2.5.3', '2.6.0rc0', '2.6.0rc1', '2.6.0rc2', '2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.7.0rc0', '2.7.0rc1', '2.7.0', '2.7.1', '2.8.0rc0', '2.8.0rc1', '2.8.0']

and return a list of versions.

Note: it seems to provide compatible releases rather than all releases. To get full list, use json approach from Eric.

-1

To fetch the latest version for a GitLab private package, the below works.

pip index versions package-name --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.com/api/v4/projects/<project-id>/packages/pypi/simple/ | grep  'LATEST:' | sed -E 's/LATEST:| //g'
-2

You can try to:

Step 1:

$ pip install get_pypi_latest_version

Step 2:

  • Run by python script:
    from get_pypi_latest_version import GetPyPiLatestVersion
    
    obtainer = GetPyPiLatestVersion()
    
    package_name = 'opencv-python'
    latest_version = obtainer(package_name)
    print(latest_version)
    
  • Run with CLI
    $ get_pypi_latest_version opencv-python
    # 4.7.0.72
    
SWHL
  • 1
  • 1