Add poetry instructions
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details

This commit is contained in:
Fred Pauchet 2021-09-03 22:03:10 +02:00
parent 633352fe4c
commit 3dd773d6d8
2 changed files with 159 additions and 4 deletions

BIN
source/images/xkcd-1987.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

View File

@ -35,11 +35,14 @@ Dans les étapes ci-dessous, nous épinglerons une version LTS afin de nous assu
ne occuperons pas pendant les 3 prochaines années).
==== Environnement virtuel
==== Environnements virtuels
Depuis la version 3.5 de Python, le module `venv` est https://docs.python.org/3/library/venv.html[la manière recommandée] pour créer un environnement virtuel.
.https://xkcd.com/1987
image::images/xkcd-1987.png[]
NOTE: Il existe plusieurs autres modules permettant d'arriver au même résultat, avec quelques avantages et inconvénients pour chacun d'entre eux. Le plus prometteur d'entre eux est https://python-poetry.org/[Poetry], qui dispose d'une interface en ligne de commande plus propre et plus moderne que ce que PIP propose.
Un des reproches que l'on peut faire au langage concerne sa versatilité: il est possible de réaliser beaucoup de choses, mais celles-ci ne sont pas toujours simples ou directes.
Pour quelqu'un qui débarquererait, la quantité d'options différentes peut paraître rebutante.
Nous pensons notamment aux environnements virtuels: ils sont géniaux à utiliser, mais on est passé par virtualenv (l'ancêtre), virtualenvwrapper (sa version améliorée et plus ergonomique), `venv` (la version intégrée depuis la version 3.3 de l'interpréteur, et https://docs.python.org/3/library/venv.html[la manière recommandée] de créer un environnement depuis la 3.5).
Pour créer un nouvel environnement, vous aurez donc besoin:
@ -47,7 +50,59 @@ Pour créer un nouvel environnement, vous aurez donc besoin:
. D'un terminal - voir le point <<../environment/_index.adoc#un-terminal,Un terminal>>
NOTE: Il existe plusieurs autres modules permettant d'arriver au même résultat, avec quelques avantages et inconvénients pour chacun d'entre eux. Le plus prometteur d'entre eux est https://python-poetry.org/[Poetry], qui dispose d'une interface en ligne de commande plus propre et plus moderne que ce que PIP propose.
Poetry se propose de gérer le projet au travers d'un fichier pyproject.toml. TOML (du nom de son géniteur, Tom Preston-Werner, légèrement CEO de GitHub à ses heures), se place comme alternative aux formats comme JSON, YAML ou INI.
[source,bash]
----
La commande poetry new <project> créera une structure par défaut relativement compréhensible:
$ poetry new django-gecko
$ tree django-gecko/
django-gecko/
├── django_gecko
│ └── __init__.py
├── pyproject.toml
├── README.rst
└── tests
├── __init__.py
└── test_django_gecko.py
2 directories, 5 files
----
Ceci signifie que nous avons directement (et de manière standard):
* Un répertoire django-gecko, qui porte le nom de l'application que vous venez de créer
* Un répertoires tests, libellé selon les standards de pytest
* Un fichier README.rst (qui ne contient encore rien)
* Un fichier pyproject.toml, qui contient ceci:
[source,toml]
----
[tool.poetry]
name = "django-gecko"
version = "0.1.0"
description = ""
authors = ["... <...@grimbox.be>"]
[tool.poetry.dependencies]
python = "^3.9"
[tool.poetry.dev-dependencies]
pytest = "^5.2"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
----
La commande `poetry init` permet de générer interactivement les fichiers nécessaires à son intégration dans un projet existant.
NOTE: J'ai pour habitude de conserver mes projets dans un répertoire `~/Sources/` et mes environnements virtuels dans un répertoire `~/.venvs/`.
Cette séparation évite que l'environnement virtuel ne se trouve dans le même répertoire que les sources, ou ne soit accidentellement envoyé vers le système de gestion de versions.
Elle évite également de rendre ce répertoire "visible" - il ne s'agit au fond que d'un paramètre de configuration lié uniquement à votre environnement de développement; les environnements virtuels étant disposables, il n'est pas conseillé de trop les lier au projet qui l'utilise comme base.
Dans la suite de ce chapitre, je considérerai ces mêmes répertoires, mais n'hésitez pas à les modifier.
@ -95,6 +150,106 @@ Cette technique fonctionnera autant pour un poste de développement que sur les
NOTE: Par la suite, nous considérerons que l'environnement virtuel est toujours activé, même si `gwift-env` n'est pas indiqué.
a manière recommandée pour la gestion des dépendances consiste à les épingler dans un fichier requirements.txt, placé à la racine du projet. Ce fichier reprend, ligne par ligne, chaque dépendance et la version nécessaire. Cet épinglage est cependant relativement basique, dans la mesure où les opérateurs disponibles sont ==, <= et >=.
Poetry propose un épinglage basé sur SemVer. Les contraintes qui peuvent être appliquées aux dépendances sont plus touffues que ce que proposent pip -r, avec la présence du curseur ^, qui ne modifiera pas le nombre différent de zéro le plus à gauche:
^1.2.3 (où le nombre en question est 1) pourra proposer une mise à jour jusqu'à la version juste avant la version 2.0.0
^0.2.3 pourra être mise à jour jusqu'à la version juste avant 0.3.0.
...
L'avantage est donc que l'on spécifie une version majeure - mineure - patchée, et que l'on pourra spécifier accepter toute mise à jour jusqu'à la prochaine version majeure - mineure patchée (non incluse 😉).
Une bonne pratique consiste également, tout comme pour npm, à intégrer le fichier de lock (poetry.lock) dans le dépôt de sources: de cette manière, seules les dépendances testées (et intégrées) seront considérées sur tous les environnements de déploiement.
Il est alors nécessaire de passer par une action manuelle (poetry update) pour mettre à jour le fichier de verrou, et assurer une mise à jour en sécurité (seules les dépendances testées sont prises en compte) et de qualité (tous les environnements utilisent la même version d'une dépendance).
L'ajout d'une nouvelle dépendance à un projet se réalise grâce à la commande `poetry add <dep>`:
[source,shell]
----
$ poetry add django
Using version ^3.2.3 for Django
Updating dependencies
Resolving dependencies... (5.1s)
Writing lock file
Package operations: 8 installs, 1 update, 0 removals
• Installing pyparsing (2.4.7)
• Installing attrs (21.2.0)
• Installing more-itertools (8.8.0)
• Installing packaging (20.9)
• Installing pluggy (0.13.1)
• Installing py (1.10.0)
• Installing wcwidth (0.2.5)
• Updating django (3.2 -> 3.2.3)
• Installing pytest (5.4.3)
----
Elle est ensuite ajoutée à notre fichier `pyproject.toml`:
[source,toml]
----
[...]
[tool.poetry.dependencies]
python = "^3.9"
Django = "^3.2.3"
[...]
----
Et contrairement à `pip`, pas besoin de savoir s'il faut pointer vers un fichier (`-r`) ou un dépôt VCS (`-e`), puisque Poetry va tout essayer, [dans un certain ordre](https://python-poetry.org/docs/cli/#add).
L'avantage également (et cela m'arrive encore souvent, ce qui fait hurler le runner de Gitlab), c'est qu'il n'est plus nécessaire de penser à épingler la dépendance que l'on vient d'installer parmi les fichiers de requirements, puisqu'elles s'y ajoutent automatiquement grâce à la commande `add`.
==== Python packaging made easy
Cette partie dépasse mes compétences et connaissances, dans la mesure où je n'ai jamais rien packagé ni publié sur [pypi.org](pypi.org).
Ce n'est pas l'envie qui manque, mais les idées et la nécessité 😉.
Ceci dit, Poetry propose un ensemble de règles et une préconfiguration qui (doivent) énormément facilite(r) la mise à disposition de librairies sur Pypi - et rien que ça, devrait ouvrir une partie de l'écosystème.
Les chapitres 7 et 8 de [Expert Python Programming - Third Edtion](#), écrit par Michal Jaworski et Tarek Ziadé en parlent très bien:
> Python packaging can be a bit overwhelming at first.
> The main reason for that is the confusion about proper tools for creating Python packages.
> Anyway, once you create your first package, you will se that this is as hard as it looks.
> Also, knowing propre, state-of-the-art packaging helps a lot.
En gros, c'est ardu-au-début-mais-plus-trop-après.
Et c'est heureusement suivi et documenté par la PyPA (*https://github.com/pypa[Python Packaging Authority]*).
Les étapes sont les suivantes:
1. Utiliser setuptools pour définir les projets et créer les distributions sources,
2. Utiliser **wheels** pour créer les paquets,
3. Passer par **twine** pour envoyer ces paquets vers PyPI
4. Définir un ensemble d'actions (voire, de plugins nécessaires - lien avec le VCS, etc.) dans le fichier `setup.py`, et définir les propriétés du projet ou de la librairie dans le fichier `setup.cfg`.
Avec Poetry, deux commandes suffisent (théoriquement - puisque je n'ai pas essayé 🤪): `poetry build` et `poetry publish`:
[source,shell]
----
$ poetry build
Building geco (0.1.0)
- Building sdist
- Built geco-0.1.0.tar.gz
- Building wheel
- Built geco-0.1.0-py3-none-any.whl
$ tree dist/
dist/
├── geco-0.1.0-py3-none-any.whl
└── geco-0.1.0.tar.gz
0 directories, 2 files
----
Ce qui est quand même 'achement plus simple que d'appréhender tout un écosystème.
==== Gestion des dépendances, installation de Django et création d'un nouveau projet
@ -571,4 +726,4 @@ La https://docs.djangoproject.com/en/stable/ref/django-admin/#startproject[docum
[source,bash]
----
django-admin.py startproject --template=https://[...].zip <my_project>
----
----