Skip to main content

Introduction (en douceur) à la gestion des dépendances Python

Écrit par
Headshot of Lucian Irsigler

Lucian Irsigler

Python dependency management

14 septembre 2021

0 minutes de lecture

Python est souvent considéré comme un langage « simple » : facile à utiliser et à prendre en main pour écrire des scripts qui accomplissent de nombreuses tâches, du web scraping à l’automatisation, en passant par la création d’applications web à grande échelle et même l’analyse de données. Pourtant, la gestion des dépendances en Python est très différente de celle des autres langages, et la multitude d’options pour configurer un environnement et choisir un gestionnaire de packages ne fait qu’ajouter à la confusion. Dans cet article, nous allons découvrir différentes façons de gérer les dépendances Python et aborder brièvement la sécurité des dépendances.

Python, un langage interprété

Un langage interprété est un langage dont les scripts ne sont pas traduits en code machine, ni même en fichiers exécutables. Ils sont transmis à un autre programme — ici, l’interpréteur Python — qui exécute le code.

Si j’écris un script Python simple comme celui-ci :

print("Hello world") #main.py

Puis que je l’exécute avec :

python pathToScript/main.py

Voici le résultat obtenu :

Hello world

Avez-vous remarqué qu’il n’y a aucun fichier exécutable, comme un fichier .exe, dans le dossier où ce code a été exécuté ? C’est parce que l’exécutable Python compile et exécute le fichier au moment de l’exécution, et non à l’avance.

En réalité, un fichier .exe exécute le code Python. Main.py est transmis à ce fichier .exe, puis exécuté. Ce fichier .exe est l’interpréteur Python compilé, accessible dans le chemin de votre environnement.

Organigramme montrant main.py, un fichier exécutable qui lit du code Python et l’exécute

Qu’est-ce qu’une dépendance en Python ?

En Python, une dépendance est comme dans tout autre langage : une bibliothèque de code nécessaire à l’exécution du code source du script pour lequel elle a été importée.

Par exemple, si vous souhaitez interagir avec une base de données PostgreSQL, deux options s’offrent à vous : écrire vous-même toutes les fonctions ou installer le package postgres, qui comprend déjà les requêtes et les autres fonctionnalités dont vous avez besoin.

Alors, comment installer le package PostgreSQL approprié ?

pip install postgres

Pour bien gérer les dépendances, quel que soit le langage, il est important de vérifier que le package est bien maintenu et ne présente aucun problème de sécurité. Pour évaluer l’état général d’un package, vous pouvez notamment utiliser Snyk Advisor.

Page de Snyk Open Source Advisor affichant une recherche de packages et un score de santé de 90/100 pour le package nodemon.

Avec Snyk Advisor, vous pouvez rechercher l’état des packages de différentes distributions, comme PyPI et npm. Vous pouvez également consulter les images de base Docker et leurs statistiques générales, leur popularité, les tags disponibles et d’autres informations utiles.

Pour revenir à notre projet lié à PostgreSQL, vérifions que l’état du package postgres est suffisamment bon :

Page Snyk Advisor consacrée au package Python postgres, avec un score de santé de 56/100 et des graphiques sur sa popularité et sa maintenance.

Le package postgres n’obtient pas un très bon score : 56 sur 100. Il n’est pas très populaire, avec environ 10 000 téléchargements par semaine, et sa dernière version date de deux ans. Cela peut indiquer qu’il n’est pas suffisamment maintenu.

En faisant défiler la page jusqu’aux sections consacrées à la sécurité et à la communauté, un point ressort : le risque lié à la licence de la dernière version du package — la version 3.0.0 du 19 octobre 2019 — mérite un examen plus approfondi :

Tableau de bord de sécurité des packages indiquant la version 3.0.0 de PostgreSQL, la licence MIT, l’absence de politique de sécurité et un score de santé du package de 56/100

Si vous choisissez d’utiliser ce package, une fois l’étape pip install effectuée, votre système aura accès au package postgres.

Pour l’importer dans vos projets :

import postgres

Vous voyez maintenant pourquoi la gestion des dépendances en Python peut devenir compliquée. Si je donne ce script à un ami qui n’a pas Python et qu’il essaie de l’exécuter, il rencontrera une erreur.

