# 12. Environnements virtuels et paquets

## 12.1. Introduction

Les programmes Python utilisent souvent des paquets et modules qui ne font pas partie de la bibliothèque standard. Ils nécessitent aussi, parfois, une version spécifique d’une bibliothèque, par exemple parce qu’un certain bug a été corrigé ou encore que le programme a été implémenté en utilisant une version obsolète de l’interface de cette bibliothèque.

Cela signifie qu’il n’est pas toujours possible, pour une installation unique de Python, de couvrir tous les besoins de toutes les applications. Basiquement, si une application A dépend de la version 1.0 d’un module et qu’une application B dépend de la version 2.0, ces dépendances entrent en conflit et installer la version 1.0 ou 2.0 laisse une des deux applications incapable de fonctionner.

La solution est de créer un environnement virtuel, un dossier auto-suffisant qui contient une installation de Python pour une version particulière de Python ainsi que des paquets additionnels.

Différentes applications peuvent alors utiliser des environnements virtuels différents. Pour résoudre l’exemple précédent où il existe un conflit de dépendances, l’application A a son environnement virtuel avec la version 1.0 installée pendant que l’application B a un autre environnement virtuel avec la version 2.0. Si l’application B requiert que la bibliothèque soit mise à jour à la version 3.0, cela n’affecte pas l’environnement de A.

## 12.2. Création d’environnements virtuels

Le module utilisé pour créer et gérer des environnements virtuels s’appelle `venv`. `venv` installe en général la version de Python la plus récente dont vous disposez. Si plusieurs versions de Python sont sur votre système, vous pouvez choisir une version particulière en exécutant `python3.X` où X indique la version de votre choix.

Pour créer un environnement virtuel, décidez d’un dossier où vous voulez le placer et exécutez le module `venv` comme un script avec le chemin du dossier :

    python3 -m venv tutorial-env

Cela crée le dossier `tutorial-env` (s’il n’existe pas) et des sous-dossiers contenant une copie de l’interpréteur Python, de la bibliothèque standard et quelques autres fichiers utiles.

Une fois l’environnement virtuel créé, vous pouvez l’activer.

Sur Windows, lancez :

    tutorial-env\Scripts\activate.bat

Sur Unix et MacOS, lancez :

    source tutorial-env/bin/activate

(Ce script est écrit pour le shell bash. Si vous utilisez csh ou fish, utilisez les variantes `activate.csh` ou `activate.fish`.)

Activer l’environnement virtuel change le prompt de votre ligne de commande pour afficher le nom de l’environnement virtuel que vous utilisez. Cela modifie aussi l’environnement afin, lorsque vous tapez `python`, d’exécuter la version spécifique de Python installée dans l’environnement. Par exemple :

    $ source ~/envs/tutorial-env/bin/activate
    (tutorial-env) $ python
    Python 3.5.1 (default, May  6 2016, 10:59:36)
      ...
    >>> import sys
    >>> sys.path
    ['', '/usr/local/lib/python35.zip', ...,
    '~/envs/tutorial-env/lib/python3.5/site-packages']
    >>>

## 12.3. Gestion des paquets avec pip

Vous pouvez installer, mettre à jour et supprimer des paquets en utilisant un programme appelé pip. Par défaut, `pip` installe les paquets du Python Package Index, <https://pypi.org>. Vous pouvez parcourir le Python Package Index avec un navigateur ou utiliser la fonction de recherche (assez) limitée de `pip` :

    (tutorial-env) $ pip search astronomy
    skyfield               - Elegant astronomy for Python
    gary                   - Galactic astronomy and gravitational dynamics.
    novas                  - The United States Naval Observatory NOVAS astronomy library
    astroobs               - Provides astronomy ephemeris to plan telescope observations
    PyAstronomy            - A collection of astronomy related tools for Python.
    ...

`pip` a plusieurs sous-commandes : `search`, `install`, `uninstall`, `freeze`, etc. Consultez le guide Installation de modules Python pour une documentation exhaustive sur `pip`.

Vous pouvez installer la dernière version d’un paquet en indiquant son nom :

    (tutorial-env) $ pip install novas
    Collecting novas
      Downloading novas-3.1.1.3.tar.gz (136kB)
    Installing collected packages: novas
      Running setup.py install for novas
    Successfully installed novas-3.1.1.3

Vous pouvez installer une version spécifique d’un paquet en donnant le nom du paquet suivi de `==` et du numéro de version souhaitée :

    (tutorial-env) $ pip install requests==2.6.0
    Collecting requests==2.6.0
      Using cached requests-2.6.0-py2.py3-none-any.whl
    Installing collected packages: requests
    Successfully installed requests-2.6.0

Si vous relancez cette commande, `pip` remarque que la version demandée est déjà installée et ne fait rien. Vous pouvez fournir un numéro de version différent pour récupérer cette version ou lancer `pip install --upgrade` pour mettre à jour le paquet à la dernière version :

    (tutorial-env) $ pip install --upgrade requests
    Collecting requests
    Installing collected packages: requests
      Found existing installation: requests 2.6.0
        Uninstalling requests-2.6.0:
          Successfully uninstalled requests-2.6.0
    Successfully installed requests-2.7.0

`pip uninstall` suivi d’un ou plusieurs noms de paquets les supprime de votre environnement virtuel.

`pip show` affiche des informations à propos d’un paquet précis :

    (tutorial-env) $ pip show requests
    ---
    Metadata-Version: 2.0
    Name: requests
    Version: 2.7.0
    Summary: Python HTTP for Humans.
    Home-page: http://python-requests.org
    Author: Kenneth Reitz
    Author-email: me@kennethreitz.com
    License: Apache 2.0
    Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages
    Requires:

`pip list` liste tous les paquets installés dans l’environnement virtuel :

    (tutorial-env) $ pip list
    novas (3.1.1.3)
    numpy (1.9.2)
    pip (7.0.3)
    requests (2.7.0)
    setuptools (16.0)

`pip freeze` produit une liste similaire des paquets installés mais l’affichage adopte un format que `pip install` peut lire. La convention habituelle est de mettre cette liste dans un fichier `requirements.txt` :

    (tutorial-env) $ pip freeze > requirements.txt
    (tutorial-env) $ cat requirements.txt
    novas==3.1.1.3
    numpy==1.9.2
    requests==2.7.0

Le fichier `requirements.txt` peut alors être ajouté dans un système de gestion de versions comme faisant partie de votre application. Les utilisateurs peuvent alors installer tous les paquets nécessaires à l’application avec `install -r` :

    (tutorial-env) $ pip install -r requirements.txt
    Collecting novas==3.1.1.3 (from -r requirements.txt (line 1))
      ...
    Collecting numpy==1.9.2 (from -r requirements.txt (line 2))
      ...
    Collecting requests==2.7.0 (from -r requirements.txt (line 3))
      ...
    Installing collected packages: novas, numpy, requests
      Running setup.py install for novas
    Successfully installed novas-3.1.1.3 numpy-1.9.2 requests-2.7.0

`pip` reconnait beaucoup d’autres options, documentées dans le guide Installation de modules Python. Lorsque vous avez écrit un paquet, si vous voulez le rendre disponible sur PyPI, lisez le guide Distribuer des modules Python.