跳转到主要内容

pip-tools保持您的固定依赖项新鲜。

项目描述

jazzband-image pypi pyversions pre-commit buildstatus-gha codecov Matrix Room Badge Matrix Space Badge discord-chat-image

pip-tools = pip-compile + pip-sync

一组命令行工具,帮助您保持基于pip的包新鲜,即使您已经固定了它们。您确实固定了它们,对吧?(在构建您的Python应用程序及其生产依赖项时,您希望确保您的构建可预测且确定。)

pip-tools overview for phase II

安装

类似于 pippip-tools 必须安装在每个项目的 虚拟环境中

$ source /path/to/venv/bin/activate
(venv) $ python -m pip install pip-tools

注意:以下所有示例命令假设您已经激活了项目的虚拟环境。

pip-compile 的示例用法

pip-compile 命令可以让您从依赖关系中编译出 requirements.txt 文件,这些依赖关系在 pyproject.tomlsetup.cfgsetup.pyrequirements.in 中指定。

使用 pip-compilepython -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 将使用现代标准符合打包工具(如 SetuptoolsHatchflit)的项目中的依赖项锁定。

假设您有一个使用 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.pysetup.cfg 中的依赖项

pip-compile 也完全支持使用 setuptools 的基于 setup.pysetup.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-compilepip-sync 的项目级默认值(或从 stdin 管道输入时的当前工作目录)。默认情况下,pip-compilepip-sync 将首先查找 .pip-tools.toml 文件,然后查找您的 pyproject.toml 文件。您还可以使用 --config 选项指定替代的 TOML 配置文件。

可以在全局范围内和特定命令中指定配置值。例如,要默认在结果要求文件输出中生成 pip 哈希,您可以在配置文件中指定。

[tool.pip-tools]
generate-hashes = true

在配置文件中,可能多次使用的 pip-compilepip-sync 选项必须定义为列表,即使它们只有一个值。

pip-tools 支持其子命令所有有效命令行标志的默认值。配置键可以使用下划线而不是短横线,因此上述内容也可以按此格式指定。

[tool.pip-tools]
generate_hashes = true

针对 pip-compilepip-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-syncpython -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 不会升级或卸载像 setuptoolspippip-tools 这样的打包工具。使用 python -m pip install --upgrade 升级这些软件包。

我应该将 requirements.inrequirements.txt 提交到源代码控制吗?

通常是的。如果您希望从源代码控制中提供可重复的环境安装,那么您应该将 requirements.inrequirements.txt 都提交到源代码控制。

请注意,如果您在多个 Python 环境上部署(请参阅下面的部分),则必须为每个 Python 环境提交一个单独的输出文件。我们建议使用 {env}-requirements.txt 格式(例如:win32-py3.7-requirements.txtmacos-py3.10-requirements.txt 等)。

跨环境使用 requirements.in/requirements.txtpip-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 517PEP 660 中描述的 get_requires_for_build_ 钩子动态请求构建依赖项。这将在输出中用以下后缀之一表示

  • (pyproject.toml::build-system.backend::editable)
  • (pyproject.toml::build-system.backend::sdist)
  • (pyproject.toml::build-system.backend::wheel)

其他有用的工具

弃用

本节列出了当前已弃用的 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 继续使用旧版解析器,尽管请注意它已弃用,并将在未来版本中删除。

项目详情


发布历史 发布通知 | RSS 源

下载文件

下载适用于您平台的文件。如果您不确定选择哪一个,请了解更多关于安装包的信息。

源代码发行版

pip-tools-7.4.1.tar.gz (145.4 kB 查看哈希值)

上传时间 源代码

构建发行版

pip_tools-7.4.1-py3-none-any.whl (61.2 kB 查看哈希值)

上传时间 Python 3

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面