Tom Daluzeau
← Parcours Python · système
Python · système · leçon 1 / 8Ch. 4 · Python et le système12 minTerminée

venv, pip et variables d'environnement

Isoler les paquets d'un projet dans un venv, figer leurs versions dans requirements.txt, lire une variable d'environnement avec os.environ et savoir pourquoi un secret n'a rien à faire dans le code ni dans git.

Mis à jour le

À recouper avec le cours. Cette leçon a été écrite à partir du plan du chapitre, avant relecture avec les supports. En cas de doute, le cours fait foi.

Pourquoi on voit ça

Jusqu’ici, ton outil de vérification du parc n’utilisait que ce que Python fournit de base. Dès qu’il doit appeler une API ou envoyer une alerte, il lui faut un paquet externe comme requests, et un secret : un token, une URL de webhook.

Deux questions arrivent alors. Où installer les paquets pour que l’outil marche pareil sur ta machine, sur celle d’un collègue et sur le serveur ? Et où ranger le secret pour qu’il ne se retrouve pas dans git ? Les réponses sont le venv et les variables d’environnement. C’est la base de tout projet Python en DevOps.

Un venv : une boîte de paquets par projet

Sans venv, pip install installe les paquets pour tout le système. Trois ennuis :

  • deux projets peuvent avoir besoin de deux versions différentes du même paquet ;
  • tu risques de casser des outils du système qui dépendent de Python ;
  • tu ne sais plus quels paquets appartiennent à quel projet.

Un venv (environnement virtuel) est un dossier qui contient son propre python et son propre pip. Tout ce que tu installes va dedans, et seulement dedans. Pense à une caisse à outils par chantier, au lieu d’un seul atelier où tout se mélange.

Python du système /usr/bin/python3 pip du système outils de l'OS on n'y installe rien projet-a/.venv python pip requests==2.32.3 les paquets du projet A projet-b/.venv python pip requests==2.28.0 une autre version, à côté (.venv) $ pip install requests
Chaque projet a sa boîte. Avec le venv actif, pip n'installe que dedans : le Python du système reste intact.

Créer, activer, installer

python -m venv .venv
source .venv/bin/activate
pip install requests
Commande Ce qu’elle fait Quand
python -m venv .venv crée le dossier .venv une fois par projet
source .venv/bin/activate active le venv dans ce terminal à chaque nouveau terminal
pip install requests installe le paquet dans le venv quand il te faut un paquet
deactivate quitte le venv quand tu as fini

Sous Windows, l’activation s’écrit .venv\Scripts\activate.

Quand le venv est actif, l’invite du terminal commence par (.venv). C’est ton repère : sans ce préfixe, pip install vise le système.

Créer n’est pas activer. Si tu crées le venv sans l’activer, tes commandes python et pip restent celles du système.

Le dossier .venv ne va pas dans git. Il est gros, il dépend de ta machine, et il se reconstruit en une commande. On l’ajoute au fichier .gitignore.

requirements.txt : la liste des paquets

Puisque le venv ne voyage pas, il faut faire voyager la liste de ce qu’il contient.

pip freeze > requirements.txt

pip freeze affiche chaque paquet installé avec sa version exacte. Le > du shell écrit cette sortie dans le fichier. Résultat, par exemple :

certifi==2026.1.4
requests==2.32.3
urllib3==2.3.0

Tu y trouves requests, mais aussi les paquets dont requests a lui-même besoin.

Versions épinglées

Le == épingle la version : une seule version possible, la même pour tout le monde.

Ligne Ce que pip installe
requests==2.32.3 exactement la 2.32.3
requests>=2.0 la plus récente à partir de la 2.0
requests la plus récente, quelle qu’elle soit

Sans épinglage, l’outil qui marche aujourd’hui peut casser dans six mois, quand une nouvelle version du paquet sort. Avec, l’installation est reproductible.

Réinstaller ailleurs

Sur une autre machine, ou dans un venv tout neuf :

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Le -r dit à pip de lire la liste dans le fichier. Ne confonds pas les deux sens :

  • pip freeze > requirements.txt : du venv vers le fichier ;
  • pip install -r requirements.txt : du fichier vers le venv.
