gwift-book/source/part-1-workspace/venvs.adoc

8.9 KiB
Raw Blame History

Travailler en isolation

On va aborder la gestion et lisolation des dépendances. Il est tout à fait possible de sen passer complètement dans le cadre de "petits" projets ou dapplications déployées sur des machines dédiées, et de fonctionner à grand renforts de "sudo" et dinstallation globale des dépendances.

Cette section est aussi utile pour une personne travaillant seule, que pour transmettre les connaissances à un nouveau membre de léquipe ou pour déployer lapplication elle-même.

Cette pratique est cependant fortement déconseillée pour plusieurs raisons:

  1. Il est tout à fait envisagable que deux applications différentes soient déployées sur un même hôte, et nécessitent chacune deux versions différentes dune même dépendance.

  2. Pour la reproductibilité dun environnement spécifique. Cela évite notamment les réponses type "Ca juste marche chez moi", puisque la construction dun nouvel environnement fait partie intégrante du processus de construction et de la documentation du projet; grace à elle, on a la possibilité de construire un environnement sain et dappliquer des dépendances identiques, quelle que soit la machine hôte.

image::images/it-works-on-my-machine.jpg

Depuis la version 3.5 de Python, le module venv est recommandé afin de créer un environnement virtuel.

Il existe plusieurs autres modules permettant darriver au même résultat, avec quelques avantages et inconvénients pour chacun dentre eux.

Note
parler ici de poetry, pip, pipenv et rebondir sur le point 2 des 12 facteurs.

Création de lenvironnement virtuel

Commencons par créer un environnement virtuel, afin dy stocker les dépendances. Placez-vous dans le répertoire dans lequel vous pourrez stocker tous vos environnements (ces environnements sont indépendants des sources; ils peuvent donc être placés nimporte où sur votre disque - évitez peut-être juste de les mettre pile dans le même répertoire que votre code source). Lancez ensuite la commande python3 -m venv gwift-env.

Ceci créera larborescence de fichiers suivante, qui peut à nouveau être un peu différente en fonction du système dexploitation:

fred@aerys:~/Sources/.venvs/gwift-env$ ls
bin  include  lib  lib64  pyvenv.cfg  share

Nous pouvons ensuite lactiver grâce à la commande source gwift-env/bin/activate.

(gwift-env) fred@aerys:~/Sources/.venvs/gwift-env$ (1)
  1. Le shell signale que nous sommes bien dans lenvironnement gwift-env.

Par la suite, nous considérerons que lenvironnement virtuel est toujours activé, même si gwift-env à chaque snippet de code.

A présent que lenvironnement est activé, tous les binaires de cet environnement prendront le pas sur les binaires du système. De la même manière, une variable PATH propre est définie et utilisée, afin que les librairies Python y soient stockées. Cest donc dans cet environnement virtuel que nous retrouverons le code source de Django, ainsi que des librairies externes pour Python une fois que nous les aurons installées.

Pour gérer des versions différentes dune même librairie, il nous suffit de jongler avec autant denvironnements que nécessaires. Une application nécessite une version de Django inférieure à la 2.0 ? On crée un environnement, on lactive et on installe ce quil faut.

Cette technique fonctionnera autant pour un poste de développement que sur les serveurs destinés à recevoir notre application.

Pour désactiver lenvironnement virtuel, il suffit dutiliser la commande deactivate

Installation de Django et création du répertoire de travail

Après avoir activé lenvironnement, on peut à présent y installer Django. Comme expliqué ci-dessus, la librairie restera indépendante du reste du système, et ne polluera aucun autre projet.

