diff --git a/chapters/portability.qmd b/chapters/portability.qmd index 33d1a01..677a943 100644 --- a/chapters/portability.qmd +++ b/chapters/portability.qmd @@ -20,30 +20,48 @@ pour afficher les slides en plein écran. -# La notion de portabilité +# Introduction : la notion de portabilité -Dans les chapitres précédents, nous avons vu un ensemble de bonnes pratiques qui permettent de considérablement améliorer la qualité d'un projet : rendre le code plus lisible, adopter une structure du projet normalisée et évolutive, et versionner proprement son code sur un dépôt `GitHub`. +Dans les chapitres précédents, nous avons vu un ensemble de bonnes pratiques qui permettent de considérablement améliorer la qualité d'un projet : rendre le code plus lisible, adopter une structure du projet normalisée et évolutive et versionner proprement son code sur un dépôt `GitHub`. -Une fois ces bonnes pratiques appliquées à notre projet, ce dernier apparaît largement partageable. Du moins en théorie, car la pratique est souvent plus compliquée : il y a fort à parier que si vous essayez d'exécuter votre projet sur un autre environnement d'exécution (un autre ordinateur, un serveur, etc.), les choses ne se passent pas du tout comme attendu. Cela signifie que qu'**en l'état, le projet n'est pas portable : il n'est pas possible, sans modifications coûteuses, de l'exécuter dans un environnement différent de celui dans lequel il a été développé**. +Une fois ces bonnes pratiques appliquées à notre projet, ce dernier apparaît largement partageable. Du moins en théorie, car la pratique est souvent plus compliquée : il y a fort à parier que si vous essayez d'exécuter votre projet sur un autre environnement d'exécution (un autre ordinateur, un serveur, etc.), les choses ne se passent pas du tout comme attendu. Cela signifie que qu'**en l'état, le projet n'est pas [portable]{.colorized} : il n'est pas possible, sans modifications coûteuses, de l'exécuter dans un environnement différent de celui dans lequel il a été développé**. -La principale raison est qu'un code ne vit pas dans une bulle isolée, il contient en général de nombreuses adhérences, plus ou moins visibles, au langage et à l'environnement dans lesquels il a été développé : +La raison principale est qu'un code ne vit pas dans une bulle isolée, il contient en général de nombreuses adhérences, plus ou moins visibles, au langage et à l'environnement dans lesquels il a été développé : -- des dépendances dans le langage du projet ; -- des dépendances dans d'autres langages (ex : `NumPy` est écrit en `C` et nécessite donc un compilateur `C`) ; -- des librairies systèmes nécessaires pour installer certains _packages_ -(par exemple, les librairies de cartographie dynamique comme `Leaflet` ou `Folium` -nécessitent la librairie système `GDAL`), -qui ne seront pas les mêmes selon le système d'exploitation utilisé. +- des __dépendances `Python`__ propres au langage du projet. C'est l'environnement des _packages_ nécessaires à exécuter le code ; +- des __dépendances dans d'autres langages__ nécessaires au fonctionnement de certaines librairies `Python`. En effet, `Python` est un langage de haut niveau et certains _packages_ nécessitent des librairies bas-niveau pour être efficaces. Par exemple, `NumPy` est écrit en `C` et nécessite donc un compilateur `C` et `Pytorch` a quant à lui besoin de `C++` ; +- des __dépendances à des librairies systèmes__ nécessaires pour installer certains _packages_ +qui ne seront pas les mêmes selon le système d'exploitation utilisé et certains paramètres matériels (par exemple, selon que Windows utilise une version 32 ou 64 bits). Par exemple, les librairies +de manipulation ou de visualisation de données spatiales (`GeoPandas`, `Folium`) reposent sur des librairies systèmes `GDAL` qui sont propres à chaque système d'exploitation[^wheels]. -Si le premier problème peut être géré relativement facilement en adoptant une [structure de projet](XXXXXX) et en spécifiant bien les différentes dépendances utilisées, par exemple avec un fichier -`requirements.txt`, les deux autres nécessitent en général des outils plus avancés. +[^wheels]: Nous reviendrons plus tard sur la manière dont la mise à disposition de _packages_ sous forme précompilée par le biais de _wheels_ offre une solution à ce problème. -Ces outils vont nous permettre de **normaliser l'environnement afin de produire un projet portable**, i.e. exécutable sur une large variété d'environnements d'exécution. Cette étape est primordiale lorsque l'on se préoccupe de la mise en production d'un projet, car elle assure une transition relativement indolore entre l'environnement de développement et celui de production. +Le premier problème peut être géré relativement facilement en adoptant une structure de projet ([chapitre précédent](/chapters/projects-architecture.qmd)) avec un fichier +`requirements.txt` bien structuré et versionné. +Les deux autres nécessitent en général des outils plus avancés. -![](https://img.devrant.com/devrant/rant/r_174386_yx6zV.jpg){fig-align="center"} +Nous allons progresser dans la démarche de reproductibilité en visant un projet +portable, c'est-à-dire qui peut être +exécuté dans un environnement différent de celui dans lequel il a été développé. -_Image empruntée à [devrant.com}(https://devrant.com/rants/174386/when-i-say-but-it-works-on-my-machine)_ +Nous allons avoir besoin de nouveaux outils qui +seront, chacun, des avancées sur l'échelle de la +reproductibilité: +* Les environnements virtuels ; +* Les conteneurs + +Ces outils vont nous permettre de **normaliser l'environnement afin de produire un projet portable**, Cette étape est primordiale lorsque l'on se préoccupe de la mise en production d'un projet, car elle assure une transition relativement indolore entre l'environnement de développement et celui de production. + +![Image empruntée à [devrant.com](https://devrant.com/rants/174386/when-i-say-but-it-works-on-my-machine)](https://img.devrant.com/devrant/rant/r_174386_yx6zV.jpg){fig-align="center"} + +Le choix de la méthode à privilégier dépend d'un arbitrage temps-opportunité. Tous les projets +n'ont pas vocation à être mis à disposition par +le biais de conteneurs. Néanmoins, +l'intérêt d'adopter une démarche de bonnes +pratiques est que si le projet gagne en ambition +et que la conteneurisation s'avère adéquate, celle-ci +sera peu coûteuse à mettre en oeuvre. # Les environnements virtuels 🐍 @@ -52,15 +70,26 @@ _Image empruntée à [devrant.com}(https://devrant.com/rants/174386/when-i-say-b Pour illustrer l'importance de travailler avec des environnements virtuels, mettons-nous à la place d'un.e aspirant.e *data scientist* qui commencerait ses premiers projets. -Selon toute vraisemblance, on va commencer par installer une distribution de `Python` — souvent, via `Anaconda` — sur son poste et commencer à développer, projet après projet. Dans cette approche, les différents *packages* qu'on va être amené à utiliser vont être installés au même endroit. Cela pose plusieurs problèmes : +Selon toute vraisemblance, on va commencer par installer une distribution de `Python` — souvent, via `Anaconda` — sur son poste et commencer à développer, projet après projet. S'il est nécessaire d'installer une librairie supplémentaire, on le fera sans trop se poser de question. Puis, on passera au projet suivant en adoptant la même démarche. Et ainsi de suite. + +Cette démarche naturelle présentera l'avantage de permettre d'aller vite dans les expérimentations. +Néanmoins, elle deviendra problématique s'il devient +nécessaire de partager son projet, ou de reprendre celui-ci dans le futur. + +Dans cette approche, les différents *packages* qu'on va être amené à utiliser vont être installés au même endroit. Ceci peut apparaître secondaire, après tout nous utilisons `Python` pour sa simplicité d'usage qui ne nécessite pas de passer des heures à se poser des questions avant d'écrire la moindre ligne de code, mais cela va finir par nous poser plusieurs problèmes : -- **conflits de version** : une application A peut dépendre de la version 1 d'un package là où une application B peut dépendre de la version 2 de ce même package. Une seule application peut donc fonctionner dans cette configuration ; +- **conflits de version** : une application A peut dépendre de la version 1 d'un package là où une application B peut dépendre de la version 2 de ce même package. Ces versions d'un même package peuvent avoir des incompatibilités[^release]. Une seule application peut donc fonctionner dans cette configuration ; - **version de `Python` fixe** — on ne peut avoir qu'une seule installation par système — là où on voudrait pouvoir avoir des versions différentes selon le projet ; - **reproductiblité limitée** : difficile de dire quel projet repose sur tel package, dans la mesure où ceux-ci s'accumulent en un même endroit au fil des projets ; -- **portabilité limitée** : conséquence du point précédent, il est difficile de fixer dans un fichier les dépendances spécifiques à un projet. +- **portabilité limitée** : conséquence du point précédent, il est difficile de fixer dans un fichier les dépendances spécifiques à un projet, et exclusivement celles-ci. Les environnements virtuels constituent une solution à ces différents problèmes. +[^release]: S'il est impossible de suivre les évolutions de tous les _packages_ de la _data science_, +il est recommandé de faire une veille sur les principaux comme `Pandas` ou `Scikit` en suivant +les _release notes_ des versions majeures qui introduisent +généralement des non-compatibilités. + ## Fonctionnement Le concept d'environnement virtuel est techniquement très simple. @@ -77,15 +106,49 @@ On peut donc simplement voir les environnements virtuels comme un moyen de faire Il existe différentes implémentations des environnements virtuels en `Python`, dont chacune ont leurs spécificités et leur communauté d'utilisateurs : * L'implémentation standard en `Python` est `venv`. -* Dans le domaine de la *data science*, l'implémentation la plus courante est sans doute `conda`. +* `conda` propose une implémentation plus complète. + +En pratique pour les utilisateurs, ces implémentations sont relativement proches. La différence conceptuelle majeure est que `conda` est à la fois un *package manager* (comme `pip`) et un gestionnaire d'environnements virtuels (comme `venv`). + +Pendant longtemps, `conda` en tant que *package manager* s'est avéré très pratique en *data science*, dans la mesure où il gérait non seulement les dépendances `Python` mais aussi dans d'autres langages, comme des dépendances `C`, très utilisées +par les principales librairies de _data science_ et dont l'installation peut être complexe sur certains systèmes d'exploitation. Néanmoins, depuis quelques années, l'installation de _packages_ par `pip` se fait de plus en plus par le biais de [_wheels_](https://pythonwheels.com/) qui sont des versions pré-compilées des librairies systèmes, propres à chaque configuration système. + +::: {.callout-note collapse="true"} +## Une différence conceptuelle entre `pip` et `conda` -En pratique, ces implémentations sont relativement proches. La différence majeure est que `conda` est à la fois un *package manager* (comme `pip`) et un gestionnaire d'environnements virtuels (comme `venv`). +L'autre différence majeure avec `pip` est que `Conda` utilise une méthode plus avancée — et donc également plus coûteuse en temps — de résolution des dépendances. -Pendant longtemps, `conda` en tant que *package manager* s'est avéré très pratique en *data science*, dans la mesure où il gérait non seulement les dépendances `Python` mais aussi dans d'autres langages — comme des dépendances `C`. L'autre différence majeure avec `pip` est que Conda utilise une méthode plus avancée — et donc également plus coûteuse en temps — de résolution des dépendances[^2]. En effet, différents packages peuvent spécifier différentes versions d'un même package dont ils dépendent tous les deux, ce qui provoque un conflit de version. Conda va par défaut appliquer un algorithme qui vise à gérer au mieux ces conflits, là où `pip` va choisir une approche plus minimaliste. Enfin, la *distribution* `Anaconda`, qui contient à la fois `Python`, `conda` et beaucoup de *packages* utiles pour la *data science*, explique également cette popularité auprès des *data scientists*. +En effet, différents packages peuvent spécifier différentes versions d'un même package dont ils dépendent tous les deux, ce qui provoque un conflit de version. `Conda` va par défaut appliquer un algorithme qui vise à gérer au mieux ces conflits, là où `pip` va choisir une approche plus minimaliste[^2]. +::: + +[^2]: Le _solver_ de `conda`, qui est un algorithme de recherche de chemin optimal dans des graphes pour gérer +les (in)compatibilités de versions, est +lourd à mettre en oeuvre. Le projet [`mamba`](https://mamba.readthedocs.io/en/latest/) a permis d'offrir +une réimplémentation de `Conda` en `C++` par le biais d'un _solver_ plus efficace. Cela a permis de franchement accélérer la vitesse d'installation des _packages_ par le biais de `conda`. Néanmoins, +l'accès de plus en plus fréquent à des [_wheels_](https://pythonwheels.com/) a permis un retour en grâce des environnements virtuels implémentés par `venv` au cours des dernières années. + +`pip+venv` présente l'avantage de la simplicité, `conda` de la fiabilité. Selon les projets, on +privilégiera l'un ou l'autre. Néanmoins, si +le projet est amené à fonctionner de manière isolée +dans un conteneur, `venv` suffira amplement car +l'isolation sera fournie par le conteneur comme +nous le verrons ultérieurement. + +::: {.callout-note collapse="true"} +## C'est différent en {{< fa brands r-project >}} ? + +On lit souvent, notamment chez les _afficionados_ de {{< fa brands r-project >}} que la gestion des environnements en `Python` est chaotique. C'était vrai au début des années 2010 mais c'est quelques peu exagéré aujourd'hui. + +La qualité supérieure des outils {{< fa brands r-project >}} pour la gestion des dépendances ne saute pas aux yeux: [`renv`](https://rstudio.github.io/renv/articles/renv.html) est très intéressant mais [ne permet pas de définir la version de +{{< fa brands r-project >}}](https://rstudio.github.io/renv/articles/renv.html#caveats) : + +> R version: renv tracks, but doesn’t help with, the version of R used with the packge. renv can’t easily help with this because it’s run inside of R, but you might find tools like rig helpful, as they make it easier to switch between multiple version of R on one computer. + +C'est, en fait, le problème principal des outils {{< fa brands r-project >}} pour la reproductibilité. Pour les utiliser, il faut souvent se trouver dans une session {{< fa brands r-project >}}, avec ses spécificités. Les outils {{< fa brands python >}} qui s'utilisent pas le biais de la ligne de commande offrent une robstusse plus importante. +::: -[^2]: La lenteur de l'installation des packages dans les environnements `conda` par rapport à `pip` et l'accès de plus en plus fréquent à des [_wheels_](https://pythonwheels.com/) a permis un retour en grâce des environnements virtuels implémentés par `venv`. Une autre alternative populaire est [`mamba`](https://mamba.readthedocs.io/en/latest/), une réimplémentation de `Conda` en `C++` qui utilise un _solver_ bien plus efficace. En proposant celui-ci, le projet `mamba` vise à pallier l'un des irritants principaux de `conda`, à savoir la lenteur du _solver_. +Puisqu'il n'y a pas de raison absolue d'imposer `pip+venv` ou `conda`, nous recommandons le pragmatisme. Personnellement, nous utilisons plutôt `venv` car nous travaillons principalement dans des microservices basés sur des conteneurs et non sur des postes personnels, ce qui est l'approche moderne dans le monde de la _data science_. Nous présentons néanmoins les deux approches par la suite. -Pour toutes ces raisons, nous allons présenter l'utilisation de `conda` comme gestionnaire d'environnements virtuels. Les principes présentés restent néanmoins valides pour les autres implémentations. ## Conda diff --git a/styles.css b/styles.css index 4e1776f..c887739 100644 --- a/styles.css +++ b/styles.css @@ -3,6 +3,10 @@ /*--title-color: #870511 ;*/ } +.colorized { + color: var(--main-color) ; +} + /* h1, h2 {