Python dan pip, daftar semua versi paket yang tersedia?

445

Diberi nama paket Python yang dapat diinstal dengan pip , apakah ada cara untuk mengetahui daftar semua versi yang memungkinkan yang bisa dipasang oleh pip? Sekarang ini coba-coba.

Saya mencoba untuk menginstal versi untuk perpustakaan pihak ketiga, tetapi versi terbaru terlalu baru, ada beberapa perubahan yang dibuat tidak kompatibel. Jadi saya ingin entah bagaimana memiliki daftar semua versi yang diketahui pip, sehingga saya dapat mengujinya.

Rory
sumber
1
Jawaban yang diterima tidak setara dengan yang lain dengan skrip karena mereka tidak menghasilkan output yang sama.
oligofren
17
Harap perbarui jawaban yang dipilih. Kuning telur rusak dan tidak dibutuhkan. Jawaban dengan pip install pylibmc==sempurna.
Jonathan
Harap perbarui jawaban yang diterima seperti yang disarankan @Jonathan. Saya tidak akan menyebutnya sempurna karena tidak akan berfungsi pada versi pip yang lebih lama (v7 atau v8), tetapi lebih baik jika tidak.
Antony Hatchkins
1
@Rory tolong perbarui jawaban yang diterima, kuning telur sudah mati. Jawaban Chris Montanaro adalah metode terbaik saat ini IMO.
Ryan Fisher
1
@Rory Harap ubah jawaban yang diterima untuk kepentingan pengunjung masa depan untuk pertanyaan populer ini. Proyek Yolk tidak lagi dipertahankan dan tidak berfungsi seperti yang diklaim oleh jawaban itu.
wim

Jawaban:

167

(Pembaruan: Pada Maret 2020, banyak orang telah melaporkan bahwa kuning telur, dipasang melalui pip install yolk3k, hanya mengembalikan versi terbaru. Jawaban Chris tampaknya memiliki banyak upvotes dan bekerja untuk saya)

Script di pastebin berhasil. Namun itu tidak terlalu nyaman jika Anda bekerja dengan beberapa lingkungan / host karena Anda harus menyalin / membuatnya setiap waktu.

Solusi all-around yang lebih baik adalah menggunakan yolk3k , yang tersedia untuk diinstal dengan pip. Misalnya untuk melihat versi Django apa yang tersedia:

$ 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

yolk3kadalah fork dari yang asli yolkyang berhenti dikembangkan pada tahun 2012 . Meskipun yolktidak lagi dipertahankan (seperti yang ditunjukkan dalam komentar di bawah), yolk3ktampaknya dan mendukung Python 3.

Catatan: Saya tidak terlibat dalam pengembangan yolk3k. Jika sesuatu tampaknya tidak berfungsi sebagaimana mestinya, meninggalkan komentar di sini tidak akan membuat banyak perbedaan. Gunakan pelacak masalah yolk3k sebagai gantinya dan pertimbangkan untuk mengirimkan perbaikan, jika memungkinkan.

m000
sumber
4
Jawaban di bawah ini (menggunakan skrip dari pastebin) lebih rumit, tetapi paling tidak berfungsi dalam kasus saya (mencari versi dari scipy). yolk hanya menunjukkan versi terakhir yang tersedia, skrip lain menunjukkan semua versi yang berasal dari 0.8.0.
oligofren
30
Sebagian besar waktu itu hanya akan mengembalikan versi terbaru
PawelRoman
17
Fir python3 cukup gunakan pip install yolk3k. Perintah kuning akan tersedia.
Pierre Criulanscy
8
Seperti kuning telur, sebagian besar waktu yolk3k hanya mengembalikan versi terbaru.
diabloneo
4
kuning telur rusak / tidak lagi dipertahankan. hapus jawaban ini.
wim
835

Untuk pip> = 9.0 gunakan

$ 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==

- semua versi yang tersedia akan dicetak tanpa benar-benar mengunduh atau menginstal paket tambahan apa pun.

Untuk pip <9.0 digunakan

pip install pylibmc==blork

