PROJET AUTOBLOG


Sam & Max: Python, Django, Git et du cul

Site original : Sam & Max: Python, Django, Git et du cul

⇐ retour index

Mise à jour

Mise à jour de la base de données, veuillez patienter...

Stack Python en 2019

dimanche 3 février 2019 à 16:10

Suite au très bon billet Débuter avec Python en 2019, je me suis dit qu’il serait bon d’en rajouter une couche.

Après toutes ces années, qu’est-ce que j’utilise pour mes projets Python ?

D’abord, Python 3.6, partout

Pas la 3.5. Pas la 3.7.

La raison est que la 3.6 est un millésime exceptionnel, dans laquelle culminent des années de fixes et goodies. Malgré celà, sortie fin 2016, elle est facile à installer: ça prend quelques minutes sur même une centos 7 via les EPEL, ou sur une ubuntu 16.04 en utilisant le ppa deadsnake.

La 3.7 n’est non seulement pas aussi aisée à déployer, mais elle ne contient pas encore autant de correctifs, et surtout fige les mots clés async / await, créant des surprises. J’admets volontiers que breakpoint(), les dataclasses et asyncio.run() sont très tentants, mais je peux vivre sans.

Donc Python 3.6.

(P.S: django et numpy droppent le support de la 3.4)

Pour déployer, pex et nuikta

Quand j’ai scripts rapides mais pleins de dépendances , fini les virtualenvs et pip install en prod. Je package tout avec pex. En gros, un fichier .pex est un format conçu par twitter l’équivalent d’un .war, que la présentation de Brian Wickman expliquera mieux que moi.

Mais en gros, en très gros, c’est un zip qui contient tout le virtualenv. On fait python mon_projet.pex et ça lance tout. Pas besoin de déploiement compliqué. scp, et c’est prêt. Je ne le recommande pas pour un gros projet web par exemple. Mais pex rend le scripting Python merveilleux, et presque trop facile: plus besoin de s’interdire une dépendance par peur que le serveur ne l’a pas, ou par flemme. Du coup, même le script le plus simple à la puissance de feu de tout pypi, et ça m’a permis de faire des one-shots très complexes en deux coups de cuillères à pot.

Quand je dois livrer un programme chez un client qui ne soit pas Web, je compile tout avec nuikta. Je me fends même parfois d’un installeur nsis au besoin. Demander à autrui d’installer la VM est source de beaucoup de problèmes, et Python est un détail d’implémentation pour beaucoup d’utilisateurs de toute façon.

Gestion de projet: pew et setup.cfg

J’aime poetry, mais la compatibilité avec setuptools est importante à mes yeux. Tout l’écosystème supporte setuptools, tout est bien testé, c’est robuste et sans surprise. J’attendrais que poetry soit stable, testé, bien intégré et surporté. Évidemment, il faudra que pyproject.toml soit suffisamment mature également, et vu l’usage de sections custo pour tous les outils qui l’utilisent, on en est encore loin.

pew est très basique, mais il ne s’occupe que du virtualenv, laissant la gestion de mon projet à mes soins. Il est rapide, et sans chichi, de plus personne dans mon équipe n’a besoin de savoir que je l’utilise.

Après quelques essais, j’ai laissé tomber pipenv, qui a trop de problèmes, et dont l’auteur met des années avant d’entendre raison sur des choses essentielles, sur lesquelles il revient par ailleurs sans mine de repenti. Ça n’en retire rien à Kenneth Reth le mérite des ses travaux, mais j’ai des deadlines.

Outillage

À moins d’avoir été sourd et aveugle, vous avez du noter un certain engouement de la communauté pour black, que je vous ai déjà dis avoir adopté.

Les conséquences sont multiples sur la stack: j’ai viré flake8, et j’ai allégé de nombreuses règles ma configuration pylint, qui est du coup mon seul linter. Faudrait que je fasse un article dessus d’ailleurs.

Mypy étant maintenant stable et utilisable, je l’active par défaut. Ça ne veut pas dire que j’annote tout mon code. Parfois je n’annote rien. Parfois juste quelques fonctions. L’énorme avantage de mypy réside dans le fait que son utilisation est parfaitement progressive, et s’adapte à l’engagement et l’effort que vous voulez y mettre.date mypy est une des rares choses que j’upgrade à tout bout de champ, car chaque update amène une vraie qualité de vie en plus.

J’intègre tout ça dans mon éditeur, et en l’occurence VSCode rend l’opération très facile.

Pour le lanceur de tests, je reste sur pytest, pour des raisons déjà exposées. Honnêtement je ne connais pas de bonnes raisons de ne pas utiliser pytest. J’utilise faker pour générer des fausses données de test. Je n’arrive toujours pas à utiliser hypothesis. J’essaye, mais je n’arrive jamais à l’appliquer sur autre chose qu’un exemple joujou. J’espère y arriver un jour, car je suis certain que c’est excellent.

Pour lancer tout ce bordel, j’utilise tox, mais je ne l’utilise pas sur tous mes projets: seulement les gros avec certaines exigences.

Je n’ai pas de template de projet type. J’ai beaucoup lorgné depuis des années du côté de cookiecutter, je n’arrive pas à me motiver à l’utiliser sérieusement.

Enfin, j’installe toujours jupyter pour tester vite fait mon code, bien que j’utilise plus la console que le notebook. Et sphinx pour la doc.

