Les environnements virtuels Python : venv, virtualenv et virtualenvwrapper 35


Quand on commence à beaucoup programmer, on accumule rapidement plusieurs projets en cours de développement sur sa machine. Certains vieux, certains récents, qui utilisent tous des bibliothèques similaires, mais pas forcément de mêmes versions. Ou parfois des bibliothèques incompatibles. Parfois même, des version différentes de Python: Python 2.6, 2.7, 3.2 ? Et c’est sans compter les mises à jour de l’OS, qui a ses propres besoins en terme de libs et de versions.

Le jour où ça casse, c’est le chaos.

Dans le monde de Python, la solution à ce problème est d’utiliser des environnements virtuels. Ca à l’air d’un gros mot, mais derrière ce terme se cache la notion simple d’avoir des installations de Python isolées de l’OS, et séparées les unes des autres pour chaque projet.

Il existe plusieurs écoles: certains utilisent buildout. C’est une solution puissante, et très compliquée. Python 3.3 vient avec venv, un outil intégré pour gérer les environnements virtuels, qui peut être installé séparément sur les versions plus anciennes sous le nom de virtualenv.

Installation et usage

Vérifiez si vous avez virtualenv déjà installé:

$ python -m venv
usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]
            [--upgrade] [--without-pip]
            ENV_DIR [ENV_DIR ...]
venv: error: the following arguments are required: ENV_DIR

Si cette commande ne marche pas, il faudra installer virtualenv:

pip install --user virtualenv

Si vous avez besoin d’un rappel sur pip, c’est par là.

Ensuite, pour chacun de vos projets, créez un environnement virtuel, avec:

python -m venv /path/vers/projet/env_nom_du_projet

Si vous l’aviez déjà. Ou:

virtualenv /path/vers/projet/env_nom_du_projet

Si vous venez de l’installer. Les deux commandes sont interchangeables.

Virtualenv va créer un dossier avec un environnement complet dedans: l’interpreteur Python, les libs, des commandes, etc. C’est votre installation isolée.

Pour travailler dans votre installation isolée:

  • sous Unix, il faut faire source /path/vers/projet/env_nom_du_projet/bin/activate.
  • sous Windows, il faut faire C:\\path\vers\projet\env_nom_du_projet\Scripts\activate.bat.

Votre prompt de ligne de commande va changer pour indiquer que vous êtes dans un environnement virtuel:

(env_nom_du_projet) sam $

Si vous installez une bibliothèque avec pip, il l’installera dans cet environnement virtuel, et elle ne sera pas accessible ailleurs. Si vous lancez la commande python, le shell Python aura accès à toutes les libs de cet environnement virtuel.

Vous pouvez sortir de l’environnement virtuel avec la commande deactivate.

Creez autant de virtualenv que vous voulez: un par projet, un pour les tests de nouvelles libs, un pour le plaisir, un pour la route… Ca prend juste de la place, et ce n’est pas ce qui manque sur nos disques durs de nos jours.

Quelques astuces avec virtualenv

Isolation par rapport à l’OS

Vous pouvez choisir que votre env hérite des libs de l’OS, ou non, mais uniquement à la création. Il faut spécifier une option:

  • --no-site-packages: votre environnement est vierge, il n’hérite pas des libs du système et a seulement accès aux libs standards de Python (os, sys, itertools, json, etc).
  • --system-site-packages: tout ce qui est installé sur l’OS est disponible dans installé dans l’env (et sera installé à l’avenir). Par exemple sous Ubuntu, vous pourrez importer toutes les libs d’UbuntuOne, le système de synchronisation Cloud d’Ubuntu écrit en Python.

Les anciennes versions ont la valeur --system-site-packages activée par défaut, les nouvelles versions de virtualenv ont la valeur --no-site-packages activée par défaut.

Si vous utilisez --system-site-packages, vous pouvez quand même demander à pip freeze de lister uniquement les libs de l’env avec l’option --local.

Choisir une version de Python

Parfois vous voudrez utiliser une version spécifique de Python. Vous pouvez tout à fait créer un env dédié à Python 3.2 et un autre à Python 2.6, il faut juste que les deux versions soient installées sur votre système.

