Cookiecutter génère une structure de projet complète en une commande. Vous choisissez un template (local ou GitHub), répondez à quelques questions, et obtenez un projet prêt à coder. Ce guide couvre l’installation, l’utilisation des templates existants et la création de vos propres templates.
Le problème que Cookiecutter résout
Section intitulée « Le problème que Cookiecutter résout »Démarrer un nouveau projet implique toujours les mêmes tâches :
- Créer la structure de dossiers
- Ajouter les fichiers de configuration (
.gitignore,pyproject.toml,Dockerfile) - Copier du code boilerplate depuis un ancien projet
- Renommer les variables, nettoyer les références au projet précédent
Ce processus prend 30 minutes à 2 heures selon la complexité. Pire, chaque développeur fait différemment, créant des incohérences dans l’équipe.
Cookiecutter automatise tout cela :
| Sans Cookiecutter | Avec Cookiecutter |
|---|---|
| Copier-coller d’un ancien projet | Une commande génère la structure |
| Rechercher/remplacer les noms | Variables pré-remplies automatiquement |
| Oublier des fichiers de config | Template complet et cohérent |
| 30 min à 2h par projet | 10 secondes |
Installation
Section intitulée « Installation »Version actuelle : 2.6.0 (février 2026)
Cookiecutter est écrit en Python. L’installation recommandée utilise pipx pour isoler les dépendances.
-
Installer pipx (si pas déjà fait)
Fenêtre de terminal # Ubuntu/Debiansudo apt install pipxpipx ensurepath# Ou avec pippip install --user pipxpipx ensurepath -
Installer Cookiecutter
Fenêtre de terminal pipx install cookiecutterSortie attendue :
done! ✨ 🌟 ✨installed package cookiecutter 2.6.0, installed using Python 3.12.3These apps are now globally available- cookiecutter -
Vérifier l’installation
Fenêtre de terminal cookiecutter --version# Cookiecutter 2.6.0
Utiliser un template existant
Section intitulée « Utiliser un template existant »Depuis GitHub
Section intitulée « Depuis GitHub »La façon la plus simple d’utiliser Cookiecutter : pointer vers un template GitHub.
cookiecutter https://github.com/audreyfeldroy/cookiecutter-pypackageCookiecutter clone le dépôt, lit le fichier cookiecutter.json, et vous pose les questions :
full_name [Audrey Roy Greenfeld]: Stéphane Robertemail [audreyr@example.com]: me@stephane-robert.infoproject_name [Python Boilerplate]: Mon Super Projetproject_slug [mon_super_projet]:...Le projet est généré dans le dossier courant :
ls mon_super_projet/# CODE_OF_CONDUCT.md docs/ LICENSE pyproject.toml README.md src/ tests/Mode non-interactif
Section intitulée « Mode non-interactif »Pour les pipelines CI/CD ou les scripts, utilisez --no-input :
cookiecutter https://github.com/audreyfeldroy/cookiecutter-pypackage --no-inputCookiecutter utilise les valeurs par défaut du template.
Passer des valeurs en ligne de commande
Section intitulée « Passer des valeurs en ligne de commande »cookiecutter https://github.com/user/template \ project_name="Mon Projet" \ author_name="Stéphane"Utiliser une version spécifique
Section intitulée « Utiliser une version spécifique »cookiecutter https://github.com/user/template --checkout v1.0.0Templates installés
Section intitulée « Templates installés »Cookiecutter met en cache les templates. Pour les lister :
cookiecutter --list-installed# 1 installed templates:# * cookiecutter-pypackagePour réutiliser un template déjà cloné :
cookiecutter cookiecutter-pypackageLe fichier cookiecutter.json
Section intitulée « Le fichier cookiecutter.json »Au cœur de chaque template, ce fichier JSON définit les variables et leurs valeurs par défaut.
Structure basique
Section intitulée « Structure basique »{ "project_name": "Mon Projet", "author_name": "Stéphane Robert", "version": "0.1.0", "description": "Un projet Python"}Chaque clé devient une variable utilisable dans les fichiers du template avec la syntaxe Jinja2 : {{ cookiecutter.project_name }}.
Choix multiples
Section intitulée « Choix multiples »{ "license": ["MIT", "GPLv3", "Apache 2.0", "BSD-3-Clause"], "use_docker": ["yes", "no"]}L’utilisateur sélectionne parmi les options. La première option est la valeur par défaut.
Variables dérivées
Section intitulée « Variables dérivées »{ "project_name": "Mon Super Projet", "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}"}project_slug est calculé automatiquement à partir de project_name.
Créer votre propre template
Section intitulée « Créer votre propre template »Structure minimale
Section intitulée « Structure minimale »Répertoiremon-template/
- cookiecutter.json
Répertoire{{cookiecutter.project_name}}/
- README.md
- .gitignore
Le dossier {{cookiecutter.project_name}} sera renommé avec la valeur saisie par l’utilisateur.
Exemple : template DevOps
Section intitulée « Exemple : template DevOps »Créons un template pour un projet avec Docker et CI/CD :
-
Créer la structure
Fenêtre de terminal mkdir -p mon-template/\{\{cookiecutter.project_name\}\}/.github/workflowscd mon-template -
Créer cookiecutter.json
Fenêtre de terminal cat > cookiecutter.json << 'EOF'{"project_name": "my-app","author_name": "Stéphane Robert","description": "Application DevOps","python_version": ["3.12", "3.11", "3.10"],"include_docker": ["yes", "no"],"include_ci": ["yes", "no"]}EOF -
Créer les fichiers du template
{{cookiecutter.project_name}}/README.md:# {{ cookiecutter.project_name }}{{ cookiecutter.description }}## Auteur{{ cookiecutter.author_name }}## Installation```bashpip install -e .\```{{cookiecutter.project_name}}/.gitignore:__pycache__/*.pyc.env.venv/dist/*.egg-info/ -
Tester le template
Fenêtre de terminal cd ..cookiecutter mon-template/
Fichiers conditionnels
Section intitulée « Fichiers conditionnels »Utilisez Jinja2 dans les noms de fichiers pour créer des fichiers conditionnels :
Répertoiremon-template/
- cookiecutter.json
Répertoire{{cookiecutter.project_name}}/
- README.md
- {{“Dockerfile” if cookiecutter.include_docker == “yes” else ""}}
Répertoire{{“.github” if cookiecutter.include_ci == “yes” else ""}}/
Répertoireworkflows/
- ci.yml
Le Dockerfile n’est créé que si l’utilisateur répond “yes” à include_docker.
Contenu conditionnel
Section intitulée « Contenu conditionnel »Dans un fichier, utilisez les conditions Jinja2 :
# {{ cookiecutter.project_name }}
{{ cookiecutter.description }}
{% if cookiecutter.include_docker == "yes" %}## Docker
Build l'image :
\```bashdocker build -t {{ cookiecutter.project_name }} .\```{% endif %}
{% if cookiecutter.include_ci == "yes" %}## CI/CD
Ce projet utilise GitHub Actions. Voir `.github/workflows/ci.yml`.{% endif %}Hooks : exécuter du code automatiquement
Section intitulée « Hooks : exécuter du code automatiquement »Les hooks sont des scripts Python exécutés à différents moments de la génération.
Types de hooks
Section intitulée « Types de hooks »| Hook | Moment d’exécution | Usage typique |
|---|---|---|
pre_prompt.py | Avant les questions | Vérifier des prérequis |
pre_gen_project.py | Avant génération | Valider les réponses |
post_gen_project.py | Après génération | Initialiser Git, installer deps |
Les hooks se placent dans le dossier hooks/ à la racine du template :
Répertoiremon-template/
- cookiecutter.json
Répertoirehooks/
- pre_gen_project.py
- post_gen_project.py
Répertoire{{cookiecutter.project_name}}/
- …
Exemple : initialiser Git après génération
Section intitulée « Exemple : initialiser Git après génération »hooks/post_gen_project.py :
import subprocessimport os
def main(): project_path = os.getcwd()
# Initialiser Git subprocess.run(["git", "init"], cwd=project_path, check=True) subprocess.run(["git", "add", "."], cwd=project_path, check=True) subprocess.run( ["git", "commit", "-m", "Initial commit from Cookiecutter"], cwd=project_path, check=True )
print("✓ Dépôt Git initialisé avec le premier commit")
if __name__ == "__main__": main()Exemple : valider le nom du projet
Section intitulée « Exemple : valider le nom du projet »hooks/pre_gen_project.py :
import reimport sys
def main(): project_name = "{{ cookiecutter.project_name }}"
if not re.match(r"^[a-zA-Z][a-zA-Z0-9_-]*$", project_name): print("ERREUR: Le nom du projet doit commencer par une lettre") print(" et ne contenir que lettres, chiffres, tirets ou underscores.") sys.exit(1)
if __name__ == "__main__": main()Gérer l’option accept-hooks
Section intitulée « Gérer l’option accept-hooks »Par défaut, Cookiecutter demande confirmation avant d’exécuter les hooks. Contrôlez ce comportement :
# Toujours exécutercookiecutter template --accept-hooks yes
# Demander (défaut)cookiecutter template --accept-hooks ask
# Jamais exécutercookiecutter template --accept-hooks noOptions de ligne de commande
Section intitulée « Options de ligne de commande »| Option | Description |
|---|---|
-V, --version | Affiche la version |
--no-input | Utilise les valeurs par défaut |
-c, --checkout | Clone une branche/tag spécifique |
-o, --output-dir | Dossier de destination |
-f, --overwrite-if-exists | Écrase si le projet existe |
-s, --skip-if-file-exists | Ignore les fichiers existants |
-l, --list-installed | Liste les templates en cache |
--replay | Réutilise les réponses précédentes |
--accept-hooks | `yes |
Templates DevOps recommandés
Section intitulée « Templates DevOps recommandés »| Template | Description | Lien |
|---|---|---|
| cookiecutter-django | Django production-ready avec Docker | GitHub |
| cookiecutter-pypackage | Package Python avec tests et CI | GitHub |
| cookiecutter-ansible-role | Rôle Ansible avec molécule | GitHub |
| cookiecutter-flask | Flask avec API REST et Docker | GitHub |
Fichier de configuration utilisateur
Section intitulée « Fichier de configuration utilisateur »Pour définir des valeurs par défaut globales, créez ~/.cookiecutterrc :
default_context: full_name: "Stéphane Robert" email: "me@stephane-robert.info" github_username: "stephrobert"
abbreviations: gh: https://github.com/\{0\}.git bb: https://bitbucket.org/\{0\}Maintenant, utilisez les abréviations :
cookiecutter gh:audreyfeldroy/cookiecutter-pypackageÀ retenir
Section intitulée « À retenir »- Cookiecutter = générateur de projets — Une commande génère une structure complète
- Templates GitHub :
cookiecutter https://github.com/user/template - cookiecutter.json définit les variables et valeurs par défaut
- Jinja2 pour le contenu dynamique :
{{ cookiecutter.variable }} - Fichiers conditionnels : nommez
{{"Dockerfile" if var == "yes" else ""}} - Hooks : scripts Python exécutés avant/après génération
- —no-input pour les pipelines CI/CD
- ~/.cookiecutterrc pour vos valeurs par défaut globales