Un ensemble d'outils de ligne de commande pour vous aider à conserver vos packages basés sur pip
à jour, même lorsque vous les avez épinglés. Vous les épinglez, n'est-ce pas ? (Lors de la création de votre application Python et de ses dépendances pour la production, vous voulez vous assurer que vos builds sont prévisibles et déterministes.)
Semblable à pip
, pip-tools
doit être installé dans chacun des environnements virtuels de votre projet :
$ source /path/to/venv/bin/activate
(venv) $ python -m pip install pip-tools
Remarque : tous les exemples de commandes restants supposent que vous avez activé l'environnement virtuel de votre projet.
pip-compile
La commande pip-compile
vous permet de compiler un fichier requirements.txt
à partir de vos dépendances, spécifiées dans pyproject.toml
, setup.cfg
, setup.py
ou requirements.in
.
Exécutez-le avec pip-compile
ou python -m piptools compile
(ou pipx run --spec pip-tools pip-compile
si pipx
a été installé avec la version Python appropriée). Si vous utilisez plusieurs versions de Python, vous pouvez également exécuter py -XY -m piptools compile
sur Windows et pythonX.Y -m piptools compile
sur d'autres systèmes.
pip-compile
doit être exécuté à partir du même environnement virtuel que votre projet afin que les dépendances conditionnelles qui nécessitent une version spécifique de Python, ou d'autres marqueurs d'environnement, soient résolues par rapport à l'environnement de votre projet.
Remarque : Si pip-compile
trouve un fichier requirements.txt
existant qui remplit les dépendances, aucune modification ne sera apportée, même si des mises à jour sont disponibles. Pour compiler à partir de zéro, supprimez d’abord le fichier requirements.txt
existant ou consultez Mise à jour des exigences pour des approches alternatives.
pyproject.toml
Le fichier pyproject.toml
est la dernière norme en matière de configuration des packages et des applications et est recommandé pour les nouveaux projets. pip-compile
prend en charge à la fois l'installation de votre project.dependencies
ainsi que de votre project.optional-dependencies
. Grâce au fait qu'il s'agit d'une norme officielle, vous pouvez utiliser pip-compile
pour épingler les dépendances dans des projets qui utilisent des outils d'empaquetage modernes conformes aux normes comme Setuptools, Hatch ou flit.
Supposons que vous disposiez d'une application Python 'foobar' packagée à l'aide Setuptools
et que vous souhaitiez l'épingler pour la production. Vous pouvez déclarer les métadonnées du projet comme :
[ 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 " ] }
Si vous disposez d’une application Django packagée à l’aide Hatch
et que vous souhaitez l’épingler pour la production. Vous souhaitez également épingler vos outils de développement dans un fichier PIN distinct. Vous déclarez django
comme dépendance et créez une dépendance facultative dev
qui inclut pytest
:
[ build-system ]
requires = [ " hatchling " ]
build-backend = " hatchling.build "
[ project ]
name = " my-cool-django-app "
version = " 42 "
dependencies = [ " django " ]
[ project . optional-dependencies ]
dev = [ " pytest " ]
Vous pouvez produire vos fichiers PIN aussi facilement que :
$ 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
C’est idéal à la fois pour épingler vos applications, mais aussi pour maintenir la stabilité du CI de votre package Python open source.
setup.py
et setup.cfg
pip-compile
prend également entièrement en charge les projets basés sur setup.py
et setup.cfg
qui utilisent setuptools
.
Définissez simplement vos dépendances et extras comme d'habitude et exécutez pip-compile
comme ci-dessus.
requirements.in
Vous pouvez également utiliser des fichiers texte brut selon vos besoins (par exemple si vous ne souhaitez pas que votre application soit un package). Pour utiliser un fichier requirements.in
pour déclarer la dépendance Django :
# requirements.in
django
Maintenant, exécutez 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
Et il produira votre requirements.txt
, avec toutes les dépendances Django (et toutes les dépendances sous-jacentes) épinglées.
(exigences de mise à jour)=
pip-compile
génère un fichier requirements.txt
en utilisant les dernières versions qui remplissent les dépendances que vous spécifiez dans les fichiers pris en charge.
Si pip-compile
trouve un fichier requirements.txt
existant qui remplit les dépendances, aucune modification ne sera apportée, même si des mises à jour sont disponibles.
Pour forcer pip-compile
à mettre à jour tous les packages dans un requirements.txt
existant, exécutez pip-compile --upgrade
.
Pour mettre à jour un package spécifique vers la dernière version ou une version spécifique, utilisez l'indicateur --upgrade-package
ou -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
Vous pouvez combiner --upgrade
et --upgrade-package
en une seule commande, pour fournir des contraintes sur les mises à niveau autorisées. Par exemple pour mettre à niveau tous les packages tout en limitant les requêtes à la dernière version inférieure à 3.0 :
$ pip-compile --upgrade --upgrade-package ' requests<3.0 '
Si vous souhaitez utiliser le mode de vérification de hachage disponible dans pip
depuis la version 8.0, pip-compile
propose l'indicateur --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
Pour afficher les exigences épinglées dans un nom de fichier autre que requirements.txt
, utilisez --output-file
. Cela peut être utile pour compiler plusieurs fichiers, par exemple avec différentes contraintes sur Django pour tester une bibliothèque avec les deux versions en utilisant 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
Ou pour afficher sur la sortie standard, utilisez --output-file=-
:
$ pip-compile --output-file=- > requirements.txt
$ pip-compile - --output-file=- < requirements.in > requirements.txt
pip
Tous les indicateurs ou arguments pip
valides peuvent être transmis avec l'option --pip-args
de pip-compile
, par exemple
$ pip-compile requirements.in --pip-args " --retries 10 --timeout 30 "
Vous pouvez définir les valeurs par défaut au niveau du projet pour pip-compile
et pip-sync
en les écrivant dans un fichier de configuration dans le même répertoire que vos fichiers d'entrée d'exigences (ou le répertoire de travail actuel si vous canalisez l'entrée depuis stdin). Par défaut, pip-compile
et pip-sync
rechercheront d'abord un fichier .pip-tools.toml
puis dans votre pyproject.toml
. Vous pouvez également spécifier un autre fichier de configuration TOML avec l'option --config
.
Il est possible de spécifier des valeurs de configuration à la fois globalement et spécifiques à la commande. Par exemple, pour générer par défaut des hachages pip
dans la sortie du fichier d'exigences résultant, vous pouvez spécifier dans un fichier de configuration :
[ tool . pip-tools ]
generate-hashes = true
Les options de pip-compile
et pip-sync
qui peuvent être utilisées plus d'une fois doivent être définies sous forme de listes dans un fichier de configuration, même si elles n'ont qu'une seule valeur.
pip-tools
prend en charge les valeurs par défaut pour tous les indicateurs de ligne de commande valides de ses sous-commandes. Les clés de configuration peuvent contenir des traits de soulignement au lieu de tirets, donc ce qui précède peut également être spécifié dans ce format :
[ tool . pip-tools ]
generate_hashes = true
Les valeurs de configuration par défaut spécifiques à pip-compile
et pip-sync
peuvent être placées sous des sections distinctes. Par exemple, pour effectuer par défaut un essai à sec avec pip-compile
:
[ tool . pip-tools . compile ] # "sync" for pip-sync
dry-run = true
Cela n'affecte pas la commande pip-sync
, qui possède également une option --dry-run
. Notez que les paramètres locaux ont la préférence sur les paramètres globaux du même nom, chaque fois que les deux sont déclarés, cela obligerait donc également pip-compile
à générer des hachages, mais ignorerait le paramètre global d'exécution à sec :
[ tool . pip-tools ]
generate-hashes = true
dry-run = true
[ tool . pip-tools . compile ]
dry-run = false
Vous êtes peut-être en train d'encapsuler la commande pip-compile
dans un autre script. Pour éviter de confondre les utilisateurs de votre script personnalisé, vous pouvez remplacer la commande de mise à jour générée en haut des fichiers d'exigences en définissant la variable d'environnement 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
Si vous disposez de différents environnements pour lesquels vous devez installer des packages différents mais compatibles, vous pouvez créer des fichiers d'exigences en couches et utiliser une couche pour contraindre l'autre.
Par exemple, si vous avez un projet Django dans lequel vous souhaitez que la dernière version 2.1
soit en production et que lors du développement, vous souhaitez utiliser la barre d'outils de débogage de Django, vous pouvez créer deux fichiers *.in
, un pour chaque couche :
# requirements.in
django<2.2
En haut des exigences de développement dev-requirements.in
vous utilisez -c requirements.txt
pour limiter les exigences de développement aux packages déjà sélectionnés pour la production dans requirements.txt
.
# dev-requirements.in
-c requirements.txt
django-debug-toolbar<2.2
Tout d’abord, compilez requirements.txt
comme d’habitude :
$ 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
Compilez maintenant les exigences de développement et le fichier requirements.txt
est utilisé comme contrainte :
$ 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
Comme vous pouvez le voir ci-dessus, même si une version 2.2
de Django est disponible, les exigences de développement n'incluent qu'une version 2.1
de Django car elles étaient contraintes. Désormais, les deux fichiers d'exigences compilés peuvent être installés en toute sécurité dans l'environnement de développement.
Pour installer les exigences en phase de production, utilisez :
$ pip-sync
Vous pouvez installer les exigences en phase de développement en :
$ pip-sync requirements.txt dev-requirements.txt
Vous pouvez utiliser pip-compile
comme hook pour le pré-commit. Consultez les documents de pré-validation pour obtenir des instructions. Exemple .pre-commit-config.yaml
:
repos :
- repo : https://github.com/jazzband/pip-tools
rev : 7.4.1
hooks :
- id : pip-compile
Vous souhaiterez peut-être personnaliser les arguments pip-compile
en configurant args
et/ou files
, par exemple :
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]
Si vous disposez de plusieurs fichiers d'exigences, assurez-vous de créer un hook pour chaque fichier.
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
Maintenant que vous disposez d'un requirements.txt
, vous pouvez utiliser pip-sync
pour mettre à jour votre environnement virtuel afin de refléter exactement ce qu'il contient. Cela installera / mettra à niveau / désinstallera tout ce qui est nécessaire pour correspondre au contenu du fichier requirements.txt
.
Exécutez-le avec pip-sync
ou python -m piptools sync
. Si vous utilisez plusieurs versions de Python, vous pouvez également exécuter py -XY -m piptools sync
sur Windows et pythonX.Y -m piptools sync
sur d'autres systèmes.
pip-sync
doit être installé et exécuté à partir du même environnement virtuel que votre projet pour identifier les packages à installer ou à mettre à niveau.
Attention : pip-sync
est destiné à être utilisé uniquement avec un requirements.txt
généré par pip-compile
.
$ 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
Pour synchroniser plusieurs listes de dépendances *.txt
, transmettez-les simplement via des arguments de ligne de commande, par exemple
$ pip-sync dev-requirements.txt requirements.txt
Passer des arguments vides entraînerait la valeur par défaut sur requirements.txt
.
Tous les indicateurs ou arguments pip install
valides peuvent être transmis avec l'option --pip-args
de pip-sync
, par exemple
$ pip-sync requirements.txt --pip-args " --no-cache-dir --no-deps "
Remarque : pip-sync
ne mettra pas à niveau ni ne désinstallera les outils d'empaquetage tels que setuptools
, pip
ou pip-tools
lui-même. Utilisez python -m pip install --upgrade
pour mettre à niveau ces packages.
requirements.in
et requirements.txt
dans le contrôle de code source ? En général, oui. Si vous souhaitez qu'une installation d'environnement reproductible soit disponible à partir de votre contrôle de source, alors oui, vous devez valider à la fois requirements.in
et requirements.txt
dans le contrôle de source.
Notez que si vous déployez sur plusieurs environnements Python (lisez la section ci-dessous), vous devez alors valider un fichier de sortie distinct pour chaque environnement Python. Nous suggérons d'utiliser le format {env}-requirements.txt
(ex : win32-py3.7-requirements.txt
, macos-py3.10-requirements.txt
, etc.).
requirements.txt
requirements.in
et pip-compile
Les dépendances d'un package peuvent changer en fonction de l'environnement Python dans lequel il est installé. Ici, nous définissons un environnement Python comme la combinaison du système d'exploitation, de la version Python (3.7, 3.8, etc.) et de l'implémentation Python (CPython, PyPy, etc.). Pour une définition exacte, se référer aux combinaisons possibles des marqueurs d'environnement PEP 508.
Comme le requirements.txt
résultant peut différer pour chaque environnement, les utilisateurs doivent exécuter pip-compile
sur chaque environnement Python séparément pour générer un requirements.txt
valide pour chaque dit environnement. Le même requirements.in
peut être utilisé comme fichier source pour tous les environnements, en utilisant les marqueurs d'environnement PEP 508 selon les besoins, de la même manière qu'il le ferait pour une utilisation régulière entre environnements pip
.
Si le requirements.txt
généré reste exactement le même pour tous les environnements Python, il peut alors être utilisé en toute sécurité dans tous les environnements Python. Mais les utilisateurs doivent être prudents, car toute mise à jour de package peut introduire des dépendances dépendantes de l'environnement, rendant également tout requirements.txt
nouvellement généré dépendant de l'environnement. En règle générale, il est conseillé aux utilisateurs de toujours exécuter pip-compile
sur chaque environnement Python ciblé pour éviter les problèmes.
pip-tools
est un excellent outil pour améliorer la reproductibilité des builds. Mais il y a quelques points à garder à l’esprit.
pip-compile
produira différents résultats dans différents environnements, comme décrit dans la section précédente.pip
doit être utilisé avec la variable d'environnement PIP_CONSTRAINT
pour verrouiller les dépendances dans les environnements de construction, comme documenté dans #8439. En reprenant l'exemple pyproject.toml
précédent, la création d'un seul fichier de verrouillage pourrait être effectuée comme :
$ 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
Certains backends de build peuvent également demander des dépendances de build de manière dynamique à l'aide des hooks get_requires_for_build_
décrits dans PEP 517 et PEP 660. Cela sera indiqué dans la sortie avec l'un des suffixes suivants :
(pyproject.toml::build-system.backend::editable)
(pyproject.toml::build-system.backend::sdist)
(pyproject.toml::build-system.backend::wheel)
pip-compile-multi - wrapper de commande pip-compile pour plusieurs fichiers d'exigences de référencement croisé.
pipdeptree pour imprimer l'arborescence des dépendances des packages installés.
Coloration de la requirements.txt
requirements.in
:
Cette section répertorie les fonctionnalités pip-tools
actuellement obsolètes.
--allow-unsafe
sera activé par défaut (#989). Utilisez --no-allow-unsafe
pour conserver l'ancien comportement. Il est recommandé de passer --allow-unsafe
maintenant pour s'adapter au changement à venir.--resolver=backtracking
.--strip-extras
sera activé par défaut (#1613). Utilisez --no-strip-extras
pour conserver l'ancien comportement.Vous pouvez choisir entre le résolveur de retour en arrière par défaut ou le résolveur hérité obsolète.
Le résolveur existant ne parviendra parfois pas à résoudre les dépendances. Le résolveur de retour en arrière est plus robuste, mais son exécution peut prendre plus de temps en général.
Vous pouvez continuer à utiliser le résolveur existant avec --resolver=legacy
mais notez qu'il est obsolète et qu'il sera supprimé dans une version ultérieure.