Bagaimana menemukan dependensi paket Python

106

Bagaimana Anda bisa secara terprogram mendapatkan daftar dependensi paket Python?

Standar setup.pytelah mendokumentasikannya, tetapi saya tidak dapat menemukan cara mudah untuk mengaksesnya dari Python atau baris perintah.

Idealnya, saya mencari sesuatu seperti:

$ pip install somepackage --only-list-deps
kombu>=3.0.8
billiard>=3.3.0.13
boto>=2.26

atau:

>>> import package_deps
>>> package = package_deps.find('somepackage')
>>> print package.dependencies
['kombu>=3.0.8', 'billiard>=3.3.0.13', 'boto>=2.26']

Catatan, saya tidak berbicara tentang mengimpor paket dan menemukan semua modul yang direferensikan. Meskipun ini mungkin menemukan sebagian besar paket dependen, ini tidak akan dapat menemukan nomor versi minimum yang diperlukan. Itu hanya disimpan di setup.py.

Cerin
sumber
Beberapa jawaban di sini menunjukkan bahwa pip diimpor untuk digunakan dalam program. The dokumentasi untuk pip sangat menyarankan terhadap penggunaan ini dari pip. Sesuatu yang perlu diingat jika ada solusi ini yang digunakan untuk sesuatu yang penting.
Jordan Mackie

Jawaban:

97

Selain pip show [package name]perintah, ada pipdeptree.

Kerjakan saja

$ pip install pipdeptree

lalu lari

$ pipdeptree

dan itu akan menunjukkan ketergantungan Anda dalam bentuk pohon, misalnya,

flake8==2.5.0
  - mccabe [required: >=0.2.1,<0.4, installed: 0.3.1]
  - pep8 [required: !=1.6.0,>=1.5.7,!=1.6.1,!=1.6.2, installed: 1.5.7]
  - pyflakes [required: >=0.8.1,<1.1, installed: 1.0.0]
ipdb==0.8
  - ipython [required: >=0.10, installed: 1.1.0]

Proyek ini berlokasi di https://github.com/naiquevin/pipdeptree , di mana Anda juga akan menemukan informasi penggunaan.

beruic
sumber
7
pipdeptreemenunjukkan dependensi dari semua paket yang diinstal , tidak hanya paket yang diberikan. Meskipun Anda dapat memfilter --jsonkeluarannya, itu masih tergantung pada paket yang akan diinstal.
sschuberth
Benar, tetapi jawabannya masih berguna ketika Anda ingin mengetahui mengapa paket-paket yang tidak ada di dalam paket diinstal requirements.txt:)
beruic
3
Selain itu, Anda dapat menggunakan -popsi untuk hanya memilih beberapa paket yang dependensinya ingin Anda jelajahi.
Zaccharie Ramzi
2
pipdeptreesangat membantu saat mengoptimalkan requirements.txt. $ pipdeptree | grep -P '^\w+' Ini hanya menghasilkan paket tingkat atas. Info lebih lanjut di sini
Pengembang
64

Coba gunakan showperintah di pip, misalnya:

$ pip show tornado
---
Name: tornado
Version: 4.1
Location: *****
Requires: certifi, backports.ssl-match-hostname

Perbarui (ambil deps dengan versi yang ditentukan):

from pip._vendor import pkg_resources


_package_name = 'somepackage'
_package = pkg_resources.working_set.by_key[_package_name]

print([str(r) for r in _package.requires()])  # retrieve deps from setup.py

Output: ['kombu>=3.0.8', 
         'billiard>=3.3.0.13', 
         'boto>=2.26']
Alex Lisovoy
sumber
1
Itu memberitahu Anda versi paket , bukan ketergantungannya ; mereka baru saja terdaftar.
jonrsharpe
Lihat Requiresbagian
Alex Lisovoy
3
Ya, tetapi itu tidak menunjukkan "nomor versi minimum yang diperlukan" , karena OP mensyaratkan:
jonrsharpe
1
Entah bagaimana $ pip3 show beautifulsoup4acara kosong Requires: untuk saya - bukankah beautifulsoup4 bergantung pada apa pun?
xealits
4
@PythonJin, ya, ternyata hanya menggunakan paket standar .. Saya hanya sedikit terkejut dengan itu. Selamat beautifulsoup4,.
xealits
6

Beberapa jawaban di sini menunjukkan pip diimpor untuk digunakan dalam program. The dokumentasi untuk pip sangat menyarankan terhadap penggunaan ini dari pip .