Pourquoi cette erreur ?

Tout d’abord, votre ami doit avoir installé Python. Ensuite, les packages nécessaires au projet doivent être installés — dans ce cas, postgres.

De plus, l’environnement Python doit disposer de tous les modules nécessaires à l’exécution du script, comme c’est le cas dans les autres langages lorsqu’une bibliothèque ou un code source spécifique manque.

Il faut donc deux éléments pour partager mon projet Python avec un ami :

  • Tous les fichiers nécessaires à l’exécution de Python

  • Le package postgres

Gestion des dépendances Python

Pour partager vos projets Python, vous devez inclure un fichier nommé requirements.txt. Vous pouvez utiliser la commande pip pour installer précisément les dépendances nécessaires au projet :

pip3 install -r requirements.txt

Nous utilisons pip3 plutôt que pip afin d’éviter d’installer la mauvaise version. pip pointe vers la première version de Python que vous avez installée. Ainsi, si vous avez d’abord installé Python 2, la commande pip pointera vers pip2, qui sert à installer des packages Python 2.

Ainsi, le terme pip3 indique explicitement à pip d’installer le package Python 3.

Si aucune version de Python 2 n’est installée sur votre ordinateur, vous n’avez pas à vous en soucier.

Pour vérifier quel pip (pip2 ou pip3) est utilisé par votre commande pip, exécutez ceci dans la console :

pip --version

Cette commande lit le fichier texte requirements.txt, qui répertorie toutes les dépendances nécessaires à ce projet, puis installe les packages qui y sont listés.

Pour que les packages soient effectivement installés lorsque quelqu’un exécute cette commande :

  • Vous devez créer ce fichier manifeste de packages

  • Les packages doivent être répertoriés dans ce fichier au format suivant : <Package name> <Higher/equal to> <some version>

Par exemple :

requirements.txt

cloudscraper==1.2.58        # Version Matching. Must be version 1.2.58
Newspaper3k >= 0.1          # Minimum version 0.1
requests != 3.4             # Version Exclusion. Anything except version 3.4
beautifulsoup4 ~= 1.1       # Compatible release. Same as >= 1.1, == 1.*
discord.py                  # Installs latest release 

Les opérateurs de comparaison servent à vérifier les versions. Ils garantissent que le gestionnaire de packages pip installe les versions adaptées à votre projet. Si aucune version n’est précisée, la dernière version est installée.

Vous pouvez maintenant partager le code source de votre projet avec vos amis et leur demander d’exécuter la commande pip3 avec le fichier requirements.txt fourni avec le projet. Ils disposeront alors des dépendances open source nécessaires à son exécution.

Qu’en est-il des gestionnaires de dépendances Python ?

En plus du fichier manifeste de packages que nous avons découvert (requirements.txt), vous pouvez utiliser des gestionnaires de packages pour simplifier la maintenance et la gestion des dépendances de vos projets Python. En voici quelques-uns que vous pouvez installer et utiliser :

  1. Poetry

  2. pyenv

  3. Setuptools

Poetry

Poetry vous permet de créer des fichiers de verrouillage qui répertorient les dépendances de votre projet. Un fichier de verrouillage est automatiquement installé lors de l’installation du package. Il facilite la mise à jour des dépendances nécessaires au projet.

Poetry s’utilise en ligne de commande. Des commandes comme :

poetry add <module>

poetry build <module>

poetry <publish>

Ces commandes facilitent le suivi et l’ajout de dépendances dans ce fichier de verrouillage, puis leur ajout à votre package PyPI.

Vous pouvez également utiliser l’option --tree pour afficher les dépendances de votre projet sous forme d’arborescence :

my-package
├── pyproject.toml
├── README.rst
├── my_package
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_my_package.py

Poetry facilite la gestion et l’ajout de dépendances.

pyenv

pyenv est un outil simple qui vous permet de passer d’une version de Python à une autre. Vous pouvez ainsi vérifier si vos dépendances posent problème avec une version antérieure de Python. Comme c’est sa fonction principale, il ne possède pas toutes les fonctionnalités d’autres gestionnaires de dépendances, comme Poetry.

