Vous êtes en train de développer un nouveau projet en Python et vous avez besoin de cette nouvelle dépendance ! Vous souhaiteriez ne pas l'installer sur votre machine, mais juste pour le projet sur lequel vous travaillez en ce moment ? Peut-être que vous avez besoin d'utiliser Python 2 plutôt que Python 3 ? Vous avez envie de mettre ce projet en ligne et vous voulez gérer tout ça facilement non ?
Vous n'avez pas encore écrit une seule ligne de code que de nombreuses questions sont déjà là pour vous empêcher d'avancer !
Le monde des dépendances en Python est assez difficile à appréhender, on s'y perd vite, c'est vrai. Heureusement, il existe des outils pour résoudre tous ces problèmes ! Ce qui est important, c'est surtout de savoir à quelle question répond quel outil.
Dans cet article, je vous présente les outils que j'utilise et je vous montre comment je procède pour gérer les dépendances de tous mes projets !
pip
pip est le gestionnaire de dépendances de Python par défaut. Il est installé avec Python la plupart du temps et il est simple à utiliser :
pip install nom_de_la_dependance
Lorsque vous installez quelque chose avec pip, 3 opérations sont effectuées :
- Vous communiquez avec PyPi pour voir si le paquet existe
- Il existe ? Super, vous le téléchargez
- La dépendance est installée dans votre environnement Python
C'est un outil élémentaire qui fait ce qu'on lui demande. Par contre, il ne prend aucune décision pour vous et se fiche pas mal des différentes versions de Python que vous utilisez.
Vous pouvez cibler la version d'une dépendance en particulier en faisant :
pip install dependance=version
Pour désinstaller, c'est comme ça :
pip uninstall dependance
Pour obtenir la liste de vos dépendances :
pip list
ou
pip freeze
- pip freeze ne liste pas les dépendances utilisées par pip lui-même
- pip freeze utilise un format spécifique à pip qui est utile pour la reproduction de votre environnementPour savoir si vous avez des dépendances qui ne sont pas à jour :
pip list --outdated
Et pour les mettre à jour du coup :
pip install dependance --upgrade
venv
Le module venv
est un outil qui permet de créer des environnements virtuels.
On l'utilise pour isoler nos applications les unes des autres et éviter les conflits avec Python. Ainsi, chaque environnement virtuel peut utiliser n'importe quelle version de la même dépendance sans qu'il y ait de problème !
Comme pip
, il vient avec Python 3, vous n'avez pas besoin de le télécharger.
Pour créer un environnement virtuel :
python -m venv nom_du_dossier
Vous pouvez voir que Python a créé un nouveau dossier avec le nom du dossier que vous avez indiqué à venv.
Ce dossier représente votre environnement virtuel.
Création d'un environnement virtuel que j'ai appelé 'env', par convention.
Là-dedans, vous avez plusieurs dossiers et un fichier de configuration :
- Le dossier
bin
qui contient les exécutables ainsi que l'interpréteur Python - Le dossier
include
qui contient les entêtes de votre environnement - Le dossier
lib
qui répertorie toutes les dépendances que vous avez installées - Le fichier
pyvenv.cfg
qui contient la configuration de votre environnement virtuel
Maintenant, vous devez indiquer au système que vous souhaitez utiliser cet environnement virtuel.
Sur les systèmes UNIX, il faudra utiliser cette commande :
source chemin/vers/environnement_virtuel/bin/activate
Alors que sur WINDOWS :
C:\chemin\vers\projet\env_nom_du_projet\Scripts\activate.bat
ou (dépendant de votre shell)
call C:\chemin\vers\projet\env_nom_du_projet\Scripts\activate.bat
Sur Windows, le dossier bin est remplacé par le dossier Scripts.
Si tout se passe bien, votre terminal devrait maintenant vous indiquer que vous êtes dans l'environnement virtuel.
Le terminal m'indique que j'ai bien activé l'environnement virtuel pour mon projet 'tools'
Enfin, vous pouvez désactiver votre environnement grâce à la commande deactivate
.
Comment venv fonctionne-t-il avec pip ?
Ces deux outils faisant partie de la librairie standard de Python, ils fonctionnent très bien ensemble et sont complémentaires. Habituellement, on crée un environnement virtuel avec venv
puis on vient installer tous les paquets qui nous intéresse avec pip
.
C'est d'ailleurs ce que je vous conseille de faire 🙂
pip-tools
Lors du développement d'un projet en Python, nous devons déclarer la liste des dépendances de l'application dans un fichier requirements.txt
afin qu'il puisse être reproduit.
Ça donne quelque chose comme :
# requirements.txt
alembic==1.4.2
autopep8==1.5.2
cffi==1.14.0
click==7.1.2
dnspython==1.16.0
email-validator==1.1.1
Flask==1.1.2
Flask-Login==0.5.0
Flask-Markdown==0.3
Flask-Migrate==2.5.3
Flask-SimpleMDE==0.3.0
Flask-SQLAlchemy==2.4.1
Flask-WTF==0.14.3
...
C'est le format standard compris par pip
. Vous avez le nom de la dépendance, deux symboles égal puis le numéro de version. Vous pouvez aussi préciser un intervalle pour les numéros de version, mais je vous déconseille de le faire. Il vaut mieux travailler avec des versions précises.
Grâce à ça, on peut en théorie reproduire un environnement et tout installer d'un coup avec la commande :
pip install -r requirements.txt
Le problème est que toutes ces dépendances ont elles-mêmes des dépendances qui ne sont pas listées dans le fichier requirements.txt
.
Par exemple, si vous désinstallez une dépendance qui ne vous intéresse plus, ses dépendances à elle vont rester dans votre environnement. Mais elles ne seront plus là si vous créez un nouvel environnement ailleurs à partir du fichier requirements.txt
.
Bref, votre application ne vas pas aimer et ça va vous prendre la tête !
C'est là qu'intervient notre outil.
pip-tools se compose de deux utilitaires :
- pip-compile
- pip-sync
Vous allez déclarer toutes vos dépendances dans un fichier requirements.in
(et pas .txt
) en indiquant des intervalles pour les versions de dépendances que vous souhaitez autoriser.
Lancez ensuite pip-compile
pour générer un fichier requirements.txt
qui satisfait tout ce que vous avez spécifié ! C'est un peu comme les lockfiles sur npm
ou yarn
si vous connaissez.
Après ça, il ne vous reste plus qu'à installer le tout avec la commande pip-sync
qui est similaire à la commande pip install -r requirements.txt
à la différence que toutes les dépendances non déclarées dans votre fichier requirements.txt
seront supprimées
Comment intégrer pip-tools dans son projet ?
Comme je vous le disais, chaque outil répond à un problème particulier.
pip-tools
est prévu pour être utilisé dans un environnement virtuel créé via venv
et dont les dépendances sont gérées par pip
.
Tout s'emboîte, c'est plutôt propre !
pyenv
Si vous avez lu notre compte-rendu du StackOverflow Developer Survey 2020, vous avez compris que Python était de plus en plus utilisé pour créer des applications en tout genre.
Cette popularité de Python fait que de nombreuses versions du langage sont en circulation.
Et pour nous développeur, c'est un problème !
Nous devons constamment changer de version en fonction des projets sur lesquels nous travaillons.
pyenv a été créé pour résoudre ce problème.
Cet outil vous permet de changer de version de Python automatiquement en fonction de votre application tout en conservant la version de Python installée au niveau de votre système.
Il nécessite un peu de configuration puisqu'il faut entre autre spécifier la version de Python que vous souhaitez utiliser à chaque démarrage d'un nouveau projet, mais une fois cela fait, vous êtes tranquille !
Comment pyenv se comporte avec pip ?
Il faut voir pyenv
comme une surcouche de pip
. Quand vous allez installer une nouvelle dépendance avec pip
, il va simplement la télécharger en prenant en compte la version de Python courante, que vous l'ayez définie dans pyenv
ou pas.
Vous pouvez donc utiliser les deux sans problème, ils sont même complémentaires 👍
Docker
Docker n'a rien à voir avec Python en soit, mais certaines personnes s'en servent pour gérer leurs dépendances.
Docker, c'est un outil pour créer et gérer des conteneurs.
Ces conteneurs peuvent être vus comme de toutes petites machines virtuelles qui vous permettent d'isoler totalement vos processus les uns des autres à moins bien sûr de les relier explicitement.
Du coup, vous pouvez mettre un peu ce que vous voulez dans un conteneur comme tous les outils dont je vous ai parlé juste avant.
À savoir que ça n'aurait pas de sens car Docker permet d'éviter les problèmes liés aux dépendances et aux environnements puisque les conteneurs sont isolés par définition.
Docker n'est pas un outil que j'utilise car je n'en ai simplement pas le besoin. Je pense que c'est très intéressant pour gérer des projets de moyenne-grande envergure, en particulier dans des environnements de production.
Par contre, ça s'adapte mal à des environnements de développements selon moi :
- C'est lourd et ça prend de la RAM sur ton OS
- C'est une techno à part entière que tu dois apprendre et comprendre
- C'est compliqué à déboguer
Ma solution
Je ne vous ai pas présenté ces outils par hasard. Ce sont ceux que j'utilise au quotidien !
Pour résumer :
- Installer des dépendances pip
- Gérer un environnement virtuel venv
- Reproduire un environnement pip-tools
- Gérer les versions de Python pyenv
Avec ça, vous avez un système souple où chaque outil répond à un problème. Tout est basé sur pip
qui est inclus dans l'installation de Python. Vous pouvez commencer par utiliser un environnement virtuel et un fichier requirement.txt
au début puis ajouter les autres outils quand vous vous sentez plus à l'aise !