Frameworks Web

Django (souvent avec django-rest-framework).

J’ai parfois des clients qui exigent flask, et donc je fais du flask. C’est toujours à regret.

Il n’a rien que flask me permette que je ne puisse faire avec Django, mais il y a une tonne de trucs à réimplementer à la main à chaque fois. À documenter. À tester. Tout ça pour changer de projet flask, et tomber sur un nouveau loustic qui a fait les trucs à sa sauce et tout recommencer.

Les projets flask ne sont bien faits que par ceux qui savent déjà très bien mener un projet Web, ce qui n’est pas la majorité des gens qui l’utilisent: en effet, il attire les utilisateurs par la simplificité de son API, et leur donne l’illusion d’être à la hauteur.

flask reste un excellent produit pour l’éducation, ou pour un petit projet vite fait, ce pour quoi je le choisis avec plaisir. Mais la majorité des projets flasks sur lesquels j’ai travaillé n’ont guère le niveau de qualité qu’on rencontre en moyenne dans les projets Python. C’est qu’on s’habitue, à force.

J’essaye aussi d’aimer SQLALchemy, dont je reconnais la flexibilité et la puissance. Mais son ergonomie est pénible, et la gestion des sessions suffisamment tortueuse pour se tirer une balle dans le pied si on cligne trop des yeux. Si j’ai des problèmes de perfs, je fais du SQL à la main de toute façon et j’utilise du cache en masse. Je reste donc sur SQLA seulement si flask, ou hors Web. Et encore, des fois je peeweese.

L’ORM de Django est une aberration en bien des points, sauf un seul. Il est éminemment pratique. Et je sais jusqu’où je peux le pousser: loin, très loin. Max va se gausser en lisant ces lignes, mais je me lasse de la beauté du code et de la pureté (ta gueule mec, arrête sourire, je te vois).

Bref, Django pour les seniors. Django pour les juniors, même si ça prendra plus de temps que flask, mais au moins le framework leur évitera de faire de la merde comme au temps de PHP à la main.

Question async, j’utilise aiohttp mais aussi fais du asyncio à là main, en faisant bien attention aux goto.

Non, je n’utilise pas les trucs du genre sanic, growler, vibora, quart, etc. Si ils sont toujours activement développés dans 3 ans, on en reparle.

Bonne nouvelle ceci dit, la doc d’asyncio est enfin potable, si vous voulez vous y mettre. Mais ça mérite quand même un article.

Ceci dit, les occasions de faire de l’asyncio sont rares. REST reste (hu hu) quand même l’option reine, HTTP2 peut se déployer via proxy et les threads assurent le plus souvent des perfs suffisantes. Pour être parfaitement honnête, j’utilise plus asyncio pour des scripts, daemon, et autres tâches de fond :)

J’ai pas encore mis en prod django channels, ou aWSGI, mais je ne suis pas du tout convaincu par ces solutions, donc j’attends de voir.

J’ai eu l’occasion d’utiliser crossbar un peu plus. L’outils est toujours excellent, mais l’API a changé sans pour autant s’améliorer. Ils se recroquevillent dans l’illusion qu’un produit spécialisé dans l’IoT est une bonne stratégie, mais c’est une voie de garage à mes yeux. Le vrai potentiel est dans le Web. Je me fais à l’idée que le projet n’attendra jamais son potentiel tant que personne n’écrit une surcouche, et que ce ne sera pas tavendo qui le fera.

En parlant de tâche de fond, je reste sur du celery, surtout depuis que je sais qu’on peut l’utiliser avec presque zero config. C’est le moins pire des systèmes. De toute façon j’ai presque toujours un redis sous la main, c’est bien trop facile et pratique pour s’en passer.

Libs

Les libs changent constamment, partant et venant selon la nécessité des projets. Au mieux puis-je vous dire ce que j’irais chercher si j’avais cette problématique.

Dates: pendulum.

Validation de données: marshmallow.

cli: click. Ça me fait mal de le dire, car je suis pas fan du style des APIs d’Armin (l’objet request global de flask, sérieux…), mais quand il fait un truc, on est sûr que ça marche. J’ai eu trop de limitations avec les alternatives.

Gestion du pognon: money.

Lib graphique: wxPython. Je fais du QT sur demande client, mais c’est trop gros pour des projets de moyenne taille.

Encoding: toujours chardet et unidecode.

Manipulation d’images: pillow.

Calculs numériques: numpy. À mon niveau je n’ai jamais besoin de scipy ou pandas.

Pour le parsing de conf je fais de plus en plus de toml, mais j’ai pytoml est pas terrible. Je vous ferai un retour sur contoml qui, si tout se passe bien, devrait être mon futur default.

Pour convertir du code Python 2 vers Python 3, python future et backport.

Pour faire du templating, jinja2.

Pour l’internationalization, babel.

Hors de Python

Git. Vue. Webpack. Ubuntu.

J’évite docker comma la peste, même si certains clients le veulent à tout prix. Je fais du react, généralement sous la torture.

Pas grand-chose à dire de plus.

Error happened! 0 - count(): Argument #1 ($value) must be of type Countable|array, null given In: /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php:428 http://ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/?Stack-Python-en-2019 #0 /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php(999): VroumVroum_Blog->update() #1 /var/www/ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/index.php(1): require_once('...') #2 {main}