pip-tools保持您的固定依赖项新鲜。
项目描述
pip-tools = pip-compile + pip-sync
一组命令行工具,帮助您保持基于pip的包新鲜,即使您已经固定了它们。您确实固定了它们,对吧?(在构建您的Python应用程序及其生产依赖项时,您希望确保您的构建可预测且确定。)
安装
类似于 pip
,pip-tools
必须安装在每个项目的 虚拟环境中
$ source /path/to/venv/bin/activate
(venv) $ python -m pip install pip-tools
注意:以下所有示例命令假设您已经激活了项目的虚拟环境。
pip-compile
的示例用法
pip-compile
命令可以让您从依赖关系中编译出 requirements.txt
文件,这些依赖关系在 pyproject.toml
、setup.cfg
、setup.py
或 requirements.in
中指定。
使用 pip-compile
或 python -m piptools compile
运行它(如果已安装 pipx
且使用适当的 Python 版本,也可以使用 pipx run --spec pip-tools pip-compile
)。如果您使用多个 Python 版本,还可以在 Windows 上运行 py -X.Y -m piptools compile
,在其他系统上运行 pythonX.Y -m piptools compile
。
pip-compile
应从与您的项目相同的虚拟环境中运行,以便条件依赖(需要特定 Python 版本或其他环境标记)相对于项目环境进行解析。
注意:如果 pip-compile
发现满足依赖关系的现有 requirements.txt
文件,则即使有更新也不会进行更改。要从头编译,首先删除现有的 requirements.txt
文件,或者查看更新依赖项的替代方法。
pyproject.toml
中的依赖项
pyproject.toml
文件是配置软件包和应用的最新标准标准,推荐用于新项目。pip-compile
支持安装您的 project.dependencies
以及 project.optional-dependencies
。由于这是一个官方标准,您可以使用 pip-compile
将使用现代标准符合打包工具(如 Setuptools、Hatch 或 flit)的项目中的依赖项锁定。
假设您有一个使用 Setuptools
打包的名为 'foobar' 的 Python 应用程序,并且您希望将其用于生产。您可以声明项目元数据如下
[build-system]
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"
[project]
requires-python = ">=3.9"
name = "foobar"
dynamic = ["dependencies", "optional-dependencies"]
[tool.setuptools.dynamic]
dependencies = { file = ["requirements.in"] }
optional-dependencies.test = { file = ["requirements-test.txt"] }
如果您有一个使用 Hatch
打包的 Django 应用程序,并且您希望将其用于生产。您还希望在一个单独的锁定文件中将开发工具锁定。您将 django
声明为依赖项,并创建一个包含 pytest
的可选依赖项 dev
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-cool-django-app"
version = "42"
dependencies = ["django"]
[project.optional-dependencies]
dev = ["pytest"]
您可以像这样轻松地生成您的锁定文件
$ pip-compile -o requirements.txt pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --output-file=requirements.txt pyproject.toml
#
asgiref==3.6.0
# via django
django==4.1.7
# via my-cool-django-app (pyproject.toml)
sqlparse==0.4.3
# via django
$ pip-compile --extra dev -o dev-requirements.txt pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --extra=dev --output-file=dev-requirements.txt pyproject.toml
#
asgiref==3.6.0
# via django
attrs==22.2.0
# via pytest
django==4.1.7
# via my-cool-django-app (pyproject.toml)
exceptiongroup==1.1.1
# via pytest
iniconfig==2.0.0
# via pytest
packaging==23.0
# via pytest
pluggy==1.0.0
# via pytest
pytest==7.2.2
# via my-cool-django-app (pyproject.toml)
sqlparse==0.4.3
# via django
tomli==2.0.1
# via pytest
这对于锁定您的应用程序,以及保持开源 Python 软件包的 CI 稳定性来说都是非常好的。
setup.py
和 setup.cfg
中的依赖项
pip-compile
也完全支持使用 setuptools
的基于 setup.py
和 setup.cfg
的项目。
只需像往常一样定义您的依赖项和额外功能,然后按照上述方式运行 pip-compile
。
requirements.in
中的依赖项
您还可以使用纯文本文件作为您的需求(例如,如果不想将应用程序打包)。要使用 requirements.in
文件声明 Django 依赖项
# requirements.in
django
现在,运行 pip-compile requirements.in
$ pip-compile requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile requirements.in
#
asgiref==3.6.0
# via django
django==4.1.7
# via -r requirements.in
sqlparse==0.4.3
# via django
它将生成您的 requirements.txt
,其中包含所有 Django 依赖项(以及所有底层依赖项)。
(updating-requirements)=
更新依赖项
pip-compile
使用满足您在支持文件中指定的依赖项的最新版本生成 requirements.txt
文件。
如果 pip-compile
发现满足依赖关系的现有 requirements.txt
文件,则即使有更新也不会进行更改。
要强制 pip-compile
更新现有的 requirements.txt
中的所有包,请运行 pip-compile --upgrade
。
要更新特定包到最新版本或指定版本,请使用 --upgrade-package
或 -P
标志。
# only update the django package
$ pip-compile --upgrade-package django
# update both the django and requests packages
$ pip-compile --upgrade-package django --upgrade-package requests
# update the django package to the latest, and requests to v2.0.0
$ pip-compile --upgrade-package django --upgrade-package requests==2.0.0
您可以在一个命令中同时使用 --upgrade
和 --upgrade-package
,以提供允许升级的约束。例如,要升级所有包,同时将 requests 的版本限制在 3.0 以下的新版本
$ pip-compile --upgrade --upgrade-package 'requests<3.0'
使用哈希值
如果您想使用从 8.0 版本开始可用的 pip
中的 哈希检查模式,pip-compile
提供了 --generate-hashes
标志。
$ pip-compile --generate-hashes requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --generate-hashes requirements.in
#
asgiref==3.6.0 \
--hash=sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac \
--hash=sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506
# via django
django==4.1.7 \
--hash=sha256:44f714b81c5f190d9d2ddad01a532fe502fa01c4cb8faf1d081f4264ed15dcd8 \
--hash=sha256:f2f431e75adc40039ace496ad3b9f17227022e8b11566f4b363da44c7e44761e
# via -r requirements.in
sqlparse==0.4.3 \
--hash=sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34 \
--hash=sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268
# via django
输出文件
要将固定要求输出到 requirements.txt
之外的文件名,请使用 --output-file
。这可能对编译多个文件很有用,例如,使用不同的约束条件对 django 进行测试,以测试同时使用两个版本的库tox
$ pip-compile --upgrade-package 'django<1.0' --output-file requirements-django0x.txt
$ pip-compile --upgrade-package 'django<2.0' --output-file requirements-django1x.txt
要输出到标准输出,请使用 --output-file=-
$ pip-compile --output-file=- > requirements.txt
$ pip-compile - --output-file=- < requirements.in > requirements.txt
将选项传递给 pip
可以使用 pip-compile
的 --pip-args
选项传递任何有效的 pip
标志或参数,例如。
$ pip-compile requirements.in --pip-args "--retries 10 --timeout 30"
配置
您可以通过将它们写入与要求输入文件相同的目录中的配置文件来定义 pip-compile
和 pip-sync
的项目级默认值(或从 stdin 管道输入时的当前工作目录)。默认情况下,pip-compile
和 pip-sync
将首先查找 .pip-tools.toml
文件,然后查找您的 pyproject.toml
文件。您还可以使用 --config
选项指定替代的 TOML 配置文件。
可以在全局范围内和特定命令中指定配置值。例如,要默认在结果要求文件输出中生成 pip
哈希,您可以在配置文件中指定。
[tool.pip-tools]
generate-hashes = true
在配置文件中,可能多次使用的 pip-compile
和 pip-sync
选项必须定义为列表,即使它们只有一个值。
pip-tools
支持其子命令所有有效命令行标志的默认值。配置键可以使用下划线而不是短横线,因此上述内容也可以按此格式指定。
[tool.pip-tools]
generate_hashes = true
针对 pip-compile
和 pip-sync
特定的配置默认值可以放在单独的部分下。例如,要默认使用 pip-compile
执行 dry-run
[tool.pip-tools.compile] # "sync" for pip-sync
dry-run = true
这不会影响具有相同名称的 pip-sync
命令,该命令也具有 --dry-run
选项。请注意,本地设置在声明时优先于同名的全局设置,因此这将使 pip-compile
生成哈希,但丢弃全局 dry-run 设置
[tool.pip-tools]
generate-hashes = true
dry-run = true
[tool.pip-tools.compile]
dry-run = false
您可能将 pip-compile
命令包装在其他脚本中。为了避免混淆您的自定义脚本的消费者,您可以通过设置 CUSTOM_COMPILE_COMMAND
环境变量来覆盖在要求文件顶部生成的更新命令。
$ CUSTOM_COMPILE_COMMAND="./pipcompilewrapper" pip-compile requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# ./pipcompilewrapper
#
asgiref==3.6.0
# via django
django==4.1.7
# via -r requirements.in
sqlparse==0.4.3
# via django
分层要求的流程
如果您需要为不同的环境安装不同但兼容的包,则可以创建分层要求文件并使用一个层来约束另一个层。
例如,如果您有一个 Django 项目,其中在生产环境中您想使用最新版本的 2.1
,而在开发时您想使用 Django 调试工具栏,那么您可以为每个层创建两个 *.in
文件。
# requirements.in
django<2.2
在开发要求 dev-requirements.in
的顶部,您使用 -c requirements.txt
将开发要求约束为在 requirements.txt
中已选择的用于生产的包。
# dev-requirements.in
-c requirements.txt
django-debug-toolbar<2.2
首先,像往常一样编译 requirements.txt
$ pip-compile
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile
#
django==2.1.15
# via -r requirements.in
pytz==2023.3
# via django
现在编译开发要求和 requirements.txt
文件被用作约束
$ pip-compile dev-requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile dev-requirements.in
#
django==2.1.15
# via
# -c requirements.txt
# django-debug-toolbar
django-debug-toolbar==2.1
# via -r dev-requirements.in
pytz==2023.3
# via
# -c requirements.txt
# django
sqlparse==0.4.3
# via django-debug-toolbar
如您所见,尽管 Django 的 2.2
版本可用,但开发要求只包括 Django 的 2.1
版本,因为它们受到约束。现在,这两个编译的要求文件都可以安全地安装在开发环境中。
要安装生产环境中的要求,请使用
$ pip-sync
您可以在开发阶段通过以下方式安装依赖项:
$ pip-sync requirements.txt dev-requirements.txt
版本控制集成
您可能想使用 pip-compile
作为 pre-commit 的钩子。请参阅 pre-commit 文档 以获取说明。示例 .pre-commit-config.yaml
repos:
- repo: https://github.com/jazzband/pip-tools
rev: 7.4.1
hooks:
- id: pip-compile
您可能想通过配置 args
和/或 files
来自定义 pip-compile
参数,例如
repos:
- repo: https://github.com/jazzband/pip-tools
rev: 7.4.1
hooks:
- id: pip-compile
files: ^requirements/production\.(in|txt)$
args: [--index-url=https://example.com, requirements/production.in]
如果您有多个依赖项文件,请确保为每个文件创建一个钩子。
repos:
- repo: https://github.com/jazzband/pip-tools
rev: 7.4.1
hooks:
- id: pip-compile
name: pip-compile setup.py
files: ^(setup\.py|requirements\.txt)$
- id: pip-compile
name: pip-compile requirements-dev.in
args: [requirements-dev.in]
files: ^requirements-dev\.(in|txt)$
- id: pip-compile
name: pip-compile requirements-lint.in
args: [requirements-lint.in]
files: ^requirements-lint\.(in|txt)$
- id: pip-compile
name: pip-compile requirements.in
args: [requirements.in]
files: ^requirements\.(in|txt)$
pip-sync
的示例用法
现在您有了 requirements.txt
,可以使用 pip-sync
更新虚拟环境,以反映其中的内容。这将安装/升级/卸载所有必要的软件包,以匹配 requirements.txt
的内容。
使用 pip-sync
或 python -m piptools sync
运行它。如果您使用多个 Python 版本,您还可以在 Windows 上运行 py -X.Y -m piptools sync
,在其他系统上运行 pythonX.Y -m piptools sync
。
pip-sync
必须安装到并与您的项目相同的虚拟环境一起运行,以便确定要安装或升级的软件包。
请注意:pip-sync
仅应与由 pip-compile
生成的 requirements.txt
一起使用。
$ pip-sync
Uninstalling flake8-2.4.1:
Successfully uninstalled flake8-2.4.1
Collecting click==4.1
Downloading click-4.1-py2.py3-none-any.whl (62kB)
100% |................................| 65kB 1.8MB/s
Found existing installation: click 4.0
Uninstalling click-4.0:
Successfully uninstalled click-4.0
Successfully installed click-4.1
要同步多个 *.txt
依赖项列表,只需通过命令行参数传入它们,例如
$ pip-sync dev-requirements.txt requirements.txt
传入空参数会导致默认为 requirements.txt
。
可以使用 pip-sync
的 --pip-args
选项传入任何有效的 pip install
标志或参数,例如
$ pip-sync requirements.txt --pip-args "--no-cache-dir --no-deps"
注意:pip-sync
不会升级或卸载像 setuptools
、pip
或 pip-tools
这样的打包工具。使用 python -m pip install --upgrade
升级这些软件包。
我应该将 requirements.in
和 requirements.txt
提交到源代码控制吗?
通常是的。如果您希望从源代码控制中提供可重复的环境安装,那么您应该将 requirements.in
和 requirements.txt
都提交到源代码控制。
请注意,如果您在多个 Python 环境上部署(请参阅下面的部分),则必须为每个 Python 环境提交一个单独的输出文件。我们建议使用 {env}-requirements.txt
格式(例如:win32-py3.7-requirements.txt
、macos-py3.10-requirements.txt
等)。
跨环境使用 requirements.in
/requirements.txt
和 pip-compile
软件包的依赖项可能会根据其安装的 Python 环境而变化。在这里,我们将 Python 环境定义为操作系统、Python 版本(3.7、3.8 等)和 Python 实现(CPython、PyPy 等)的组合。有关确切定义,请参阅 PEP 508 环境标记 的可能组合。
由于生成的 requirements.txt
可以根据每个环境而不同,因此用户必须分别在每个 Python 环境上执行 pip-compile
,以生成适用于每个环境的有效 requirements.txt
。可以使用 PEP 508 环境标记 作为需要的方式,将相同的 requirements.in
用作所有环境的源文件,就像为常规 pip
跨环境使用一样。
如果生成的 requirements.txt
对于所有 Python 环境都完全相同,则可以安全地在 Python 环境之间使用它。但是,用户应小心,因为任何软件包更新都可能引入环境相关的依赖项,使任何新生成的 requirements.txt
也变为环境相关。作为一般规则,建议用户仍然始终在每个目标 Python 环境上执行 pip-compile
以避免问题。
最大化可重复性
pip-tools
是一个很好的工具,可以提高构建的可重复性。但也有一些需要注意的事项。
- 如前所述,
pip-compile
将在不同的环境中产生不同的结果。 pip
必须与PIP_CONSTRAINT
环境变量一起使用,以锁定构建环境中的依赖项,如文档中所述 #8439。- 依赖项来自许多来源。
继续之前的 pyproject.toml
示例,创建单个锁文件可以像这样完成
$ pip-compile --all-build-deps --all-extras --output-file=constraints.txt --strip-extras pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.9
# by the following command:
#
# pip-compile --all-build-deps --all-extras --output-file=constraints.txt --strip-extras pyproject.toml
#
asgiref==3.5.2
# via django
attrs==22.1.0
# via pytest
backports-zoneinfo==0.2.1
# via django
django==4.1
# via my-cool-django-app (pyproject.toml)
editables==0.3
# via hatchling
hatchling==1.11.1
# via my-cool-django-app (pyproject.toml::build-system.requires)
iniconfig==1.1.1
# via pytest
packaging==21.3
# via
# hatchling
# pytest
pathspec==0.10.2
# via hatchling
pluggy==1.0.0
# via
# hatchling
# pytest
py==1.11.0
# via pytest
pyparsing==3.0.9
# via packaging
pytest==7.1.2
# via my-cool-django-app (pyproject.toml)
sqlparse==0.4.2
# via django
tomli==2.0.1
# via
# hatchling
# pytest
某些构建后端还可能使用 PEP 517 和 PEP 660 中描述的 get_requires_for_build_
钩子动态请求构建依赖项。这将在输出中用以下后缀之一表示
(pyproject.toml::build-system.backend::editable)
(pyproject.toml::build-system.backend::sdist)
(pyproject.toml::build-system.backend::wheel)
其他有用的工具
-
pip-compile-multi - 多交叉引用需求文件包装器。
-
pipdeptree 打印已安装包的依赖树。
-
requirements.in
/requirements.txt
语法高亮- 为 Vim 的 requirements.txt.vim。
- VS Code 的 Python 扩展。
- 为 Emacs 的 pip-requirements.el。
弃用
本节列出了当前已弃用的 pip-tools
功能。
- 在下一个主要版本中,
--allow-unsafe
行为将默认启用(https://github.com/jazzband/pip-tools/issues/989)。使用--no-allow-unsafe
以保留旧行为。建议现在传递--allow-unsafe
以适应即将到来的更改。 - 旧版解析器已弃用,将在未来版本中删除。新默认值是
--resolver=backtracking
。 - 在下一个主要版本中,
--strip-extras
行为将默认启用(https://github.com/jazzband/pip-tools/issues/1613)。使用--no-strip-extras
以保留旧行为。
关于解析器的说明
您可以选择默认回溯解析器或弃用的旧版解析器。
旧版解析器有时无法解析依赖项。回溯解析器更健壮,但通常运行时间更长。
您可以使用 --resolver=legacy
继续使用旧版解析器,尽管请注意它已弃用,并将在未来版本中删除。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪一个,请了解更多关于安装包的信息。