Je ne vais pas détailler commen installer deux versions de Python en parallèle sur chaque OS car je n’ai aucune idée de comment on fait sous Mac ou Windows, mais sous Ubuntu c’est très simple: par défaut on est en Python 2.7, et pour installer Python 3, on fait sudo apt-get install python3. Pour installer Python 2.6, on fait sudo apt-get python2.6.

On a alors 3 executables: /usr/bin/python va déclencher Python 2.7, /usr/bin/python2.6 va appeler Python 2.6, etc. Aucun conflit système, c’est merveilleux.

Il ne reste qu’à construire son environnement virtuel en lui passant en paramètre le chemin vers le Python à utiliser:

virtualenv mon_env -p /usr/bin/python2.6

Et voilà, si on active “mon_env”, la commande python ouvre un shell en Python 2.6, et toutes les libs de l’env sont en 2.6.

Attention: on ne peut pas reconvertir facilement un env d’une version de Python à l’autre. Une fois que c’est créé, c’est fait. Si vous changez d’avis, faite un pip freeze, supprimez l’env, recréé l’env, et faites un pip install -r.

Virtualenv depuis un script extérieur

Si vous êtes dans un script extérieur et que vous voulez appeler un de vos scripts avec ce virtualenv, vous n’avez pas besoin de l’activer pour que ça marche. Il suffit d’appeler le script en le passant en paramètre à l’interpréteur de l’env. Par exemple:

/path/vers/projet/env_nom_du_projet/bin/python mon_script.py

Le script sera alors exécuté dans le cadre du virtualenv.

virtualenvwrapper: ou comment ne pas se faire chier pour passer d’un env à l’autre

Si vous êtes sous Windows, vous pouvez aller boire une bière à la cuisine, ça ne marche pas sous votre OS.

Pour les chanceux qui ont accès à un Unix, il existe un merveilleux logiciel qui va vous éviter le yoyo entre les envs:

pip install --user virtualenvwrapper

Ensuite il faut rajouter quelques lignes dans votre script d’init de shell, par exemple dans ~/.bashrc:

export WORKON_HOME=~/.virtualenvs
mkdir -p $WORKON_HOME
source ~/.local/bin/virtualenvwrapper.sh

Selon où vous avez installé virtualenvwrapper, la dernière ligne peut changer. Moi, mon virtualenv est installé au niveau du système dont le chemin est plutôt /usr/local/bin/virtualenvwrapper.sh.

Ces lignes vont lancer virtualenvwrapper en permanence dans le shell. Relancez le terminal pour l’activer. Le premier lancement va vous afficher un tas de lignes, rassurez-vous, ça n’arrive qu’une fois.

Ensuite, vous avez accès à de nouvelles commandes:

  • mkvirtualenv nom_env va créer un virtualenv dans le dossier ~/.virtualenvs, où que vous soyez.
  • workon nom_env va automatiquement activer un env, où que vous soyez.
  • rmvirtualenv nom_env va surpprimer l’env du même nom.

Les options de mkvirtualenv sont les mêmes que pour la commande virtualenv, vous n’avez juste plus à vous souciez de où sont vos envs, ni de où vous êtes.

