PyPI API - How to get stable package version
pip, pypi, python
Solution
Version scheme defined in the PEP-440. There is a module packaging, which can handle version parsing and comparison.
I came up with this function to get latest stable version of a package:
import requests
import json
try:
from packaging.version import parse
except ImportError:
from pip._vendor.packaging.version import parse
URL_PATTERN = 'https://pypi.python.org/pypi/{package}/json'
def get_version(package, url_pattern=URL_PATTERN):
"""Return version of package on pypi.python.org using json."""
req = requests.get(url_pattern.format(package=package))
version = parse('0')
if req.status_code == requests.codes.ok:
j = json.loads(req.text.encode(req.encoding))
releases = j.get('releases', [])
for release in releases:
ver = parse(release)
if not ver.is_prerelease:
version = max(version, ver)
return version
if __name__ == '__main__':
print("Django==%s" % get_version('Django'))
When executed, this produces following results:
$ python v.py
Django==2.0
Problem
How does `pip` determine which version is the stable version of a package? For example, the current stable release of Django is `1.7.5` (as of 2-27-15), and that is the version installed by the command `pip install django`. But when I go to the PyPI JSON API for Django (https://pypi.python.org/pypi/Django/json), it resolves to the most recent release (including development versions): ``` "version": "1.8b1", ``` There is a key in the JSON response that looks like it would indicate stable: ``` "stable_version": null, ``` but the value is `null` on all the packages I tried in the API. There is this line in the JSON response: ``` "classifiers": [ "Development Status :: 4 - Beta", ``` But that is a complex line to parse on. It would be nice if there was a line like `"stable_version": true` or `false`. How can I determine the default pip installed version using the PyPI JSON API?