ta machine .venv pip freeze > requirements.txt dépôt git seule la liste voyage le .venv ne voyage pas machine du collègue .venv neuf pip install -r requirements.txt
pip freeze descend du venv vers le fichier, pip install -r remonte du fichier vers un venv neuf.

os.environ : lire une variable d’environnement

Une variable d’environnement est une valeur que le shell transmet au programme qu’il lance. On la définit avec export :

export FLEET_ENV=prod
python fleetcheck.py

Côté Python, os.environ se lit comme un dictionnaire. Tu retrouves donc les deux écritures de la leçon sur les collections.

Écriture Si la variable existe Si elle manque À utiliser pour
os.environ["X"] sa valeur KeyError une variable obligatoire
os.environ.get("X") sa valeur None une variable facultative
os.environ.get("X", "dev") sa valeur "dev" une variable avec valeur par défaut

Avec FLEET_ENV=prod défini et FLEET_TOKEN absent :

import os

print(os.environ["FLEET_ENV"])
print(os.environ.get("FLEET_TOKEN"))
print(os.environ.get("FLEET_REGION", "eu"))
print(os.environ["FLEET_TOKEN"])
prod
None
eu
KeyError: 'FLEET_TOKEN'

Une valeur lue dans l’environnement est toujours une chaîne. Avec export FLEET_TIMEOUT=5, os.environ["FLEET_TIMEOUT"] vaut "5", pas 5. Pour calculer, convertis avec int().

Les secrets : jamais dans le code, jamais dans git

Un secret est une valeur qui donne un accès : un token d’API, un mot de passe, une URL de webhook. Une URL de webhook est bien un secret : quiconque la connaît peut poster des messages dans ton canal d’alerte.

Pourquoi ne pas l’écrire dans le script ?

  • Le code part dans git, et git n’oublie rien. Même si tu effaces la ligne au commit suivant, le secret reste lisible dans l’historique.
  • Tous ceux qui ont accès au dépôt ont alors accès au secret.
  • Pour changer de token, il faudrait modifier le code.

La solution : le code ne contient que le nom de la variable. La valeur reste sur la machine.

Shell export FLEET_WEBHOOK=… Environnement nom = valeur, en texte fleetcheck.py os.environ.get(…) la valeur n'existe que sur la machine, le temps de l'exécution dépôt git : tout le monde le lit, et pour toujours os.environ.get("FLEET_WEBHOOK") le nom de la variable : oui https://hooks…/XXXX la valeur du secret : jamais
Le secret va du shell au programme par l'environnement. git ne voit que son nom.
export FLEET_WEBHOOK="https://hooks.example.com/services/XXXX"
import os

url = os.environ.get("FLEET_WEBHOOK")
if url is None:
    print("pas de webhook : aucune alerte envoyée")
else:
    print("alerte envoyée")

Sans la variable, le code affiche :

pas de webhook : aucune alerte envoyée

Ici, le webhook est facultatif : on utilise get et on teste None. Si le secret était obligatoire, on prendrait les crochets, et le KeyError signalerait tout de suite l’oubli. Dans les deux cas, on n’affiche jamais la valeur du secret, ni avec print ni dans les logs.

À retenir

  • Un venv est un dossier de paquets propre à un projet : python -m venv .venv le crée, source .venv/bin/activate l’active.
  • pip freeze > requirements.txt écrit la liste ; pip install -r requirements.txt la réinstalle.
  • == épingle une version exacte : l’installation est la même partout.
  • On versionne requirements.txt, jamais .venv.
  • os.environ["X"] lève KeyError si la variable manque ; os.environ.get("X") renvoie None. La valeur est toujours une chaîne.
  • Un secret (token, URL de webhook) se lit dans une variable d’environnement : jamais dans le code, jamais dans git.

Entraînement

12 questions, dont 4 à compléter. Tu réponds, on passe à la suivante. La note arrive à la fin.

Cartes · 7

Réviser les cartes ici

Espace : retourner