Python moderne, partie 1 : création du projet avec pyenv & poetry
By BRAZA Faouzi
9 juin 2021
Ne ratez pas nos articles sur l'open source, le big data et les systèmes distribués, fréquence faible d’un email tous les deux mois.
L’apprentissage d’un langage de programmation se structure souvent autour de points essentiels : pratiquer la syntaxe du langage, en maîtriser le style, comprendre certains principes et paradigmes sous-jacents pour en exploiter tout le potentiel (e.g., programmation procédurale, orientée objet ou fonctionnelle). Avec un peu de temps et beaucoup de pratique, vous êtes prêt à exploiter vos nouvelles compétences pour écrire des programmes informatiques capables de résoudre de nouveaux problèmes.
Cependant, la maîtrise d’un langage ne fera pas de vous un ingénieur accompli. En effet, un aspect souvent sous-estimé, est d’être capable d’établir un environnement de travail qui respecte les bonnes pratiques en ingénierie logicielle, améliore votre productivité tout en facilitant la collaboration avec vos tiers. Adaltas gère plusieurs projets open-source et encourage les contributions extérieures. Beaucoup de ces projets son écrits pour Node.js. Fort de cette expérience, que nous avons établi des bonnes pratiques nécessaires à la gestion de nos projets écrits en Node.js.
Python est un autre langage utilisé au sein de l’entreprise par nos consultants. La gestion des packages, leur maintenance, et la maîtrise des outils disponibles dans l’écosystème Python sont souvent décris comme lourds, peu flexibles et difficiles à l’usage. Récemment de nombreux projets open-source ont émergé dans l’écosystème de Python et proposent justement de faciliter la mise en place d’un environnement de travail complet pour gérer vos projets Python. Ici nous présentons deux d’entre eux : Pyenv, qui facilite l’installation et la gestion de plusieurs versions de Python sur votre machine, et Poetry, qui permet de gérer et organiser vos packages et environnement virtuels afin d’établir un environnement de travail efficace et productif.
Cet article est le premier d’une série de trois dans laquelle nous partageons nos meilleures pratiques concernant la gestion de projet Python :
- Partie 1 : création d’un projet avec pyenv et poetry
- Partie 2 : tests unitaires et respect des conventions Git commit
- Partie 3 : Intégration continue avec GitHub Actions et publication sur PiPy
Pre-requis
Installation de pyenv
Pour installer pyenv
, assurez vous d’avoir les dépendances nécessaires et spécifiques à votre système d’exploitation. Celles-ci sont requises par pyenv
pour installer Python en compilant les fichiers sources. Ainsi pour Ubuntu/Debian installez les packages suivant :
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev \
libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python-openssl
Pour connaître les dépendances spécifiques à votre système d’exploitation, jetez un coup d’œil à la documentation. Une fois fait, vous pouvez installer pyenv
. Pour cela je vous recommence d’utiliser pyenv-installer qui automatise l’ensemble de l’installation.
curl https://pyenv.run | bash
Avec pyenv
vous pouvez installer la version de Python que vous souhaitez. Utilisez la commande suivante pour connaître les versions disponibles à l’installation :
pyenv install --list
Pour notre démonstration, installons les versions 3.7.10
, 3.8.7
, 3.9.2
:
pyenv install 3.7.10
Downloading Python-3.7.10.tar.xz...
-> https://www.python.org/ftp/python/3.7.10/Python-3.7.10.tar.xz
Installing Python-3.7.10...
Installed Python-3.7.10 to /home/fbraza/.pyenv/versions/3.7.10
Une fois installées, listons l’ensemble des versions présentes sur notre machine :
pyenv versions
* system
3.7.10
3.8.7
3.9.2
pyenv
identifie plusieurs versions : celles que nous venons d’installer ainsi que la version utilisée par le système d’exploitation (system
). Le signe *
avant system
indique la version active sur la machine hôte, actuellement la version déployée par le système. pyenv
gère les versions de Python à différents niveaux : global ou local. Définissons la version 3.7.10
comme version globale :
pyenv global 3.7.10
Listons à nouveaux les versions présentes :
pyenv versions
system
* 3.7.10 (set by /home/<username>/.pyenv/version)
3.8.7
3.9.2
Vous pouvez voir que la version 3.7.10
est notre version globale avec son chemin d’accès entre parenthèses. Intéressons nous brièvement au fonctionnement de pyenv
. Pour chaque version installée, pyenv
génère un chemin d’accès associé à son exécutable. Lorsque vous utilisez une commande Python ou exécutez un programme, pyenv
capture les commandes exécutées, détermine quelle version de Python utiliser puis passe les commandes à la bonne version de Python.
Changer la version globale n’affectera pas les processus exécutés par votre version système. La version système correspond à la version de Python utilisée par défaut dans votre système d’exploitation afin d’exécuter un ensemble de taches bien précises. Ne changez jamais votre version système ! Celle-ci évolue et est mise à jour avec votre système d’exploitation. La version globale définie par
pyenv
exécutera les commandes issues de vos programmes Python.
Installation de poetry
L’outil Poetry vous permet de gérer les packages Python et leur dépendances. Il a un rôle similaire au classique fichier setup.py
ou à l’outil pipenv. Poetry est néanmoins plus flexible et offre plus de fonctionnalités. En effet ; vous pouvez préalablement déclarer l’ensemble des dépendances nécessaires à votre projet dans un fichier pyproject.toml
pour ensuite laisser poetry
les installer et assurer leur mises à jour. Enfin vous pouvez, à l’aide de poetry
, publier votre package sur Pypi.
Terminons la mise en place des pré-requis avec l’installation de poetry
sur notre système :
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
Création de notre projet Python
Voyons dans cette partie comment créer un projet Python pour ensuite l’isoler dans un environnement virtuel en utilisant pyenv
et poetry
.
Définir la version de Python avec Pyenv
Créons le répertoire my_awesome_project
:
mkdir my_awesome_project && cd $_
Une fois dans le répertoire, définissons une version locale de Python pour votre projet à l’aide de pyenv
. Ceci obligera poetry
à utiliser cette version locale et non la version globale. Voici la commande :
pyenv local 3.8.7
Cette commande crée un fichier .python-version
détecté par pyenv
. Par conséquent tout fichier Python ou répertoire projet crées à partir de ce point, dépendra de la version locale définie par pyenv
.
Créer notre projet avec poetry
Poetry propose une interface en ligne de commande robuste et facile d’utilisation qui vous permet de créer, configurer et mettre à jour votre projet Python et ses dépendances. Pour créer votre projet, exécutez la commande suivante :
poetry new <project_name>
Cette commande génère une structure par défaut. Le contenu de notre nouveau projet est le suivant :
.
├──
│ └── __init__.py
├── pyproject.toml
├── README.rst
└── tests
├── __init__.py
└── test_.py
Notez la présence du fichier pyproject.toml
. C’est dans ce fichier que sont définis les méta-données, les dépendances ainsi que les scripts de votre projet. Pour ceux déjà familier avec l’écosystème de Node.js, pyproject.toml
est l’équivalent Python du fichier package.json
.
[tool.poetry]
name = "your_project_name"
version = "0.1.0"
description = ""
authors = ["<username> <email address>"]
[tool.poetry.dependencies]
python = "^3.8"
[tool.poetry.dev-dependencies]
pytest = "^5.2"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
Plusieurs sections sont présentes par défaut :
[tool.poetry]
: cette section contient les méta-données de votre package. Vous pouvez y spécifier le nom de votre package, une description courte du package, des détails concernant l’auteur du package, sa version de développement etc…Tout ces informations sont optionnelles sauf si vous décidez de publier votre package sur Pypi.[tool.poetry.dependencies]
: cette section contient l’ensemble des dépendances nécessaires au fonctionnement de votre package. Vous pouvez y spécifier la version d’installation de chaque package (packageX = "1.0.0"
). La version de Python utilisée est également déclarée dans cette section.python = "^3.8"
définit la version minimum requise pour faire fonctionner votre package. Celle-ci a été définit localement avecpyenv
.[tool.poetry.dev-dependencies]
: cette section contient l’ensemble des dépendances nécessaires au développement du package. Ces dépendances ne sont pas requises pour faire fonctionner votre package et par conséquent ne sont pas téléchargées lors de son installation.[build-system]
: A moins que vous souhaitez mettre à jour la version depoetry
, ne touchez pas cette section.
Vous trouverez l’ensemble des sections disponibles pour votre fichier
pyproject.toml
ici.
Installer et activer l’environnement virtuel
Deux approches sont possibles : soit vous connaissez à l’avance l’ensemble de vos dépendances et vous pouvez donc les ajouter à votre fichier pyproject.toml
maintenant, soit vous les ajoutez progressivement. Dans notre cas nous les ajouterons plus tard. Ainsi nous pouvons initialiser notre projet et créer un environnement Python virtuel. Pour cela exécutons la commande suivante :
poetry install
Creating virtualenv summarize-dataframe-SO-g_7pj-py3.8 in ~/.cache/pypoetry/virtualenvs
Updating dependencies
Resolving dependencies... (6.4s)
Writing lock file
Package operations: 8 installs, 0 updates, 0 removals
• Installing pyparsing (2.4.7)
• Installing attrs (20.3.0)
• Installing more-itertools (8.7.0)
• Installing packaging (20.9)
• Installing pluggy (0.13.1)
• Installing py (1.10.0)
• Installing wcwidth (0.2.5)
• Installing pytest (5.4.3)
Installing the current project: summarize_dataframe (0.1.0)
Tout d’abord, cette commande installe l’environnement virtuel puis le stocke en dehors de notre projet, de manière similaire à ce que peut proposer l’utilitaire conda
. En effet, plutôt que de créer un répertoire local dans notre projet contenant toutes les dépendances Python (comme le fait virtualenv
), poetry
stocke l’environnement sur un chemin global de votre système (.cache/
par défaut). Ceci permet d’isoler votre projet de ses dépendances.
Vous pouvez néanmoins configurer
poetry
pour installer les environnements virtuels localement dans votre projet Python. Jetez un œil à la documentation si c’est ce que vous souhaitez.
Ensuite poetry
va lire le contenu de votre fichier pyproject.toml
et installer les dépendances spécifiées. Par défaut et si non spécifié, poetry
télécharge puis installe la dernière version de chaque dépendance. À la fin de cette opération, poetry
crée un fichier poetry.lock
qui contient une liste de toutes les dépendances installées avec leur versions respectives. Gardez à l’esprit que, maintenant, le fichier poetry.lock
passe en priorité par rapport à ce qui est définit dans votre fichier pyproject.toml
. Pensez à toujours partager votre fichier poetry.lock
sur Git. Ceci permettra à vos collaborateurs de télécharger votre package et d’en installer les dépendances facilement.
Nous pouvons maintenant activer notre environnement virtuel :
peotry shell
Spawning shell within ~/.cache/pypoetry/virtualenvs/summarize-dataframe-SO-g_7pj-py3.8
. ~/.cache/pypoetry/virtualenvs/summarize-dataframe-SO-g_7pj-py3.8/bin/activate
Cette commande active votre environnement et crée un processus Shell sous-jacent qui hérite du processus parent sans avoir la capacité de le modifier. Ceci permet d’encapsuler et d’isoler complètement votre environnement virtuel.
Créer un référentiel Git
Pour finir créons un référentiel Git pour notre projet :
git init
git remote add origin https://github.com/fbraza/summarize_dataframe.git
echo ".*\n!.gitignore" > .gitignore
echo "# your_project_name" > README.md
git add .
git commit -m "build: first commit. Environment built"
git push -u origin master
Conclusion
pyenv
et poetry
sont deux outils qui permettent de mettre en place rapidement un environnement de travail Python pour votre projet. pyenv
permet de gérer les versions de Python installées sur votre machine et de définir celles que vous souhaitez utiliser localement dans vos projets. poetry
permet d’initialiser son projet et de l’encapsuler dans un environnement virtuel avec l’ensemble de ses dépendances. L’utilisation de poetry
fluidifie et facilite grandement la mise en place d’un projet tout en respectant les conventions définies dans l’index Python Enhancement Proposals avec notamment la création du fichier pyproject
proposé par la convention PEP 518.
Dans notre prochain article nous commencerons à définir notre projet et en écrire les lignes de code. Nous verrons comment (i) ajouter des dépendances à notre avec poetry
, (ii) écrire des test unitaires puis les exécuter avec poetry
et enfin (iii) mettre en place et assurer le respect des bonnes pratiques de rédaction de nos message de commits git
.
Pense-bête
pyenv
- Lister les version de Python disponibles
pyenv install --list
- Définir la version globale de Python
pyenv global <version_id>
- Définir la version local de Python
pyenv local <version_id>
poetry
- Créer un projet
poetry new <project_name>
- Installez les dépendances et créer l’environnement virtuel
poetry install
- Activer l’environnement
poetry shell