Files
training.python.beginner/documentation/99-more-virtualenv.md
Steve Kossouho 77aa231f5b Update first chapters and new questions
Updated first chapter slides.
Added new questions in the new training section.
2025-07-07 21:18:04 +02:00

12 KiB
Raw Permalink Blame History

title, author, mainfont
title author mainfont
Exporter un environnement Python Steve Kossouho Source Sans Pro

Exporter un environnement virtuel entre deux machines

Ou comment recréer un environnement virtuel sans devoir réinstaller toutes les dépendances à la main…


Exporter l'environnement virtuel

Les environnements virtuels sont contenus dans des dossiers, et sont généralement dépendants du système sur lequel ils sont créés :

  • L'exécutable bin/python y est un lien symbolique vers l'interpréteur Python qui a servi à créer l'environnement (version, OS, architecture processeur)
  • les paquets externes écrits en C, et qui sont donc compilés, ne sont utilisables que sur une configuration spécifique (par exemple. Linux sur x86/64 Python 3.11, ou Windows sur ARM64 Python 3.12, ou Linux x86/32 Python 3.9 etc.); une release d'un tel paquet va générer de nombreuses variantes, et une seule version de Numpy existe actuellement dans 44 variantes.

Il serait rare qu'une simple copie du répertoire d'environnement virtuel permette de le réutiliser ailleurs.


…Et d'ailleurs, il existe une bien meilleure idée, beaucoup plus économe en efforts :

pip propose justement un moyen d'échanger une liste des dépendances installées dans l'environnement virtuel, pour pouvoir très simplement les réinstaller sur un autre système. Cette liste est appelée fichier de dépendances, ou requirements.txt. Elle est très souvent fournie avec des projets Python, justement pour en simplifier le partage et la réutilisation.


pip freeze --local > requirements.txt

Dans le terminal de votre projet (si votre environnement virtuel est activé, ce qui est le cas dans PyCharm), cette commande génère un fichier texte, requirements.txt qui contiendra une liste des paquets installés dans votre environnement ainsi que leur version.


Sur votre système cible, vous pouvez ensuite réimporter ce fichier et installer toutes les dépendances qui y sont inscrites avec cette commande :

pip install -r requirements.txt

Elles seront installées dans l'environnement virtuel actuellement activé. (pensez bien à l'y créer et à l'activer si besoin !)


Créer manuellement un environnement virtuel

Pour créer un environnement virtuel Python, dans un terminal, tapez :

python -m venv <nom du nouveau dossier venv>

Le dossier créé contiendra un répertoire bin (scripts sous Windows) et un répertoire lib.


Comment activer/désactiver un environnement virtuel

Vos environnements virtuels possèdent un sous-répertoire bin. Pour activer et utiliser automatiquement votre environnement virtuel, il faut se rendre dans le dossier bin et taper dans un terminal :

source ./activate  # ou activate.csh ou activate.fish

Sous Windows, vous devez plutôt simplement exécuter une commande:

./scripts/activate.ps1  # Dans le powershell si vous êtes dans le répertoire du venv

(ça peut être activate.fish si votre shell utilise fish, et ainsi de suite...) Votre invite de commande devrait contenir un nouvel élément, au moins entre parenthèses, vous indiquant que l'environnement virtuel est bien activé et utilisé.


Pour ensuite désactiver cet environnement virtuel, il vous suffit, dans le terminal où l'environnement est activé, de saisir :

deactivate

L'invite de commande du shell ne contiendra plus l'ajout indiquant que votre environnement est actuellement utilisé. (Quand PyCharm active automatiquement un venv, la commande deactivate{.bash} est indisponible)


Comment uniquement télécharger des paquets externes pour les machines déconnectées ?

Effectivement, vous pourriez vouloir créer un environnement où des machines nécessitant des paquets Python n'ont pas accès à internet. Dans ce cas, il est possible d'utiliser pip pour utiliser un répertoire comme dépôt en remplacement de PyPI. Ce répertoire peut être un répertoire réseau, par exemple, si vous avez au moins accès au réseau local.


Dans l'ordre, pour appliquer une telle mesure, vous pouvez :

  • Utiliser le fichier de dépendances pour télécharger les archives des paquets nécessaires
  • Placer les archives dans un dossier accessible sur le réseau (ou localement)
  • Utiliser pip sur la machine cible, en précisant de ne pas utiliser PyPI mais notre dossier

pip download -r requirements.txt

Attention, ça va tout télécharger dans le répertoire en cours !


Sur la machine cible, il ne vous reste plus qu'à utiliser pip et lui dire d'aller chercher les paquets depuis le répertoire local ou réseau :

pip install -r requirements.txt --no-index --find-links=file://chemin/repertoire

Si vous souhaitez créer un dépôt compatible avec PyPI, il vous suffit de créer un projet Python et d'installer dans votre environnement virtuel le paquet pypiserver. Il est très simple à utiliser, et cet article chez Linode sur les dépôts pour pip devrait vous aider à y voir plus clair.


Bonus : PyCharm et la gestion de vos dépendances

PyCharm est capable de remplir automatiquement votre fichier requirements.txt (possiblement avec la version) en analysant le code de votre projet.

Remplissage automatique des dépendances


