2013-03-29 209 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)) 

您可以使用递归调用依赖关系的依赖性来获得完整的树。干杯!