Python包依赖树

22

我希望分析Python包的依赖关系树。如何获取这些数据?

我已经知道的事情:

  1. setup.py有时会包含一个requires字段,其中列出了软件包的依赖关系
  2. PyPi是Python包的在线存储库
  3. PyPi有一个API

我不知道的事情:

  1. 在PyPi上,很少有项目(约10%)明确列出requires字段中的依赖项,但pip / easy_install仍然可以正确下载软件包。 我错过了什么?例如,用于统计计算的流行库pandas没有列出requires,但仍然安装numpypytz等… 是否有更好的方法自动收集完整的依赖项列表?
  2. 是否存在预先存在的数据库? 我是否在重复现有工作?
  3. 是否存在类似的、易于访问的、用于其他语言的分布式系统(R、Clojure等)的数据库?

你的问题实际上太宽泛了。不要在一个帖子中提出太多问题,保持实用性和可回答性。你的第三点会引发辩论和购物清单,而不是具体的答案。 - Martijn Pieters
3个回答

19
你应该查看install_requires字段,而不是使用requires。请参见新的和已更改的setup关键字
因为requires字段太过笼统,不能依赖它来进行依赖项安装。此外,还有setup_requirestest_requires字段用于依赖于setup.py和运行测试所需的依赖项。
当然,依赖图早就被分析过了。这篇Olivier Girardot博客文章中包含了一张很棒的图片: PyPI dependencies
该图像链接到互动版本的图表。

5
好的,这确实是一张非常漂亮的图表! - Martijn Pieters
2
那张图太棒了。 - Will
4
虽然这张图很漂亮,但我不懂如何读取它。 - duozmo
还有requires_dist,我可以在json api中看到:https://pypi.python.org/pypi/Django/json像cryptography这样的包使用`install_requires',但该信息不在api中:https://pypi.python.org/pypi/cryptography/json - radtek

1
使用类似 pip 的工具,您可以列出每个软件包的所有要求。
命令为:
pip install --no-install package_name

你可以在脚本中重复使用pip的一部分。负责解析要求的部分是pip.req模块。


2
我喜欢在Python中使用pip的想法。如果我已经安装了该软件包,则命令行界面会失败。我如何直接使用Python代码查找特定软件包的依赖项? - MRocklin
5
“--no-install”已经过时。 - Chris Martin

1

以下是如何使用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))

你可以使用递归调用依赖关系的依赖关系来获取完整的树形结构。干杯!

我使用了这个一行命令从PyPI API获取信息:PKG=requests; curl -L "https://pypi.python.org/pypi/${PKG}/json" | jq '.info | {requires_dist, requires, setup_requires, test_requires, install_requires}' 显然,将PKG更改为您想要查找的内容。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接