Cest parti: `pip install 'django<3.1' !

$ pip install django
Collecting django
    Downloading Django-3.0.5
100% |################################|
Installing collected packages: django
Successfully installed django-3.0.5

Les commandes de création dun nouveau site sont à présent disponibles, la principale étant django-admin startproject. Par la suite, nous utiliserons manage.py, qui constitue un wrapper autour de django-admin.

Pour démarrer notre projet, nous lançons donc django-admin startproject gwift.

$ django-admin startproject gwift

Cette action a pour effet de créer un nouveau dossier gwift, dans lequel on trouve la structure suivante:

$ tree gwift
gwift
├── gwift
|   |── asgi.py
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

Cest sans ce répertoire que vont vivre tous les fichiers liés au projet. Le but est de faire en sorte que toutes les opérations (maintenance, déploiement, écriture, tests, …​) puissent se faire à partir dun seul point dentrée.

Lutilité de ces fichiers est définie ci-dessous:

  • settings.py contient tous les paramètres globaux à notre projet.

  • urls.py contient les variables de routes, les adresses utilisées et les fonctions vers lesquelles elles pointent.

  • manage.py, pour toutes les commandes de gestion.

  • asgi.py contient la définition de linterface ASGI, le protocole pour la passerelle asynchrone entre votre application et le serveur Web.

  • wsgi.py contient la définition de linterface WSGI, qui permettra à votre serveur Web (Nginx, Apache, …​) de faire un pont vers votre projet.

Note
déplacer la configuration dans un répertoire config à part.

Tant quon y est, nous pouvons rajouter les répertoires utiles à la gestion de notre projet, à savoir la documentation, les dépendances et le README:

$ mkdir docs requirements
$ touch docs/README.md
(gwift) fred@aerys:~/Sources$ tree gwift
gwift
├── docs
│   └── README.md
├── gwift
│   ├── asgi.py
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

Gestion des dépendances

Comme nous venons dajouter une dépendance à notre projet, profitons-en pour créer un fichier reprenant tous les dépendances de notre projet. Celles-ci sont normalement placées dans un fichier requirements.txt. Dans un premier temps, ce fichier peut être placé directement à la racine du projet, mais on préférera rapidement le déplacer dans un sous-répertoire spécifique (requirements), afin de grouper les dépendances en fonction de leur utilité:

  • base.txt

  • dev.txt

  • production.txt

Au début de chaque fichier, il suffit dajouter la ligne -r base.txt, puis de lancer linstallation grâce à un pip install -r <nom du fichier>. De cette manière, il est tout à fait acceptable de ninstaller flake8 et django-debug-toolbar quen développement par exemple. Dans limmédiat, on va simplement ajouter django dans une version strictement inférieure à la version 3.1 dans le fichier requirements/base.txt.

$ echo 'django<3.1' > requirements/base.txt
$ echo '-r base.txt' > requirements/prod.txt
$ echo '-r base.txt' > requirements/dev.txt

Prenez directement lhabitude de spécifier la version ou les versions compatibles: les librairies que vous utilisez comme dépendances évoluent, de la même manière que vos projets. Des fonctions sont cassées, certaines signatures sont modifiées, des comportements sont altérés, etc.

Pour être sûr et certain le code que vous avez écrit continue à fonctionner, spécifiez la version de chaque librairie de dépendances.

Avec les mécanismes dintégration continue et de tests unitaires, on verra plus loin comment se prémunir dun changement inattendu.

Matrice de compatibilité

Décrire un fichier tox.ini

$ touch tox.ini

Licence

Décrire une licence ? :-)

$ touch LICENCE

Configuration globale

Décrire le fichier setup.cfg

$ touch setup.cfg

Makefile

Décrire le makefile :)

$ touch Makefile

Structure finale de lenvironnement

Nous avons donc la strucutre finale pour notre environnement de travail:

$ (gwift) fred@aerys:~/Sources/gwift$ tree gwift
gwift
├── docs
│   └── README.md
├── gwift
│   ├── asgi.py
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── Makefile
├── manage.py
├── requirements
│   ├── base.txt
│   ├── dev.txt
│   └── prod.txt
├── setup.cfg
└── tox.ini

3 directories, 13 files