di mana blorkdapat berupa string apa pun yang bukan nomor versi yang valid .

Chris Montanaro
sumber
25
Saya merasa aneh bahwa kesalahan pip memuntahkan semua versi tetapi mereka tidak memiliki argumen untuk secara eksplisit mendapatkan data tersebut
Chris Montanaro
2
Properti bagus lain dari solusi ini adalah ia bekerja dengan semua flag normal untuk membatasi sumber instalasi. Sebagai contoh pip install --only-binary :all: pylibmcakan mencantumkan semua versi pylibmc yang tersedia sebagai paket biner.
pavon
3
pip install pylibmc==9999999 | tr ', ' "\n" | sort -n
Vikas
18
Ini harus ditandai sebagai jawaban yang benar karena tidak mengharuskan paket lain diinstal.
Yves Dorfsman
5
Agak konyol bahwa ini sepertinya satu-satunya cara untuk melakukan ini di pip. Saya harap setidaknya ada masalah terbuka tentang ini di pelacak bug mereka?
pmos
69

Pembaruan:
Pada Sep 2017 metode ini tidak lagi berfungsi: --no-installdihapus di pip 7

Gunakan pip install -v, Anda bisa melihat semua versi yang tersedia

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

Untuk tidak menginstal paket apa pun, gunakan salah satu solusi berikut:

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

atau

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

Diuji dengan pip 1.0

root@node7:~# pip --version
pip 1.0 from /usr/lib/python2.7/dist-packages (python 2.7)
HVNMencintai
sumber
9
pip 1.5.4memberi DEPRECATION: --no-install, --no-download, --build, and --no-clean are deprecated. See https://github.com/pypa/pip/issues/906.dan tidak menampilkan versi yang tersedia untuk paket yang sudah diinstal.
int_ua
2
untuk menampilkan semua versi, itu hanya perlu -v. Sisa jawaban saya adalah untuk menghindari efek tambahan (instal / unduh). Untuk pkg yang terinstal, cukup tambahkan --upgrade. Lalu, Anda dapat membuat virtualenv terpisah untuk membuat semuanya lebih sederhana.
HVNTweeting
2
pip 9.0.1 gonggongan:no such option: --no-install
tired_of_nitpickers
"versi terbaru:" dari -v mengecualikan beberapa versi.
mmacvicar
55

Anda tidak memerlukan paket pihak ketiga untuk mendapatkan informasi ini. pypi menyediakan umpan JSON sederhana untuk semua paket di bawah

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

Berikut adalah beberapa kode Python hanya menggunakan pustaka standar yang mendapatkan semua versi.

import json
import urllib2
from distutils.version import StrictVersion

def versions(package_name):
    url = "https://pypi.python.org/pypi/%s/json" % (package_name,)
    data = json.load(urllib2.urlopen(urllib2.Request(url)))
    versions = data["releases"].keys()
    versions.sort(key=StrictVersion)
    return versions

print "\n".join(versions("scikit-image"))

Kode itu dicetak (per 23 Februari 2015):

