Les environnements virtuels Python : virtualenv et virtualenvwrapper 23


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. Pour les gens comme moi qui veulent quelque chose qui marche partout, tout le temps et facilement, il y a virtualenv.

Installation et usage

Première chose à faire, 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:

virtualenv /path/vers/projet/env_nom_du_projet

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.

23 thoughts on “Les environnements virtuels Python : 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”

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.