Toutefois, si vous avez besoin de vérifier que votre package fonctionne avec une ancienne version de Python, pyenv est un outil utile.

Setuptools

Setuptools est également un package qui facilite la gestion des packages. Il demande un peu plus de travail que Poetry, mais il remplit bien sa fonction.

Comme son nom l’indique, Setuptools aide les utilisateurs à configurer votre package, notamment en leur fournissant les packages nécessaires à l’exécution du script.

Avec setuptools, vous créez deux fichiers : un fichier pyproject.toml et un fichier setup.py/setup.cfg.

Dans le fichier .toml, ajoutez le code suivant pour indiquer à Python que vous allez utiliser Setuptools afin de spécifier les informations relatives à votre package :

[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

Dans votre fichier setup.py/setup.cfg, vous pourriez ensuite avoir quelque chose comme ceci :

[metadata]
name = mypackage
version = 0.0.1

[options]
packages = mypackage
install_requires =
    requests
    importlib; python_version == "2.6"

Vous aurez ensuite besoin d’un outil de création, comme PyPA build. Votre projet sera créé dans un fichier .gz, prêt à être distribué.

Setuptools nécessite davantage d’interventions manuelles de votre part, mais il gère efficacement les packages et garantit à vos utilisateurs de disposer de tous les packages nécessaires à l’exécution du script.

Ces trois gestionnaires de dépendances figurent parmi les plus populaires. Chacun a ses forces et ses faiblesses. Quel que soit votre choix, ils fonctionnent tous efficacement et simplifient la gestion des dépendances en Python.

Terminal affichant l’analyse des dépendances d’un projet Python Flask, qui détecte un chemin vulnérable dans Jinja2 et recommande une mise à niveau.

Mieux encore, la CLI Snyk vous montre le chemin des dépendances qui mène à la vulnérabilité, ainsi que la façon de résoudre le problème : en passant à une version plus récente qui inclut un correctif de sécurité.

Pour conclure

Les bibliothèques open source vulnérables ne sont pas le seul risque de sécurité. Votre application Python peut, par exemple, contenir du code non sécurisé ou être intégrée à des conteneurs non sécurisés. Daniel Berman a rédigé un article détaillé sur les premiers pas avec Snyk pour développer des applications Python sécurisées, que je vous recommande vivement de lire à la suite de cet article.

J’espère que vous avez apprécié cette présentation de la gestion des dépendances et de la sécurité en Python. Pour en savoir plus sur la sécurité Python, consultez ces ressources :

  1. Outils de gestion des dépendances pour Python

  2. Qu’est-ce que package-lock.json ? Les fichiers de verrouillage pour les packages yarn et npm

  3. Comment maintenir les dépendances npm dans votre projet

  4. Le gestionnaire de packages Python Poetry et son intégration de la sécurité avec un outil d’analyse de la composition logicielle

Lancez-vous dans les compétitions Capture The Flag

Apprenez à résoudre des défis Capture The Flag en regardant à la demande notre atelier virtuel d’initiation.


Lucian Irsigler est un programmeur passionné qui aime les complexités de la vie.

Lire la suite

blog feature snyk container custom base recommendations
Blog

Découvrez Evo Agentic AppSec : une sécurité au rythme du développement de l’IA

Le développement piloté par l’IA dépasse les capacités des processus de sécurité traditionnels. Agentic AppSec de Snyk s’appuie sur des agents de sécurité pour détecter, corriger et vérifier les vulnérabilités en continu, tandis que les équipes définissent les exigences.

feature insights context
Blog

Les attaques autonomes sont déjà là. La défense doit suivre leur rythme.

Les attaquants autonomes réduisent la fenêtre de défense. Découvrez comment la découverte, la correction, la validation et la prévention continues peuvent aider les équipes de sécurité à suivre le rythme.

feature insights context
Blog

La prévention est-elle essentiellement un problème résolu ?

La prévention dans le code généré par les agents est résolue sur le plan architectural, mais le défi reste de choisir des contrôles qui protègent la sécurité sans ralentir le développement.