Standards Python - Template Cookiecutter
Contexte
Sans convention partagée, chaque nouveau projet Python démarre différemment : l'un utilise Poetry, l'autre setup.py, un troisième n'a pas de tests, un quatrième a une CI qui lui est propre. Le code fonctionne, mais la maintenance à l'échelle de l'organisation devient coûteuse, chaque projet étant un cas particulier. J'ai mis en place un template Cookiecutter qui impose une structure cohérente dès la création, avec la stack et les workflows qui vont avec.
Trois types de projets, une seule base
Le template distingue trois niveaux de complexité correspondant aux cas réels rencontrés dans les projets CATIE :
- Script
- Module
- Application
Un point d'entrée unique, pas de tests obligatoires, logging basique. Pour les outils utilitaires et les automatisations simples qui ne justifient pas une structure de package complète, mais bénéficient quand même d'un environnement propre et d'un devcontainer.
Structure en src/, suite de tests pytest avec couverture, versionnage automatique par tag Git, publication en wheel et en archive source. C'est le type destiné aux bibliothèques réutilisables et aux outils en ligne de commande (Click). La CI publie automatiquement sur le serveur interne à chaque tag.
Tout ce que contient le module, plus un Dockerfile multi-étapes, un fichier Docker Compose pour le développement local, un chart Helm et une CI/CD complète qui construit, teste, publie l'image et déploie via Helm ou Docker Compose. Pour les services de longue durée et les API.
Choix techniques
uv remplace Poetry. La résolution et l'installation des dépendances sont nettement plus rapides, et l'outil couvre aussi la gestion des versions de Python. La migration depuis Poetry a été faite en cours de vie du template, en décembre 2025, et les workflows Python mutualisés ont reçu leurs équivalents uv. Les projets générés auparavant restent sous Poetry tant qu'ils ne sont pas resynchronisés avec le template.
Ruff remplace le trio Black, isort et flake8 : un seul outil, une seule configuration, une exécution nettement plus rapide. Il couvre le formatage, le tri des imports et le linting.
pre-commit exécute les vérifications localement avant chaque commit, pas seulement en CI, ce qui avance la détection des erreurs dans le cycle.
La maintenance dans le temps
Un template qui n'évolue pas devient vite obsolète. Cruft propage les mises à jour du template vers les projets qui en sont issus : cruft update applique dans un projet le diff entre la version du template qui l'a généré et la version courante. Quand une dépendance ou une configuration évolue dans le template, les projets qui en sont issus intègrent la mise à jour sans repartir de zéro.
Résultats
Le template sert de point de départ aux projets Python de l'organisation depuis décembre 2023. Les outils internes de l'équipe SONU (bot 6TRON, alertes de stock, bot de documentation) en sont issus : ils partagent la même structure de dépôt, les mêmes hooks pre-commit et un Dockerfile bâti sur le même modèle. Un nouveau projet démarre avec sa CI et son devcontainer déjà en place.
Limites connues
L'adoption de Cruft n'est pas universelle : certains projets anciens ne l'ont pas activé, ce qui crée une dérive progressive avec le template. La synchronisation n'est pas non plus automatique : le workflow mutualisé qui ouvrait une pull request de mise à jour Cruft a été retiré de generic_workflows, et cruft update se lance désormais à la main dans chaque projet. Les projets de type script n'ont pas de tests par convention, ce qui peut encourager la mauvaise habitude de ne jamais en écrire même lorsque cela serait utile. La frontière entre "module" et "application" n'est pas toujours évidente pour les contributeurs, ce qui génère parfois des choix de type inadaptés.
Liens
Le dépôt du template est privé à l'organisation catie-aq. Page liée :
Articles liés
5 articles du blog détaillent des notions mises en pratique dans ce projet.
- Python : Packaging
Templates et bonnes pratiques pour le packaging et la publication de packages Python.
- Python : Pytest
Framework de test du template : suite pytest avec couverture pour les projets de type module, exécutée en CI/CD.
- Python : uv
Exploration de uv comme alternative à pip, plus rapide, pour la gestion des dépendances du projet.
- Python : Ruff
Ruff configuré comme linter et formateur standard du template Python, à la place de black, isort et flake8.
- Python : Poetry
Template Python fondé sur Poetry pour la gestion des dépendances, les tests (pytest) et les releases.