35 thoughts on “Les environnements virtuels Python : venv, virtualenv et virtualenvwrapper

  • DSeed

    pip install -r : ca sert à koi ?
    Un rapport avec l’installation des paquets présent dans pip freeze ?

    J’utilise un fichier requirements.txt pour énumérer mes paquets installé et donc sauvé mon environnement et puis après pour installé l’ensemble je fais :

    pip install -r requirements.txt

    ET MERCI POUR CETTE ARTICLE (mm si je connais déjà un peu virtualenv ça fait du bien un petit rappel et compléments ;)

  • Oyo

    cdvirtualenv dans le même genre est bien pratique. Une fois workon myenv fait, il permet de changer de répertoire pour celui de l’environnement. Et celle-ci qui à l’occasion est utile: cdsitepackages.

  • Sam Post author

    @Soli: tampon de bonne guerre :-)
    @Oyo: wow, je connaissais pas cdsitepackages, c’est génial. Je vais tout le temps regarder le code source de Django.
    @DSeed: oui.

  • Étienne

    Perso, j’utilise des VM. Ça permet aussi d’isoler le postgresql/mysql, d’isoler aussi la distribution, etc.

    Un .img, c’est facile à sauvegarder/restaurer.

    Et quand on ne veut pas développer avec sa machine, on a pas de postgresql ou de supervisord qui tourne pour rien.

  • Sam Post author

    C’est bien mais:

    – on rajoute en complexité (gérer les VM soi-même, ça demande beaucoup de connaissance, sauf si on se lance dans le cloud, ce que tout le monde ne peut/veut pas faire)
    – une VM ça suppose copier toute l’image, ce qui peut prendre vachement de temps si l’image est grosse, alors que juste installer un système peut être très rapide
    – une VM bouffe de la puissance
    – ça ne résout pas le problème d’utilisation de plusieurs projets sur la même machine: on ne va pas faire deux VM sous prétexte qu’on a deux petits sites incompatibles sur la machine

    Dans tous les cas je suis vraiment pour l’utilisation massive de MV, mais ce n’est pas encore la panacée.

  • David

    Petite question sur la partie “Choisir une version de Python” :
    Sur mon Ubuntu le apt-get install python2.6 n’est pas dispo. Donc je l’ai fais à la main :
    wget http://www.python.org/ftp/python/2.6/Python-2.6.tgz
    tar -zxvf Python2.6.tar.gz
    cd Python2.6
    ./configure
    make
    make install

    Par contre je n’ai pas de dossier python2.6 dans /usr/bin/ donc impossible de faire virtualenv mon_env -p /usr/bin/python2.6

  • David

    Oui il semblerait que se soit dans /usr/local/bin/python2.6
    Je m’en suis sorti à coup de ln un peu partout, j’avais pas le choix

  • Kévin

    Salut,

    J’ai une petite question par rapport à virtualenv. Alors déjà désolé si ma question peut parraitre débile, je me suis mis à Python depuis peu.

    Alors la question c’est quelle est la manière standard de gérer les environnement virtuel avec git ?

    Je m’expllique, j’ai commencé un petit projet Flask, dont la structure est la suivante :
    testFlask
    |– app
    |– flask_env
    |– run.py
    `– temp

    Est ce que je dois commit mon flask_env sur mon repot git ou bien c’est une mauvaise pratique ? Parce que je ne sais pas comment c’est organisé a l’intérieur, est ce que les chemin vers les libs que j’ai installé sont hard codés ou pas etc.

    Dans la doc de pip, j’ai lu l’histoire du pip freeze > requirement.txt, n’est-ce pas mieux de juste mettre ça sur le repo git ?

    Merci bien !

  • Sam Post author

    Oui. On ne commit pas son virtualenvenv. On commit le fichier requirements.txt.

  • Morkav

    Déso je déterre un peu l’article. J’ai pu lire ici que virtualenv c’est pas du feu avec python3 du coup il y a pyvenv. Qu’en pensez vous ? Quels sont les différences selon vous ?

    Cimer pour le super taffe !

  • Sam Post author

    C’est juste que virtualenv est intégré à Python 3 sous la forme de la commande pyenv, donc pas besoin de l’installer.

  • Sam Post author

    Pyenv, c’est comme tous les trucs copiés du monde ruby : c’est crade. Notament, pyenv remplace le références des exécutables Python par des faux éxécutables pour fonctionner. Ca peut avoir des tas de conséquences inattendues qui ne se révèlent pas dans l’usage de tous les jours, mais une nuit à 3h du mat sur ce petit cas précis et improbable la veille de la démo client.

  • Morkav

    Ok, merci pour ces précisions ! Pour Pyenv, tu as regardé dans les sources pour voir ca ?

  • Darzok

    Je suis novice avec Python, je trouve votre poste intéressant mais cependant j’ai quelques questions :

    ou puis retrouver l’ensemble des environnements virtuel créé ? car lorsque que je me met dans mon home et que je créer un nouvelle environnement je ne le trouve pas avec un ls…. ça me déroute un peu ^^ ou se cache t-il non d’un pip !

    puis avec virtualenvwraper, comment créer un environnement en spécifiant la version de python que je souhaite utiliser ?

  • Sam Post author

    Vos questions trouverons réponse dans les premiers paragraphes de la partie “virtualenvwrapper: ou comment ne pas se faire chier pour passer d’un env à l’autre” et “Choisir une version de Python”

  • GeoJulien

    A noter que depuis les dernières évolutions de virtualenv, le dossier bin n’existe plus et l’arbo d’un environnement virtuel contient 3 dossiers : Include, Lib et Scripts. Voir http://virtualenv.readthedocs.org/en/latest/userguide.html#windows-notes

    De plus, la dernière version est compatible powershell mais demande une augmentation de privilèges : http://virtualenv.readthedocs.org/en/latest/userguide.html#activate-script (note bleue en bas)

    Enfin, j’ai eu la mauvaise surprise de ne pas pouvoir lancer de UI pourtant créée avec Tkinter. On obtient le message “This probably means that Tcl wasn’t installed properly”. Il faut copier manuellement le sous-dossier ‘tcl’ de l’installation de Python dans le dossier de l’environnement virtuel. Voir : http://stackoverflow.com/a/30377257

    Je parle de Python 2.7.9+, c’est donc peut-être différent avec 3.x.

  • Sam Post author

    @GeoJulien: le dossier bin est toujours là, mais sous Mac et Linux. Il s’appelle en effet “script” sous Windows.

  • ninou

    et comment on fait quand on veut travailler avec différentes versions de h5py dans différents environnements mais aussi avec différentes versions de librairies libhdf5 ? h5py n’installe que la couche python et non la librairie sous jacente.

    donc est-ce que je peux faire un make;make install de la librairie et qu’elle puisse s’installer dans mon virtualenv et non au niveau du système ?

    merci

  • Sam Post author

    Ca c’est pas une question Python, c’est une question soit de C, soit de sysadmin. Dans tous les cas, mauvais blog :)

  • ast

    Je viens de tester virtualenv sous windows. L’environnement virtuel n’est effectif que dans la fenêtre de commande où l’on a lancé le activate.bat, or il est quasi impossible de travailler dans cette fenêtre DOS-like. SI j’ouvre IDLE ou si je double click sur un py, j’ai pas l’env virtuel. L’ideal serait que tout le PC passe d’un environnement à un autre.

  • Sam Post author

    Non, le but de l’environnement virtuel est d’avoir une activation ponctuelle de cet environnement. Si on l’applique à tout l’OS, ça retirerait tout l’interêt. Mais on peut lancer un fichier en particulier dans l’environnement virtuel en utilisant le chemin complet vers l’executable de Python qui est dans le dossier de l’env. Un bon éditeur, bien entendu, vous permettra de faire confortablement depuis son interface.

  • Majeri Lud

    Salut, Merci pour cette article au combien intéressant. Je code sous pycharm qui intègre deja les environements virtuel mais je cherche maintenant un moyen de synchronisation de mes fichier python/env sur plusieurs machine. Actuellement j’utilise juste un repertoire google drive mais je rencontre qq probleme de lock lors de la synchro. Est ce qu’il y aurait une solution simple pour partager mes env/fichier entre plusieurs machine. ( sans passer un systeme style git ou encore pythonanywhere. merci

  • Sam Post author

    Moi j’utilise un système de déploiement + git, doc quand je vais sur une autre machine, je git pull, et j’up mon deploiement. Du coup aucune idée pour ton use case.

  • Andronaute

    Merci pour ta réponse. Je pense que j’ai pas le choix. Je vais voir du coté de git en mode payant. Sinon c’est quoi ce que tu appel “un système de déploiement”. Parce que si tu utilise git, tu clone ton depot non ? tu te retrouve avec tes fichiers en local tout simplement. Je suis pas un expert de git juste les notions de base, j’ai manqué qq chose ? Mon but était simplement de pouvoir travailler de chez moi qd je fais de grosse insomnie !!

  • Sam Post author

    Git va récupérer le code source, mais après un site c’est plus que du code : tu as les données de la base, les services, etc.

  • Sam Post author

    Oui maintenant c’est l’inverse, par défaut on a pas accès à site-package, et il faut le demander avec --system-site-packages

Leave a comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.