Dans le menu ToolsSync python requirements (vous pouvez aussi utiliser le raccourci Shift + Shift pour rechercher rapidement l'entrée de menu), PyCharm vous offre un raccourci pour mettre à jour votre fichier de dépendances, conformément aux imports que vous avez utilisés dans votre code.

Il vous faudra préciser le chemin du fichier requirements.txt à mettre à jour, puis configurer la façon dont vous voudrez que PyCharm remplisse les dépendances (intégrer le numéro de version, supprimer les dépendances non utilisées, etc.)


Extra : Gérer des paquets selon l'environnement

Selon la topologie dans laquelle vous évoluez (contraintes de sécurité incluses, ex. VPN), vous pouvez être amené à organiser vos projets de plusieurs manières. Du plus simple au plus difficile :

  1. Projets Python sur un dépôt Git public
  2. Projets Python sur un dépôt Git privé (SSH etc.)
  3. Projets Python packagés dans un dépôt brut sur un répertoire réseau monté
  4. Projets Python packagés dans un serveur pip.

Dépendances

Lorsque votre projet nécessite d'utiliser des bibliothèques Python pour fonctionner, il est rappelé qu'il est une bonne pratique de fournir avec celui-ci un fichier de dépendances. Ce fichier s'appelle par convention requirements.txt. Il contient la référence de toutes les bibliothèques que vous utilisez, dans la version dont vous avez besoin.

# Exemples de bibliothèques
ipython==8.15.0  # console Python avancée
pyside6==6.5.2  # Qt Framework

Une fois ce genre de fichier décrit, il est possible d'installer les dépendances qu'il référence avec la commande pip install -r requirements.txt.


Dépôt Git public

Le fichier de dépendances de votre projet, si vous avez accès à celles-ci, peut contenir des entrées vers des branches ou des commits de projets présents sur un dépôt Git. Par exemple, si vous souhaitez inclure Django==3.2.0, vous pouvez rédiger une entrée similaire au contenu suivant :

# L'entrée est utilisée comme option d'un pip install
git+https://github.com/django/django.git@3.2

Dépôt Git privé

Si votre entrée provient d'une usine logicielle et que votre dépôt est privé, l'entrée de votre fichier de dépendances reste la même, mais vous devrez peut-être posséder des identifiants pour y accéder. En général, autoriser une clé SSH configurée sur votre machine de développement sera nécessaire, mais probablement la seule étape nécessaire.


Dossier monté

Monter un dossier distant consiste à rendre disponible localement l'accès à un répertoire présent sur une machine à distance (généralement un NAS).

Il est possible de demander à l'outil pip de télécharger et d'installer des paquets disponibles sur le protocole file://, à condition d'utiliser l'option pip install -r requirements.txt --find-links=file:///path/to/dir.

Les paquets proposés par vos collègues doivent être installables par pip et les archives (aux formats .tar.gz et .whl) doivent être disponibles dans ce répertoire. Voir le protocole officiel pour la création de paquets Python


Imports dynamiques

Il peut arriver que, lors de la création d'une bibliothèque, un développeur doive s'adapter à des situations où certains imports ne seront pas disponibles. Un cas extrême serait d'introduire l'utilisation de pathlib (disponible uniquement dans Python 3.4+), alors que votre bibliothèque est censée pouvoir fonctionner dans un environnement Python 2.7.

Techniquement, c'est une mauvaise idée de s'y prendre ainsi, mais si le choix n'est pas permis, il faut passer par certaines stratégies.


Imports alternatifs

La façon la plus connue de venir à bout de la possibilité d'utiliser des imports différents selon l'environnement consiste à utiliser la gestion d'exceptions :

try:
    import package1
    print("Package1 importé !")
except ImportError:
    print("Erreur lors de l'importation de package1.")
    try:
        import package2
        print("Package2 importé !")
    except ImportError:
        print("Erreur lors de l'importation de package2.")
        exit()

Une autre façon plus contrôlée, mais plus rarement vue en production, consiste à interroger la version de l'interpréteur pour choisir quel package ou module importer :

# Récupère un objet représentant l'interpréteur Python
from sys import version_info

if version_info.major == 3:
    import pathlib
    filename = pathlib.Path("/home/demo/readme.txt").parent
else:
    from os import path
    filename = path.dirname("/home/demo/readme.txt")

Imports dynamiques par nom

Vous pouvez, en Python, importer un module ou un package par son nom complet. La méthode fonctionne aussi bien dans Python 2 que Python 3 .

Elle est un peu compliquée à utiliser, et accepte plusieurs arguments :

path = __import__("os.path", globals(), locals(), ["basename", "join"], 0)
basename = path.basename
join = path.join

Imports depuis des répertoires personnalisés

Lorsque vous avez des modules dans des répertoires personnalisés, vous pouvez ajouter lesdits répertoires au PYTHONPATH :

import sys

# Ajouter le répertoire au PYTHONPATH
sys.path.append("/home/new_path/root")
import mon_module  # dans le répertoire

Configurations

Lire des informations sous la forme de fichiers .ini :

import configparser

data = configparser.ConfigParser().read("/home/demo/file.ini")

Variables d'environnement

Une technique utilisée dans certains projets pour configurer certaines options (mots de passe, clés d'API) consiste à créer un fichier de configuration, que certaines bibliothèques peuvent charger et appliquer aux variables d'environnement (variables stockées par le système d'exploitation, différentes de la base de registre Windows)