Alih-alih mengakses pkg_resourcesmelalui impor pip, Anda sebenarnya dapat mengimpor pkg_resourcessecara langsung dan menggunakan logika yang sama (yang sebenarnya merupakan salah satu solusi yang disarankan dalam dokumen pip yang ditautkan untuk siapa saja yang ingin melihat informasi meta paket secara terprogram).

import pkg_resources

_package_name = 'yourpackagename'

def get_dependencies_with_semver_string():
    package = pkg_resources.working_set.by_key[_package_name]
    return [str(r) for r in package.requires()]

Jika Anda mengalami kesulitan mencari tahu persis apa nama paket Anda, WorkingSetcontoh dikembalikan oleh pkg_resources.working_setimplements__iter__ sehingga Anda dapat mencetak semuanya dan mudah-mudahan melihat milik Anda di sana :)

yaitu

import pkg_resources

def print_all_in_working_set():
    ws = pkg_resources.working_set
    for package_name in ws:
        print(ws)

Ini berfungsi dengan python 2 dan 3 (meskipun Anda harus menyesuaikan pernyataan cetak untuk python2)

Jordan Mackie
sumber
3

(INI ADALAH JAWABAN LEGACY DAN HARUS DIHINDARI UNTUK VERSI PIP MODERN DAN KIRI DI SINI UNTUK REFERENSI KE VERSI PIP LAMA) Jawaban Alex bagus (+1). Dengan python:

pip._vendor.pkg_resources.working_set.by_key['twisted'].requires()

harus mengembalikan sesuatu seperti

[Requirement.parse('zope.interface>=3.6.0')]

di mana twisted adalah nama paketnya, yang dapat Anda temukan di kamus:

pip._vendor.pkg_resources.WorkingSet().entry_keys

untuk mencantumkan semuanya:

dict = pip._vendor.pkg_resources.WorkingSet().entry_keys
for key in dict:
    for name in dict[key]:
        req =pip._vendor.pkg_resources.working_set.by_key[name].requires()
        print('pkg {} from {} requires {}'.format(name,
                                                  key,
                                                  req))

harus memberi Anda daftar seperti ini:

pkg pyobjc-framework-syncservices from /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC requires [Requirement.parse('pyobjc-core>=2.5.1'), Requirement.parse('pyobjc-framework-Cocoa>=2.5.1'), Requirement.parse('pyobjc-framework-CoreData>=2.5.1')]
cgseller
sumber
Apakah ada yang berubah di versi terbaru? The _vendoratribut tampaknya tidak ada di versi pip 19.1.1(Edit: Baiklah, tampaknya telah pindah ke pkg_resourcespaket dalam versi python terbaru!)
Prahlad Yeri
Ya, banyak hal telah berubah, dan saya akan melihat baik memperbarui ini atau menghapusnya demi rekomendasi di bawah.
cgseller
Jawaban Alex hanya sebagian lebih baik dari sudut pandang saya (baik pip showsebagian, bukan yang lain). Baik menggunakan pip show, pipdeptree atau melihat jawaban Jordan Mackie menggunakan setuptools ' pkg_resourceslangsung.
sinoroc
2

Gunakan https://libraries.io/ . Ini adalah tempat yang baik untuk menjelajahi dependensi sebelum menginstal menggunakan pip.

Misalnya. Ketik google-cloud-storage dan cari, lalu Anda dapat menemukan halaman perpustakaan ( https://libraries.io/rubygems/google-cloud-storage ). Pilih versi yang ingin Anda jelajahi dependensinya dari 'Rilis' (defaultnya adalah yang terbaru), Di bawah 'Dependencies' Anda dapat menemukan daftar dependensi dan versi yang didukungnya.

Praboda
sumber
1

Coba ini menurut artikel ini di python:

import pip 
installed_packages = pip.get_installed_distributions()
installed_packages_list = sorted(["%s==%s" % (i.key, i.version)
     for i in installed_packages]) 
print(installed_packages_list)

Ini akan menunjukkan seperti:

['behave==1.2.4', 'enum34==1.0', 'flask==0.10.1', 'itsdangerous==0.24', 
 'jinja2==2.7.2', 'jsonschema==2.3.0', 'markupsafe==0.23', 'nose==1.3.3', 
 'parse-type==0.3.4', 'parse==1.6.4', 'prettytable==0.7.2', 'requests==2.3.0',
 'six==1.6.1', 'vioozer-metadata==0.1', 'vioozer-users-server==0.1', 
 'werkzeug==0.9.4']
EniGma
sumber