0.7.2
0.8.0
0.8.1
0.8.2
0.9.0
0.9.1
0.9.2
0.9.3
0.10.0
0.10.1
eric chiang
sumber
2
JSON memiliki jumlah sarang yang cukup. Saya dulu versions = [x for x in data["releases"] if any([y["python_version"] in ['cp26', '2.6'] for y in data["releases"][x]])]menemukan versi yang kompatibel dengan Python 2.6. (Saya tidak melihat di cp26mana pun, tetapi beberapa paket telah cp27jadi saya berspekulasi bahwa ini mungkin ada dalam paket lain.)
tripleee
2
Berikut adalah cara untuk melakukannya dengan curl, jq, dan urutkan ("satu-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
1
Ini melempar ValueErrorpengecualian untuk beberapa paket yang mengikuti skema versi yang tidak terlalu ketat. Untuk memperbaikinya untuk paket-paket ini, lihat inti ini .
TrinitronX
usang akan melakukan ini untuk Anda.
shadi
18

Saya datang dengan skrip bash sederhana-mati. Terima kasih kepada penulis jq .

#!/bin/bash
set -e

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

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

Pembaruan: Tambahkan pengurutan berdasarkan nomor versi.

Timofey Stolbov
sumber
Saya tidak dapat mulai curlbekerja, mungkin karena kesalahan sertifikat. wget --no-check-certificatebekerja, tetapi bahkan curl -k --insecuretidak menghasilkan apa-apa. Peringatan yang saya dapat dengan wgetmengatakanERROR: certificate common name `www.python.org´ doesn´t match requested host name `pypi.python.org´.
tripleee
Itu sort -Vtidak bekerja pada OSX dengan versi homebrewjq
deepelement
16

Anda bisa menggunakan paket yolk3k, bukan kuning telur. yolk3k adalah garpu dari kuning telur asli dan mendukung kedua python2 dan 3.

https://github.com/myint/yolk

pip install yolk3k
ykyuen
sumber
Ini berguna untuk diketahui, karena kuning telur tidak bekerja di bawah python 3.x
Broken Man
1
yolk3k hanya mengembalikan versi yang terinstal untuk saya:yolk -V attest Attest 0.5.3
Antony Hatchkins
2
yolk3k tampaknya hanya mengembalikan versi terbaru?
mvherweg
16

Setelah melihat kode pip untuk sementara waktu, sepertinya kode yang bertanggung jawab untuk menemukan paket dapat ditemukan di PackageFinderkelas di pip.index. Metodenya find_requirementmencari versi a InstallRequirement, tetapi sayangnya hanya mengembalikan versi terbaru.

Kode di bawah ini hampir merupakan salinan 1: 1 dari fungsi aslinya, dengan pengembalian dalam baris 114 diubah untuk mengembalikan semua versi.

Skrip mengharapkan satu nama paket sebagai argumen pertama dan satu-satunya dan mengembalikan semua versi.

http://pastebin.com/axzdUQhZ

Saya tidak dapat menjamin kebenarannya, karena saya tidak terbiasa dengan kode pip. Tapi semoga ini membantu.

Output sampel

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

Kode:

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]
Reiner Gerecke
sumber
Ini bekerja jauh lebih baik daripada jawaban di atas. skinny $ yolk -V scipy scipy 0.12.0 kurus $ python test.py scipy Versi 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
1
Penggunaan ini secara eksplisit tidak disarankan dalam dokumen : " Anda tidak boleh menggunakan API internal pip dengan cara ini "
wim
9

Anda dapat menggunakan skrip Python 3 kecil ini (hanya menggunakan modul perpustakaan standar) untuk mengambil daftar versi yang tersedia untuk paket dari PyPI menggunakan JSON API dan mencetaknya dalam urutan kronologis terbalik. Tidak seperti beberapa solusi lainnya Python diposting di sini, ini tidak putus versi longgar seperti django's 2.2rc1atau 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')

Simpan skrip dan jalankan dengan nama paket sebagai argumen, misalnya:

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
sumber
7

Ini berfungsi untuk saya di OSX:

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

Ini mengembalikan daftar satu per baris:

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

Atau untuk mendapatkan versi terbaru yang tersedia:

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

Perlu diingat gsortharus diinstal (pada OSX) untuk mengurai versi. Anda dapat menginstalnya denganbrew install coreutils

nenek
sumber
Astaga mengapa Anda bahkan memposting jawaban ini. Jawaban @Chris Montaro bekerja dan elegan. Ini hanya menimbulkan komplikasi yang tidak perlu
Brian Leach
@BrianLeach smh ... pendekatan yang sama difilter untuk digunakan dalam skrip ...
nenek
1
Bekerja di cygwin / bash untuk saya, untuk jenis solusi menggunakan kedua, bukan gsort di cygwin.
WebComer
Di sini python menghasilkan kode yang lebih mudah dibaca daripada bash ... lihat balasan @eric chiang (semoga :) di atas ...
mirekphd
4

Proyek saya ludditememiliki fitur ini.

Contoh penggunaan:

>>> 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')

