2013-03-29 111 views
21

我想分析一下Python包的依賴關係樹。我如何獲得這些數據?Python包依賴關係樹

事情我已經知道了

  1. setup.py有時含有requires場,列出軟件包的依賴
  2. 的PyPI是Python包的在線存儲庫
  3. PyPI將有一個API

的事情,我不知道

  1. PyPi上很少有項目(約10%)明確列出requires字段中的依賴項,但pip/easy_install仍然設法下載正確的程序包。我錯過了什麼?例如,流行的統計計算庫pandas未列出requires,但仍設法安裝numpy,pytz等....有沒有更好的方法來自動收集完整的依賴關係列表?
  2. 某處是否有預先存在的數據庫?我是否重複現有的工作?
  3. 做類似的,交通方便,與配電系統(R,Clojure的,等等?)其他語言
+0

你的問題,實際上太寬泛了。不要在帖子中提出太多問題,並保持實用性和可回答性。你的觀點3.邀請辯論和購物清單,而不是具體的答案。 –

回答

18

你應該看install_requires代替,看到New and changed setup keywords存在數據庫。

requires被視爲過於模糊依賴安裝依賴的字段。另外,setup.py所需的依賴關係還有運行測試的setup_requirestest_requires字段。

當然,之前已經分析了依賴關係圖;從這個blog article by Olivier Girardot談到這個夢幻般的形象:

PyPI dependencies
的圖像鏈接到圖形的交互式版本。

+1

thx恭維:p –

+4

那麼,它*是一個非常漂亮的圖! –

+1

這張圖令人難以置信。 – Will

2

使用像pip這樣的工具,您可以列出每個軟件包的所有需求。

的命令是:

pip install --no-install package_name 

您可以在腳本中重複使用PIP的一部分。負責解析需求的部分是模塊pip.req

+2

我喜歡在Python中使用'pip'的想法。如果我已經安裝了該軟件包,命令行界面將失敗。我如何直接使用Python代碼來查找特定包的依賴關係? – MRocklin

+1

'--no-install'已棄用。 –

0

下面是如何可以通過編程使用python pip包做到這一點:

from pip._vendor import pkg_resources # Ensure pip conf index-url pointed to real PyPi Index 

# Get dependencies from pip 
package_name = 'Django' 
try: 
    package_resources = pkg_resources.working_set.by_key[package_name.lower()] # Throws KeyError if not found 
    dependencies = package_resources._dep_map.keys() + ([str(r) for r in package_resources.requires()]) 
    dependencies = list(set(dependencies)) 
except KeyError: 
    dependencies = [] 

這裏是你如何可以從PyPI將API得到的依賴關係:

import requests 
import json 
package_name = 'Django' 
# Package info url 
PYPI_API_URL = 'https://pypi.python.org/pypi/{package_name}/json' 
package_details_url = PYPI_API_URL.format(package_name=package_name) 
response = requests.get(package_details_url) 
data = json.loads(response.content) 
if response.status_code == 200: 
    dependencies = data['info'].get('requires_dist') 
    dependencies2 = data['info'].get('requires') 
    dependencies3 = data['info'].get('setup_requires') 
    dependencies4 = data['info'].get('test_requires') 
    dependencies5 = data['info'].get('install_requires') 
    if dependencies2: 
     dependencies.extend(dependencies2) 
    if dependencies3: 
     dependencies.extend(dependencies3) 
    if dependencies4: 
     dependencies.extend(dependencies4) 
    if dependencies5: 
     dependencies.extend(dependencies5) 
    dependencies = list(set(dependencies)) 

您可以使用遞歸調用依賴關係的依賴性來獲得完整的樹。乾杯!