一組命令列工具可協助您讓基於pip
的套件保持最新狀態,即使您已固定它們也是如此。你確實把它們釘住了,對吧? (在建立 Python 應用程式及其生產依賴項時,您需要確保建置是可預測的和確定性的。)
與pip
類似, pip-tools
必須安裝在專案的每個虛擬環境中:
$ source /path/to/venv/bin/activate
(venv) $ python -m pip install pip-tools
注意:所有剩餘的範例命令都假設您已經啟動了專案的虛擬環境。
pip-compile
的用法範例pip-compile
指令可讓您從pyproject.toml
、 setup.cfg
、 setup.py
或requirements.in
中指定的依賴項編譯requirements.txt
檔。
使用pip-compile
或python -m piptools compile
運行它(或pipx run --spec pip-tools pip-compile
如果pipx
是使用適當的 Python 版本安裝的)。如果您使用多個Python版本,也可以在Windows上執行py -XY -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 應用程序,並且您希望將其固定用於生產。您還希望將開發工具固定在單獨的 pin 檔案中。您將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 " ]
您可以輕鬆產生 PIN 文件,如下所示:
$ 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 依賴項(以及所有底層依賴項)。
(更新需求)=
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
組合在一個命令中,以對允許的升級提供限制。例如,升級所有軟體包,同時將請求限制為低於 3.0 的最新版本:
$ pip-compile --upgrade --upgrade-package ' requests<3.0 '
如果您想使用pip
自 8.0 版本以來提供的雜湊檢查模式, 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
標誌或參數都可以透過pip-compile
的--pip-args
選項傳遞,例如
$ 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
執行試運行:
[ tool . pip-tools . compile ] # "sync" for pip-sync
dry-run = true
這不會影響pip-sync
指令,該指令也有一個--dry-run
選項。請注意,每當聲明兩者時,本地設定優先於同名的全域設置,因此這也會使pip-compile
產生哈希值,但丟棄全域試運行設定:
[ 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-config.yaml
:
repos :
- repo : https://github.com/jazzband/pip-tools
rev : 7.4.1
hooks :
- id : pip-compile
您可能希望透過配置args
和/或files
來自訂pip-compile
args,例如:
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 -XY -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 install
標誌或參數都可以透過pip-sync
的--pip-args
選項傳遞,例如
$ 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
和pip-compile
requirements.txt
跨環境使用套件的依賴關係可能會根據安裝它的 Python 環境而變化。在這裡,我們將Python環境定義為作業系統、Python版本(3.7、3.8等)和Python實作(CPython、PyPy等)的組合。有關準確的定義,請參閱 PEP 508 環境標記的可能組合。
由於每個環境產生的requirements.txt
可能不同,因此使用者必須分別在每個Python環境上執行pip-compile
以產生對每個所述環境有效的requirements.txt
。相同的requirements.in
可以用作所有環境的來源文件,根據需要使用 PEP 508 環境標記,與常規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 - 用於多個交叉引用需求檔案的 pip-compile 指令包裝器。
pipdeptree 列印已安裝軟體包的依賴關係樹。
requirements.in
requirements.txt
高亮:
本節列出了目前已棄用的pip-tools
功能。
--allow-unsafe
行為 (#989)。使用--no-allow-unsafe
保留舊行為。建議現在透過--allow-unsafe
來適應即將到來的變化。--resolver=backtracking
。--strip-extras
行為將預設為啟用(#1613)。使用--no-strip-extras
來保留舊的行為。您可以選擇預設回溯解析器或已棄用的舊版解析器。
舊版解析器有時會無法解析依賴項。回溯解析器更強大,但通常需要更長的時間來運行。
您可以繼續使用帶有--resolver=legacy
的舊解析器,但請注意它已被棄用並將在未來版本中刪除。