Ini mencantumkan semua versi paket yang tersedia, dengan menanyakan API json https://pypi.org/

wim
sumber
Akan lebih instruktif jika Anda memberi tahu kami apa yang dilakukan paket Anda, jika tidak, Anda hanya mempromosikan perangkat lunak Anda :)
user228395
@ user228395 Saya pikir itu sudah cukup jelas, tetapi daftar semua versi dari paket yang tersedia, yang persis apa judul pertanyaan itu bertanya tentang. Diedit - lebih baik?
wim
Cara kerjanya tentu saja. Jadi pada dasarnya membungkus solusi yang disajikan oleh @Timofey Stolbov?
user228395
1
@ user228395 Saya tidak akan menyebutnya "pembungkus", karena jawaban itu menggunakan bash, curl, dan jq - sedangkan luddite hanya menggunakan pustaka standar Python (urllib). Tetapi solusi dari Stolbov tidak menggunakan titik akhir yang sama di pypi.org . Bolehkah saya bertanya apa alasan downvote Anda?
wim
1
Jika Anda mengikuti tautan ke halaman detail proyek, Anda dapat melihat bahwa fitur utama proyek adalah tentang memeriksa requirements.txtfile untuk paket-paket yang kedaluwarsa. Ini lebih dari beberapa baris kode. Untuk memeriksa requirements.txtfile, Anda memerlukan fungsionalitas untuk mendaftar semua versi paket. Bagian ini sengaja dipisahkan, dan bagian dari API publik luddite. Dan itu sumber Apache License 2.0, saya pikir itu tidak benar-benar adil untuk memanggil paket perangkat lunak "kotak hitam".
wim
2

Saya tidak beruntung yolk, yolk3katau pip install -vakhirnya saya menggunakan ini (disesuaikan dengan Python 3 dari jawaban eric chiang):

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
sumber
1
StrictVersiontidak akan bekerja untuk banyak paket ( django, uwsgi, psycopg2untuk beberapa nama). Anda dapat menggunakan parse_version()dari setuptools(lihat jawaban saya untuk contoh).
Eugene Yarmash
1

Solusi alternatif adalah dengan menggunakan API Gudang:

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

Misalnya untuk Flask:

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

akan dicetak:

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'])
Charlie
sumber
0

bashSkrip sederhana yang hanya bergantung pada pythondirinya sendiri (saya berasumsi bahwa dalam konteks pertanyaan itu harus diinstal) dan salah satu curlatau wget. Ini memiliki asumsi bahwa Anda memiliki setuptoolspaket yang diinstal untuk mengurutkan versi (hampir selalu diinstal). Itu tidak bergantung pada dependensi eksternal seperti:

  • jq yang mungkin tidak ada;
  • grepdan awkitu mungkin berperilaku berbeda di Linux dan 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)))"

Versi yang sedikit lebih panjang dengan komentar.

Masukkan nama paket ke dalam variabel:

PACKAGE=requests

Dapatkan versi (menggunakan 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)))")

Dapatkan versi (menggunakan 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)))")

Cetak versi yang diurutkan:

echo $VERSIONS
Andrey Semakin
sumber
-1

Pilihan saya adalah kombinasi dari beberapa jawaban yang diposting, dengan beberapa modifikasi untuk membuatnya lebih mudah digunakan dari dalam lingkungan python yang berjalan.

Idenya adalah untuk memberikan perintah yang sama sekali baru (dimodelkan setelah perintah instal) yang memberi Anda contoh dari pencari paket untuk digunakan. Sisi baiknya adalah ini berfungsi dengan, dan menggunakan, indeks apa pun yang didukung pip dan membaca file konfigurasi pip lokal Anda, sehingga Anda mendapatkan hasil yang benar seperti ketika Anda menginstal pip biasa.

Saya telah berupaya membuatnya kompatibel dengan pip v 9.x dan 10.x .. tetapi hanya mencobanya pada 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())

Contoh 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
Kaos
sumber
penggunaan ini secara eksplisit tidak disarankan dalam dokumen : " Anda tidak boleh menggunakan API internal pip dengan cara ini "
wim