Améliorer l’exploitation de votre projet Python avec un Makefile
- 2024-03-14
- Publié par : Christophe DELEUZE
- Catégorie : Python
Lorsque vous développez un projet Python, l’efficacité est la clé. Un moyen souvent négligé d’améliorer votre flux de travail est l’utilisation d’un Makefile. Généralement associé à des projets en C, un Makefile peut également être un atout précieux pour les développeurs Python. Dans cet article, nous explorerons pourquoi l’intégration d’un Makefile dans votre projet Python peut améliorer votre productivité et quelles pratiques adopter pour maximiser ses avantages.
Pourquoi intégrer un Makefile dans un projet Python ?
Automatisation des tâches récurrentes
L’un des avantages majeurs d’un Makefile est de regrouper autour du mot clé make toutes les tâches courantes que vous souhaitez automatiser telles que la création de virtualenv, l’installation de dépendances, l’exécution de tests, etc. Plutôt que de mémoriser une multitude de commandes, un simple make suffira pour accomplir ces actions.
Par exemple :
make virtualenv
make build
make build-dev
make up
make up-dev
make down
make clean
make tests
make download-assets
Maintenir la cohérence du projet
En regroupant tout au même endroit, le Makefile permet de définir et maintenir une structure cohérente pour votre projet. C’est le point d’entrée privilégié pour spécifier les règles et les dépendances à appliquer sur votre projet. En l’utilisant, nous nous assurons que chaque membre de l’équipe suit le même processus, minimisant ainsi les erreurs potentielles liées à des configurations individuelles.
Gagner du temps
De fait, l’automatisation des tâches répétitives avec un Makefile permet de gagner un temps précieux. Vous pouvez concentrer votre énergie sur le développement plutôt que sur l’exécution manuelle de scripts ou la configuration constante de votre environnement. De plus, avec un Makefile, vous aurez l’auto-complétion des règles, ce qui est pratique au quotidien.
Quoi mettre dans le Makefile ?
À partir d’ici, je vous propose quelques exemples non exhaustifs qui pourront vous servir de source d’idée de choses à mettre dans un Makefile.
Configuration de l'environnement
Le premier point que nous allons avoir tendance à vouloir automatiser est l’utilisation des environnements virtuels. Utiliser des environnements virtuels unifiés dans toute l’équipe de développeur facilite le debug et les interactions entre développeurs.
Pour intégrer l’installation de cet environnement dans un Makefile, rien de plus simple :
# Créer un environnement virtuel
venv:
python3 -m venv venv
Ensuite, il suffira de faire tout simplement make venv.
Installation des dépendances
Après avoir créé un environnement virtuel, nous voudrons certainement installer les dépendances avec une commande du type : make install. Pour cela nous ferons :
# Installer les dépendances
install:
pip install -r requirements.txt
Toutefois, dans les faits, l’installation des dépendances sera souvent couplée à la création de l’environnement virtuel.
Voici un script qui fait le travail complet d’installation d’un environnement virtuel pyenv et de dépendances gérées par poetry :
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
GREEN="\e[1;92m"
CYAN="\e[1;96m"
RESET="\e[0m"
ENV_NAME=project-api
PYTHON_VERSION=3.12.2
POETRY_VERSION=1.8.2
echo -e "${GREEN}Creating a virtualenv ${CYAN}${ENV_NAME}${GREEN} with Python ${CYAN}${PYTHON_VERSION}${RESET}"
rm -f .python-version
pyenv install ${PYTHON_VERSION} --skip-existing
pyenv virtualenv ${PYTHON_VERSION} ${ENV_NAME} --force
pyenv local ${ENV_NAME}
echo -e "${GREEN}Updating pip, setuptools & wheel${RESET}"
pip install --upgrade pip setuptools wheel
echo -e "${GREEN}Install poetry${RESET}"
pip install poetry==${POETRY_VERSION}
echo -e "${GREEN}Install dependencies with poetry${RESET}"
poetry config virtualenvs.create false
poetry install
echo -e "${GREEN}All set !${RESET}"
NB : Ce script, que j’ai nommé setup_dev_env.sh, sera rangé dans un dossier nommé scripts situé à la racine du projet et il sera exécuté dans le Makefile de la façon suivante :
# Installer les dépendances
dev-env:
./scripts/setup_dev_env.sh
Exécution des tests
Maintenant que nous avons un environnement complètement fonctionnel sur notre machine, nous allons sans aucun doute vouloir exécuter des tests avec make tests pour garantir la stabilité du code du projet. Ici, mon projet est testé à l’aide de la librairie pytest.
# Exécuter les tests
tests:
pytest tests/
Nettoyage du projet
Parfois, les fichiers en caches, créés tous au long de la durée de vie du projet, nous jouent des tours et il convient de tout nettoyer pour y voir plus clair. Pourquoi ne pas intégrer un make clean à votre projet ?
# Nettoyer le projet
clean:
rm -rf venv
find . -name "*.pyc" -exec rm -f {} \;
La règle clean supprimera les fichiers inutiles, facilitant la distribution et le partage du projet.
Intégration de Docker
L’utilisation conjointe d’un Makefile et de Docker peut considérablement renforcer la portabilité de votre projet Python. En ajoutant des règles spécifiques au Makefile, vous pouvez orchestrer le déploiement de votre application dans des conteneurs Docker.
Par exemple, une règle docker-build pourrait construire une image Docker de votre application, tandis qu’une règle docker-run pourrait lancer cette image dans un conteneur.
Cette approche simplifie le processus de déploiement en garantissant une isolation totale de l’environnement, éliminant ainsi les problèmes potentiels liés aux variations entre les environnements de développement et de production.
En utilisant Docker de concert avec un Makefile, vous établissez une méthode robuste pour la gestion des dépendances, la configuration de l’environnement et le déploiement, offrant ainsi une solution complète pour des projets Python efficaces et facilement déployables tout en limitant les difficultés liées à la maitrise de docker et de ses paramètres qui sont alors gérés dans le Makefile.
Voici un exemple de Makefile qui utilise docker-compose avec deux configurations, une configuration pour l’environnement de production (compose.yml) et une pour l’environnement de dev (compose-dev.yml) :
compose := docker-compose -f compose.yml
build:
@$(compose) build
build-dev:
@$(compose) -f compose-dev.yml build
build-no-cache:
@$(compose) build --no-cache
up:
@$(compose) up
up-detach:
@$(compose) up --detach
up-dev:
@$(compose) -f compose-dev.yml up
down:
@$(compose) down
Documentation du makefile
Maintenant que nous avons fait le tour des principales thématiques qui intéressent un développement, nous ne devons pas oublier de permettre à son utilisateur de s’y retrouver. Alors un make help n’est jamais de trop :
help:
@echo "dev-env create the dev environnement"
@echo "build build stack"
@echo "build-no-cache build stack with --no-cache flag"
@echo "up up stack"
@echo "up-detach up stack with --detach flag"
@echo "up-dev up stack in dev mode"
@echo "down down stack"
@echo "pre-commit make all checks to do before commit"
@echo "tests make pytest"
@echo "clean cleanup pyc files inside the project"
scripts spécifiques
Outre les propositions génériques que nous avons déjà vus, vous aurez peut-être besoin de pouvoir exécuter simplement des scripts spécifiques. Dans ce cas, je vous conseille de créer un répertoire scripts (comme pour setup-dev-env.sh) et de référencer vos scripts dans le Makefile avec un mot clé explicite.
Le mot de la fin
L’ajout d’un Makefile à votre projet Python est une étape simple qui peut considérablement améliorer votre flux de travail. L’automatisation des tâches répétitives, la cohérence du projet et la gestion efficace de l’environnement sont des avantages indéniables. En adoptant ces bonnes pratiques, vous optimiserez votre développement, gagnerez du temps et favoriserez une collaboration plus fluide au sein de votre équipe. Alors, ne sous-estimez pas le pouvoir d’un Makefile dans votre projet Python !