用于在PyPI世界中发现包依赖的工具和库
项目描述
在Thoth项目中使用的Python依赖关系求解器。
由于Python是一种动态编程语言,Thoth运行了多种类型的求解器,这些求解器在软件环境(操作系统、现有原生包、系统符号及其版本以及Python解释器版本)上有所不同。一个例子是一个在RHEL 8.0上运行Python 3.6的求解器,另一个例子是在安装了不同版本glibc以及操作系统提供的某些原生库的ABI符号的Fedora 33上运行的求解器(有关更多信息,请参阅Python的manylinux标准和devtools)。
查看Thoth中使用的构建求解器列表
有关详细解释,请参阅这篇博客文章:如何击败Python的pip:解决Python依赖项。
该求解器在不同的环境中(不同的操作系统以及提供的各种原生包)运行,以获取Python包的依赖信息。另一个重要信息是,给定的Python包是否可以在环境中安装(例如,原生包的依赖项存在于环境中)。一个例子是运行Python 3.8或使用gcc工具链为构建原生扩展构建的Python 3.6的UBI 8特定求解器。
项目范围
本项目的目的是回答一个简单的问题——对于提供的堆栈,将安装哪些包(由pip或任何Python兼容的依赖项解析器解析)?
假设您有一个应用程序只有一个依赖项
$ cat requirements.txt
tensorflow
本项目提供工具将告诉您在解析过程中会考虑哪些依赖项(整个依赖图)
thoth-solver -vvv pypi -r requirements.txt
该求解器的输出是给定软件堆栈的依赖项分析——在上面的例子中,对任何发布版本的包tensorflow及其所有依赖项(直接和间接依赖项)的分析,以及Python生态系统所需的其他信息,以便Python解析器执行实际的tensorflow解析。
该工具还允许指定符合PEP-503的自定义Python包索引——有关分析您提供的自定义Python包,请参阅--index选项。
还可以使用标准的Python版本范围说明符限制版本,或仅限制输出到直接依赖项。
产生的输出
除非指定了--no-transitive,否则该工具将递归地分析特定环境中所需包的所有依赖项。要分析的依赖项可以定义在类似于requirements.txt的文件中,或作为字符串以以下形式表示:
<package-name><version-cmp><version-identifier>
其中<package-name>是分析的包名称(例如,在PyPI上),部分<version-cmp><version-identifier>是可选的,并为给定的包创建版本说明符(如果没有指定,则考虑所有版本)。
以下示例输出可以通过运行以下参数的工具体现(以下为生成的日志示例)
$ thoth-solver python --requirements 'tensorflow==2.0.0' --index https://pypi.ac.cn/simple --no-transitive
2019-10-01 14:01:02,756 [31432] INFO root:128: Logging to a Sentry instance is turned off
2019-10-01 14:01:02,756 [31432] INFO root:150: Logging to rsyslog endpoint is turned off
2019-10-01 14:01:06,838 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'tensorflow==2.0.0'
2019-10-01 14:01:07,003 [31432] INFO thoth.solver.python.python:356: Using index 'https://pypi.ac.cn/simple' to discover package 'tensorflow' in version '2.0.0'
2019-10-01 14:01:40,568 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'absl-py' with range '>=0.7.0' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:40,568 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'absl-py>=0.7.0'
2019-10-01 14:01:40,689 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'astor' with range '>=0.6.0' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:40,689 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'astor>=0.6.0'
2019-10-01 14:01:40,841 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'gast' with range '==0.2.2' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:40,841 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'gast==0.2.2'
2019-10-01 14:01:40,984 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'google-pasta' with range '>=0.1.6' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:40,985 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'google-pasta>=0.1.6'
2019-10-01 14:01:41,104 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'keras-applications' with range '>=1.0.8' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:41,104 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'keras-applications>=1.0.8'
2019-10-01 14:01:41,273 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'keras-preprocessing' with range '>=1.0.5' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:41,274 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'keras-preprocessing>=1.0.5'
2019-10-01 14:01:41,443 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'numpy' with range '<2.0,>=1.16.0' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:41,443 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'numpy<2.0,>=1.16.0'
2019-10-01 14:01:41,723 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'opt-einsum' with range '>=2.3.2' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:41,723 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'opt-einsum>=2.3.2'
2019-10-01 14:01:41,828 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'six' with range '>=1.10.0' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:41,828 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'six>=1.10.0'
2019-10-01 14:01:41,942 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'protobuf' with range '>=3.6.1' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:41,943 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'protobuf>=3.6.1'
2019-10-01 14:01:42,095 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'tensorboard' with range '<2.1.0,>=2.0.0' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:42,095 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'tensorboard<2.1.0,>=2.0.0'
2019-10-01 14:01:42,286 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'tensorflow-estimator' with range '<2.1.0,>=2.0.0' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:42,287 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'tensorflow-estimator<2.1.0,>=2.0.0'
2019-10-01 14:01:42,411 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'termcolor' with range '>=1.1.0' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:42,411 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'termcolor>=1.1.0'
2019-10-01 14:01:42,580 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'wrapt' with range '>=1.11.1' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:42,581 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'wrapt>=1.11.1'
2019-10-01 14:01:42,693 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'grpcio' with range '>=1.8.6' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:42,693 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'grpcio>=1.8.6'
2019-10-01 14:01:43,007 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'wheel' with range '>=0.26' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:43,008 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'wheel>=0.26'
2019-10-01 14:01:43,116 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'backports-weakref' with range '>=1.0rc1' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:43,117 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'backports-weakref>=1.0rc1'
2019-10-01 14:01:43,262 [31432] INFO thoth.solver.python.python:405: Resolving dependency versions for 'enum34' with range '>=1.1.6' from 'https://pypi.ac.cn/simple'
2019-10-01 14:01:43,262 [31432] INFO thoth.solver.python.python_solver:113: Parsing dependency 'enum34>=1.1.6'
输出可能非常详细,以下部分描述了输出中一些最有趣的部分,使用JSONPath
.metadata - 分配给求解器运行的元数据——这些元数据在Thoth项目中特别有用,其中分析器在集群中运行,元数据的目的在于捕捉可能对集群中由于不同的容器环境(例如Python版本)而出现的问题进行调试有益的信息
.result - 该工具实际产生的结果
.result.unparsed - 一系列失败解析的需求(不遵守Python标准的错误依赖项规范)
.result.unresolved - 未解决的依赖项列表 - 失败的原因可能是例如包不存在或其版本在指定的Python包索引中不存在,或者例如包发行版与求解器软件环境(Python版本、环境标记等)不兼容,或者无效的发行版(例如,在包构建时由setup.py要求的发行版中遗忘的requirements.txt)。
.result.tree - 实际序列化的依赖树(Python生态系统中的循环依赖是可能的)
.result.tree[*].package_name - 分析的包的名称
.result.tree[*].package_version - 分析的包的版本
.result.tree[*].sha256 - 给定Python包索引中存在的artifacts的sha256摘要
.result.tree[*].importlib_metadata - 与给定包关联的元数据,这些元数据是通过使用importlib-metadata获得的,在Python 3.9+上回退到标准的importlib.metadata
.result.tree[*].importlib_metadata.metadata - 包元数据 - 有关更多信息,请参阅packaging文档
.result.tree[*].importlib_metadata.requires - 由importlib_metadata.requires获得的声明给定Python包需求的原始字符串
.result.tree[*].importlib_metadata.version - 由importlib_metadata.requires获得的版本
.result.tree[*].importlib_metadata.files - 给定包的文件信息(另外解析以提供摘要、文件大小和路径)由importlib_metadata.files获得
.result.tree[*].importlib_metadata.entry_points - 通过importlib_metadata.entry_points获得的入口点(另外解析以提供入口点名称、组和值)
{ "entry_points": [ { "group": "console_scripts", "name": "saved_model_cli", "value": "tensorflow.python.tools.saved_model_cli:main" }, { "group": "console_scripts", "name": "tensorboard", "value": "tensorboard.main:run_main" }, { "group": "console_scripts", "name": "tf_upgrade_v2", "value": "tensorflow.tools.compatibility.tf_upgrade_v2_main:main" }, { "group": "console_scripts", "name": "tflite_convert", "value": "tensorflow.lite.python.tflite_convert:main" }, { "group": "console_scripts", "name": "toco", "value": "tensorflow.lite.python.tflite_convert:main" }, { "group": "console_scripts", "name": "toco_from_protos", "value": "tensorflow.lite.toco.python.toco_from_protos:main" } ], "files": [ { "hash": { "mode": "sha256", "value": "47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU" }, "path": "tensorflow_core/tools/pip_package/__init__.py", "size": 0 } ], "metadata": { "Author": "Google Inc.", "Author-email": "packages@tensorflow.org", "Classifier": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Scientific/Engineering", "Topic :: Scientific/Engineering :: Mathematics", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Software Development", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules" ], "Download-URL": "https://github.com/tensorflow/tensorflow/tags", "Home-page": "https://tensorflowcn.cn/", "Keywords": "tensorflow tensor machine learning", "License": "Apache 2.0", "Metadata-Version": "2.1", "Name": "tensorflow", "Platform": [ "UNKNOWN" ], "Requires-Dist": [ "absl-py (>=0.7.0)", "astor (>=0.6.0)", "gast (==0.2.2)", "google-pasta (>=0.1.6)", "keras-applications (>=1.0.8)", "keras-preprocessing (>=1.0.5)", "numpy (<2.0,>=1.16.0)", "opt-einsum (>=2.3.2)", "six (>=1.10.0)", "protobuf (>=3.6.1)", "tensorboard (<2.1.0,>=2.0.0)", "tensorflow-estimator (<2.1.0,>=2.0.0)", "termcolor (>=1.1.0)", "wrapt (>=1.11.1)", "grpcio (>=1.8.6)", "wheel (>=0.26)", "backports.weakref (>=1.0rc1) ; python_version < \"3.4\"", "enum34 (>=1.1.6) ; python_version < \"3.4\"" ], "Summary": "TensorFlow is an open source machine learning framework for everyone.", "Version": "2.0.0" }, "requires": [ "absl-py (>=0.7.0)", "astor (>=0.6.0)", "gast (==0.2.2)", "google-pasta (>=0.1.6)", "keras-applications (>=1.0.8)", "keras-preprocessing (>=1.0.5)", "numpy (<2.0,>=1.16.0)", "opt-einsum (>=2.3.2)", "six (>=1.10.0)", "protobuf (>=3.6.1)", "tensorboard (<2.1.0,>=2.0.0)", "tensorflow-estimator (<2.1.0,>=2.0.0)", "termcolor (>=1.1.0)", "wrapt (>=1.11.1)", "grpcio (>=1.8.6)", "wheel (>=0.26)", "backports.weakref (>=1.0rc1) ; python_version < \"3.4\"", "enum34 (>=1.1.6) ; python_version < \"3.4\"" ], "version": "2.0.0" }
上述示例显示了与tensorflow==2.0.0关联的数据。有意的文件部分被截断,文件摘要按PEP-427中描述的方式签名。
.result.tree[*].dependencies - 可以根据分析包的需求规范解决的依赖项列表
.result.tree[*].dependencies[*].extras - 表示应使用PEP-508在extras部分中指定的extras安装给定包的额外名称
.result.tree[*].dependencies[*].extra - 表示应考虑此依赖项的额外名称,如PEP-508在extras部分中指定
.result.tree[*].dependencies[*].marker - 环境标记的完整规范,如PEP-508在环境标记部分中描述
.result.tree[*].dependencies[*].marker_evaluation_error - 在运行软件环境中标记评估失败时捕获错误信息的字符串,否则为null
.result.tree[*].dependencies[*].marker_evaluated - 由包定义的标记,但还调整了用于当前环境的评估(请参阅下面的说明)。
.result.tree[*].dependencies[*].marker_evaluation_result - 表示给定标记评估结果为真(给定环境接受标记)或假(标记不接受)的一个布尔值,特殊值 null 表示标记评估错误(有关更多信息,请参阅 marker_evaluation_error)
.result.tree[*].dependencies[*].normalized_package_name - 表示根据 PEP-503 中规范名称部分 描述的规范包名
.result.tree[*].dependencies[*].specifier - 表示符合 PEP-440 的依赖项声明的版本范围指定符
.result.tree[*].dependencies[*].resolved_versions - 根据版本范围指定符和指定的 Python 包索引(通过 --index 选项可以指定多个索引,这将导致在每个索引上进行包发现)解析出的版本列表
一个依赖项条目的示例(来自 .result.tree[*].dependencies 之一)
{
"extras": [],
"extra": [],
"marker": "python_version < \"3.4\"",
"marker_evaluated": "python_version < \"3.4\"",
"marker_evaluation_error": null,
"marker_evaluation_result": false,
"normalized_package_name": "backports-weakref",
"package_name": "backports.weakref",
"parsed_markers": [
{
"op": "<",
"value": "3.4",
"variable": "python_version"
}
],
"resolved_versions": [
{
"index": "https://pypi.ac.cn/simple",
"versions": [
"1.0rc1",
"1.0.post1"
]
}
],
"specifier": ">=1.0rc1"
}
为了在求解器环境中评估环境标记,需要调整标记,以便它可以在求解器环境中进行评估 - 请参阅 PEP-508 中环境标记部分 的规范,特别是以下部分
The "extra" variable is special. It is used by wheels to signal which
specifications apply to a given extra in the wheel METADATA file, but since
the METADATA file is based on a draft version of PEP-426, there is no current
specification for this. Regardless, outside of a context where this special
handling is taking place, the "extra" variable should result in an error like
all other unknown variables.
安装和部署
该项目也发布在 PyPI 上,因此可以通过 pip 或 Pipenv 安装最新版本
pipenv install thoth-solver
在 Thoth 项目 中运行求解器以收集有关包依赖信息。请检查 thoth-station/thoth-application 存储库中的部署和安装说明。
本地运行求解器
要本地运行求解器,首先克隆存储库并安装项目
git clone git@github.com:thoth-station/solver.git thoth-solver
cd thoth-solver
pipenv install --dev
PYTHONPATH='.' ./thoth-solver-cli --help
现在您可以运行求解器
pipenv run python3 ./thoth-solver --verbose python -r 'selinon==1.0.0' -i https://pypi.ac.cn/simple --no-transitive
项目详情
thoth-solver-1.10.2.tar.gz 的散列值
算法 | 散列摘要 | |
---|---|---|
SHA256 | 4c4d7ea40b526fb6df52512a2418d65bbd3c636350f7d41f0ab9995e9171577d |
|
MD5 | 84a627d857a5ec134876eab03554d1d5 |
|
BLAKE2b-256 | 74dd4e8afeab30f32badc8b41a7a05b9a599f477291beadfa9906e640571561c |