Eine Reihe von Befehlszeilentools, die Ihnen helfen, Ihre pip
-basierten Pakete aktuell zu halten, auch wenn Sie sie angeheftet haben. Du pinnst sie doch, oder? (Beim Erstellen Ihrer Python-Anwendung und ihrer Abhängigkeiten für die Produktion möchten Sie sicherstellen, dass Ihre Builds vorhersehbar und deterministisch sind.)
Ähnlich wie pip
müssen pip-tools
in jeder virtuellen Umgebung Ihres Projekts installiert werden:
$ source /path/to/venv/bin/activate
(venv) $ python -m pip install pip-tools
Hinweis : Bei allen verbleibenden Beispielbefehlen wird davon ausgegangen, dass Sie die virtuelle Umgebung Ihres Projekts aktiviert haben.
pip-compile
Mit dem Befehl pip-compile
können Sie eine Datei requirements.txt
aus Ihren Abhängigkeiten kompilieren, die entweder in pyproject.toml
, setup.cfg
, setup.py
oder requirements.in
angegeben sind.
Führen Sie es mit pip-compile
oder python -m piptools compile
(oder pipx run --spec pip-tools pip-compile
wenn pipx
mit der entsprechenden Python-Version installiert wurde). Wenn Sie mehrere Python-Versionen verwenden, können Sie auch py -XY -m piptools compile
unter Windows und pythonX.Y -m piptools compile
auf anderen Systemen ausführen.
pip-compile
sollte in derselben virtuellen Umgebung wie Ihr Projekt ausgeführt werden, damit bedingte Abhängigkeiten, die eine bestimmte Python-Version oder andere Umgebungsmarkierungen erfordern, relativ zur Umgebung Ihres Projekts aufgelöst werden.
Hinweis : Wenn pip-compile
eine vorhandene Datei requirements.txt
findet, die die Abhängigkeiten erfüllt, werden keine Änderungen vorgenommen, auch wenn Updates verfügbar sind. Um von Grund auf zu kompilieren, löschen Sie zunächst die vorhandene Datei requirements.txt
oder lesen Sie „Anforderungen aktualisieren“ für alternative Ansätze.
pyproject.toml
Die Datei pyproject.toml
ist der neueste Standard zum Konfigurieren von Paketen und Anwendungen und wird für neue Projekte empfohlen. pip-compile
unterstützt sowohl die Installation Ihrer project.dependencies
als auch Ihrer project.optional-dependencies
. Da es sich um einen offiziellen Standard handelt, können Sie pip-compile
verwenden, um die Abhängigkeiten in Projekten zu fixieren, die moderne standardkonforme Paketierungstools wie Setuptools, Hatch oder Flit verwenden.
Angenommen, Sie haben eine „foobar“-Python-Anwendung, die mit Setuptools
gepackt wurde, und möchten sie für die Produktion anheften. Sie können die Projektmetadaten wie folgt deklarieren:
[ 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 " ] }
Wenn Sie eine Django-Anwendung haben, die mit Hatch
gepackt wurde, und diese für die Produktion anheften möchten. Sie möchten Ihre Entwicklungstools auch in einer separaten Pin-Datei anheften. Sie deklarieren django
als Abhängigkeit und erstellen eine optionale dev
, die pytest
enthält:
[ build-system ]
requires = [ " hatchling " ]
build-backend = " hatchling.build "
[ project ]
name = " my-cool-django-app "
version = " 42 "
dependencies = [ " django " ]
[ project . optional-dependencies ]
dev = [ " pytest " ]
Sie können Ihre Pin-Dateien so einfach erstellen wie:
$ 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
Dies eignet sich hervorragend zum Fixieren Ihrer Anwendungen, aber auch, um die CI Ihres Open-Source-Python-Pakets stabil zu halten.
setup.py
und setup.cfg
pip-compile
bietet außerdem volle Unterstützung für setup.py
und setup.cfg
-basierte Projekte, die setuptools
verwenden.
Definieren Sie einfach wie gewohnt Ihre Abhängigkeiten und Extras und führen Sie pip-compile
wie oben aus.
requirements.in
Sie können für Ihre Anforderungen auch reine Textdateien verwenden (z. B. wenn Sie nicht möchten, dass Ihre Anwendung ein Paket ist). So verwenden Sie eine Datei requirements.in
zum Deklarieren der Django-Abhängigkeit:
# requirements.in
django
Führen Sie nun pip-compile requirements.in
aus:
$ 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
Und es wird Ihre requirements.txt
mit allen Django-Abhängigkeiten (und allen zugrunde liegenden Abhängigkeiten) erstellen.
(Aktualisierungsanforderungen)=
pip-compile
generiert eine Datei requirements.txt
unter Verwendung der neuesten Versionen, die die von Ihnen in den unterstützten Dateien angegebenen Abhängigkeiten erfüllen.
Wenn pip-compile
eine vorhandene Datei requirements.txt
findet, die die Abhängigkeiten erfüllt, werden keine Änderungen vorgenommen, auch wenn Updates verfügbar sind.
Um pip-compile
zu zwingen, alle Pakete in einer vorhandenen requirements.txt
zu aktualisieren, führen Sie pip-compile --upgrade
aus.
Um ein bestimmtes Paket auf die neueste Version oder eine bestimmte Version zu aktualisieren, verwenden Sie das Flag --upgrade-package
oder -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
Sie können --upgrade
und --upgrade-package
in einem Befehl kombinieren, um Einschränkungen für die zulässigen Upgrades festzulegen. Um beispielsweise alle Pakete zu aktualisieren und gleichzeitig Anfragen auf die neueste Version unter 3.0 zu beschränken:
$ pip-compile --upgrade --upgrade-package ' requests<3.0 '
Wenn Sie den seit Version 8.0 in pip
verfügbaren Hash-Checking-Modus verwenden möchten, bietet pip-compile
das Flag --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
Um die angehefteten Anforderungen in einem anderen Dateinamen als requirements.txt
auszugeben, verwenden Sie --output-file
. Dies kann zum Kompilieren mehrerer Dateien nützlich sein, beispielsweise mit unterschiedlichen Einschränkungen für Django, um eine Bibliothek mit beiden Versionen mithilfe von tox zu testen:
$ pip-compile --upgrade-package ' django<1.0 ' --output-file requirements-django0x.txt
$ pip-compile --upgrade-package ' django<2.0 ' --output-file requirements-django1x.txt
Oder verwenden Sie zur Ausgabe in die Standardausgabe --output-file=-
:
$ pip-compile --output-file=- > requirements.txt
$ pip-compile - --output-file=- < requirements.in > requirements.txt
pip
Alle gültigen pip
Flags oder Argumente können mit der Option --pip-args
von pip-compile
übergeben werden, z
$ pip-compile requirements.in --pip-args " --retries 10 --timeout 30 "
Sie können Standardeinstellungen auf Projektebene für pip-compile
und pip-sync
definieren, indem Sie sie in eine Konfigurationsdatei im selben Verzeichnis wie Ihre Anforderungseingabedateien schreiben (oder im aktuellen Arbeitsverzeichnis, wenn Eingaben von stdin weitergeleitet werden). Standardmäßig suchen sowohl pip-compile
als auch pip-sync
zuerst nach einer .pip-tools.toml
Datei und dann in Ihrer pyproject.toml
. Sie können auch eine alternative TOML-Konfigurationsdatei mit der Option --config
angeben.
Es ist möglich, Konfigurationswerte sowohl global als auch befehlsspezifisch anzugeben. Um beispielsweise standardmäßig pip
Hashes in der resultierenden Anforderungsdateiausgabe zu generieren, können Sie in einer Konfigurationsdatei Folgendes angeben:
[ tool . pip-tools ]
generate-hashes = true
Optionen für pip-compile
und pip-sync
die mehr als einmal verwendet werden können, müssen als Listen in einer Konfigurationsdatei definiert werden, auch wenn sie nur einen Wert haben.
pip-tools
unterstützt Standardwerte für alle gültigen Befehlszeilen-Flags seiner Unterbefehle. Konfigurationsschlüssel können Unterstriche anstelle von Bindestrichen enthalten, daher könnte das Obige auch in diesem Format angegeben werden:
[ tool . pip-tools ]
generate_hashes = true
Spezifische Konfigurationsstandards für pip-compile
und pip-sync
können in separaten Abschnitten abgelegt werden. Um beispielsweise standardmäßig einen Probelauf mit pip-compile
durchzuführen:
[ tool . pip-tools . compile ] # "sync" for pip-sync
dry-run = true
Dies hat keine Auswirkungen auf den Befehl pip-sync
, der auch über die Option --dry-run
verfügt. Beachten Sie, dass lokale Einstellungen Vorrang vor den globalen Einstellungen mit demselben Namen haben, wenn beide deklariert werden. Dies würde also dazu führen, dass pip-compile
auch Hashes generiert, aber die globale Probelaufeinstellung verwirft:
[ tool . pip-tools ]
generate-hashes = true
dry-run = true
[ tool . pip-tools . compile ]
dry-run = false
Möglicherweise schließen Sie den Befehl pip-compile
in ein anderes Skript ein. Um Verbraucher Ihres benutzerdefinierten Skripts nicht zu verwirren, können Sie den oben in den Anforderungsdateien generierten Aktualisierungsbefehl überschreiben, indem Sie die Umgebungsvariable CUSTOM_COMPILE_COMMAND
festlegen.
$ 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
Wenn Sie unterschiedliche Umgebungen haben, für die Sie unterschiedliche, aber kompatible Pakete installieren müssen, können Sie mehrschichtige Anforderungsdateien erstellen und eine Schicht verwenden, um die andere einzuschränken.
Wenn Sie beispielsweise ein Django-Projekt haben, bei dem Sie die neueste Version 2.1
in Produktion haben möchten und bei der Entwicklung die Django-Debug-Symbolleiste verwenden möchten, können Sie zwei *.in
Dateien erstellen, eine für jede Ebene:
# requirements.in
django<2.2
Oben in den Entwicklungsanforderungen dev-requirements.in
verwenden Sie -c requirements.txt
um die Entwicklungsanforderungen auf Pakete zu beschränken, die bereits in requirements.txt
für die Produktion ausgewählt wurden.
# dev-requirements.in
-c requirements.txt
django-debug-toolbar<2.2
Kompilieren Sie zunächst requirements.txt
wie gewohnt:
$ 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
Kompilieren Sie nun die Entwicklungsanforderungen und die Datei requirements.txt
wird als Einschränkung verwendet:
$ 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
Wie Sie oben sehen können, umfassen die Entwickleranforderungen, obwohl eine 2.2
Version von Django verfügbar ist, nur eine 2.1
Version von Django, da diese eingeschränkt waren. Jetzt können beide kompilierten Anforderungsdateien sicher in der Entwicklungsumgebung installiert werden.
Um Anforderungen in der Produktionsphase zu installieren, verwenden Sie:
$ pip-sync
Sie können Anforderungen in der Entwicklungsphase installieren, indem Sie:
$ pip-sync requirements.txt dev-requirements.txt
Sie können pip-compile
als Hook für das Pre-Commit verwenden. Anweisungen finden Sie in den Pre-Commit-Dokumenten. Beispiel .pre-commit-config.yaml
:
repos :
- repo : https://github.com/jazzband/pip-tools
rev : 7.4.1
hooks :
- id : pip-compile
Möglicherweise möchten Sie die Argumente pip-compile
anpassen, indem Sie args
und/oder files
konfigurieren, zum Beispiel:
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]
Wenn Sie über mehrere Anforderungsdateien verfügen, stellen Sie sicher, dass Sie für jede Datei einen Hook erstellen.
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
Nachdem Sie nun eine requirements.txt
haben, können Sie pip-sync
verwenden, um Ihre virtuelle Umgebung so zu aktualisieren, dass sie genau widerspiegelt, was sich darin befindet. Dadurch wird alles installiert/aktualisiert/deinstalliert, was erforderlich ist, um den Inhalten der requirements.txt
zu erfüllen.
Führen Sie es mit pip-sync
oder python -m piptools sync
aus. Wenn Sie mehrere Python-Versionen verwenden, können Sie auch py -XY -m piptools sync
unter Windows und pythonX.Y -m piptools sync
auf anderen Systemen ausführen.
pip-sync
muss in derselben virtuellen Umgebung wie Ihr Projekt installiert und ausgeführt werden, um zu ermitteln, welche Pakete installiert oder aktualisiert werden müssen.
Seien Sie vorsichtig : pip-sync
ist nur für die Verwendung mit einer von pip-compile
generierten requirements.txt
vorgesehen.
$ 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
Um mehrere *.txt
Abhängigkeitslisten zu synchronisieren, übergeben Sie sie einfach über Befehlszeilenargumente, z. B
$ pip-sync dev-requirements.txt requirements.txt
Die Übergabe leerer Argumente würde dazu führen, dass standardmäßig requirements.txt
verwendet wird.
Alle gültigen pip install
oder -Argumente können mit der Option --pip-args
von pip-sync
übergeben werden, z
$ pip-sync requirements.txt --pip-args " --no-cache-dir --no-deps "
Hinweis : pip-sync
aktualisiert oder deinstalliert keine Verpackungstools wie setuptools
, pip
oder pip-tools
selbst. Verwenden Sie python -m pip install --upgrade
um diese Pakete zu aktualisieren.
requirements.in
und requirements.txt
in die Quellcodeverwaltung übernehmen? Im Allgemeinen ja. Wenn Sie möchten, dass eine reproduzierbare Umgebungsinstallation über Ihre Quellcodeverwaltung verfügbar ist, dann sollten Sie sowohl requirements.in
als auch requirements.txt
an die Quellcodeverwaltung übergeben.
Beachten Sie, dass Sie bei der Bereitstellung in mehreren Python-Umgebungen (lesen Sie den Abschnitt unten) eine separate Ausgabedatei für jede Python-Umgebung festschreiben müssen. Wir empfehlen die Verwendung des Formats {env}-requirements.txt
(z. B. win32-py3.7-requirements.txt
, macos-py3.10-requirements.txt
usw.).
requirements.in
/ requirements.txt
und pip-compile
Die Abhängigkeiten eines Pakets können sich abhängig von der Python-Umgebung, in der es installiert ist, ändern. Hier definieren wir eine Python-Umgebung als die Kombination aus Betriebssystem, Python-Version (3.7, 3.8 usw.) und Python-Implementierung (CPython, PyPy usw.). Eine genaue Definition finden Sie in den möglichen Kombinationen der PEP 508-Umgebungsmarker.
Da die resultierende requirements.txt
für jede Umgebung unterschiedlich sein kann, müssen Benutzer pip-compile
für jede Python-Umgebung separat ausführen, um eine für jede Umgebung gültige requirements.txt
zu generieren. Dieselbe requirements.in
kann als Quelldatei für alle Umgebungen verwendet werden, wobei nach Bedarf PEP 508-Umgebungsmarkierungen verwendet werden, genauso wie dies bei der regulären umgebungsübergreifenden pip
-Nutzung der Fall wäre.
Wenn die generierte requirements.txt
für alle Python-Umgebungen exakt gleich bleibt, kann sie sicher in allen Python-Umgebungen verwendet werden. Benutzer sollten jedoch vorsichtig sein, da jede Paketaktualisierung umgebungsabhängige Abhängigkeiten einführen kann, wodurch jede neu generierte requirements.txt
ebenfalls umgebungsabhängig wird. Als allgemeine Regel wird empfohlen, dass Benutzer dennoch immer pip-compile
in jeder Ziel-Python-Umgebung ausführen sollten, um Probleme zu vermeiden.
pip-tools
ist ein großartiges Tool zur Verbesserung der Reproduzierbarkeit von Builds. Aber es gibt ein paar Dinge zu beachten.
pip-compile
führt in unterschiedlichen Umgebungen zu unterschiedlichen Ergebnissen, wie im vorherigen Abschnitt beschrieben.pip
muss mit der Umgebungsvariablen PIP_CONSTRAINT
verwendet werden, um Abhängigkeiten in Build-Umgebungen zu sperren, wie in #8439 dokumentiert. Wenn wir das pyproject.toml
-Beispiel von früher fortsetzen, könnte das Erstellen einer einzelnen Sperrdatei wie folgt erfolgen:
$ 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
Einige Build-Backends können Build-Abhängigkeiten auch dynamisch anfordern, indem sie die in PEP 517 und PEP 660 beschriebenen get_requires_for_build_
-Hooks verwenden. Dies wird in der Ausgabe mit einem der folgenden Suffixe angezeigt:
(pyproject.toml::build-system.backend::editable)
(pyproject.toml::build-system.backend::sdist)
(pyproject.toml::build-system.backend::wheel)
pip-compile-multi – pip-compile-Befehls-Wrapper für mehrere Querverweis-Anforderungsdateien.
pipdeptree, um den Abhängigkeitsbaum der installierten Pakete zu drucken.
requirements.in
/ requirements.txt
Syntaxhervorhebung:
In diesem Abschnitt werden die derzeit veralteten pip-tools
Funktionen aufgeführt.
--allow-unsafe
standardmäßig aktiviert (#989). Verwenden Sie --no-allow-unsafe
um das alte Verhalten beizubehalten. Es wird empfohlen --allow-unsafe
jetzt zu übergeben, um sich an die bevorstehende Änderung anzupassen.--resolver=backtracking
.--strip-extras
standardmäßig aktiviert (#1613). Verwenden Sie --no-strip-extras
um das alte Verhalten beizubehalten.Sie können zwischen dem Standard-Backtracking-Resolver und dem veralteten Legacy-Resolver wählen.
Der Legacy-Resolver löst gelegentlich keine Abhängigkeiten auf. Der Backtracking-Resolver ist robuster, die Ausführung kann jedoch im Allgemeinen länger dauern.
Sie können den Legacy-Resolver weiterhin mit --resolver=legacy
verwenden. Beachten Sie jedoch, dass er veraltet ist und in einer zukünftigen Version entfernt wird.