Paramétrer un script Python avec Argparse (première partie)
Apprendre à programmer et écrire des scripts simplifie la vie pour répéter les mêmes tâches. Mais les données que vous devez utiliser sont généralement différentes. Vous allez, par exemple, devoir travailler avec des fichier ou des répertoires différents.
Je vous ai proposé plusieurs exemple de scripts comme renommer ses photos en Python ou supprimer les jpgs lorsqu’on photographie en RAW+jpg. Ces scripts traitent le répertoire courant, c’est à dire que les photos doivent être dans le répertoire courant. Ce n’est pas le plus pratique, surtout lorsqu’on connait le problème d’identifier le répertoire d’exécution de Python.
Ce serait bien d’informer le script quel répertoire utiliser. Nous allons voir ici comment faire lors de l’exécution du script.
Exécuter un programme Python
Pour cet article, je vais partir du principe qu’un script Python est exécuté par l’invite de commande (en dos, PowerShell, Bash, Zsh…). La commande sera du type
python -m monscript python -m monpackage.monscript
Je vous invite à ce sujet à aller voir mon article sur le fichier __main__.py.
Paramétrer un programme Python
Paramétrer le lancement d’un programme (Python ou autre) consiste à ajouter des arguments à la ligne de commande. Celle-ci ressemble alors à une des lignes suivantes :
python -m monscript -h python -m monscript --help python -m monscript -o outputfile.txt python -m monscript sourcefile.csv python -m monscript sourcefile.csv -o output.txt
C’est un usage commun avec l’invite de commande que les utilisateurs Linux connaissent bien.
Petite explication sur les options de la ligne de commande.
Certains de vos scripts auront besoin d’une information pour fonctionner comme par exemple le nom du fichier sur lequel travailler. Cette information et obligatoire et ce paramètre devra être fourni. Il est en général fourni de manière positionnelle comme dans l’exemple de la ligne 4 et 5. Son absence provoquera une erreur.
Les trois lignes précédentes présentent un argument optionnel qui est soit une lettre précédée d’un tiret (ligne 1) soit un mot précédé de deux tirets (ligne 2). Cette option peut être accompagnée d’un argument (ligne 3 où l’option est un nom pour un fichier de sortie).
La ligne 5 présente une combinaison d’argument positionnel et optionnel. Dans cet article, après une présentation d’argparse, je ne parlerai que des arguments positionnels.
Paramétrer le lancement d’un script Python avec Argparse
Utiliser les paramètres de la ligne de commande remonte à l’origine de la ligne de commande. Cela repose sur la décomposition de la ligne de commande mais a longtemps été compliqué car les arguments sont en général spécifiques à chaque script.
Python a ajouté un outil très efficace : argparse. En passant, cette bibliothèque est très bien documentée et intelligemment accompagné d’un tutoriel.
Je ne vais pas reprendre tout le tutoriel mais expliquer ici le concept et les bases.
Argparse part du principe que l’utilisation de la ligne de commande suit certains principes. Certains comportements sont attendus et la syntaxe est convenue. Ainsi, Argparse automatisera un certain nombre de choses pour vous permettre de vous focaliser sur l’exploitation des arguments.
Ainsi, son usage de base va consister à créer un objet de type ArgumentParser
et appeler sa méthode .parse_args()
.
import argparse parser = argparse.ArgumentParser() parser.parse_args()
Un programme qui ne contient que ces lignes ne fera rien si vous l’exécutez. Cependant, argparse part du principe qu’il doit proposer un comportement standard pour certaines options. Ainsi, vous avez toujours besoin d’une aide. L’option -h
ou --help
existe automatiquement.
? % python -m demoargs -h usage: demoargs.py [-h] options: -h, --help show this help message and exit
Par contre, si vous essayez avec n’importe quelle autre option, vous aurez une erreur :
? % python -m demoargs -o usage: demoargs.py [-h] demoargs.py: error: unrecognized arguments: -o
Ajouter des arguments positionnels
Pour nos scripts, nous aurons besoin de demander quel répertoire ou quel fichier traiter. Cet argument devra être obligatoire et sera donc un argument positionnel, c’est à dire qu’il devra être dans un ordre bien précis après le lancement du script.
En même temps, argparse doit pouvoir l’identifier. Nous allons donc lui dire qu’il attends cet argument. Notre code devient :
import argparse parser = argparse.ArgumentParser() parser.add_argument("source_dir") parser.parse_args()
À partir de là, plusieurs choses intéressantes se mettent en place. Premièrement, vous ne pouvez plus lancer le programme sans fournir un argument à la suite.
? % python -m demoargs usage: demoargs.py [-h] source_dir demoargs.py: error: the following arguments are required: source_dir
Vous remarquez que le programme attends un argument source_dir
.
Deuxièmement, vous pouvez voir que l’aide a été automatiquement enrichie :
? % python -m demoargs -h usage: demoargs.py [-h] source_dir positional arguments: source_dir options: -h, --help show this help message and exit
Lorsque vous ajouter un argument par la méthode .add_argument()
, celui-ci est automatiquement ajouté à l’aide. Mais cette aide n’est pas très informative en l’état. La méthode est prévue pour et vous pouvez ajouter un message d’aide. Petite précision : argparse peut être internationalisé, vous pouvez donc avoir l’aide en français. Mais c’est une partie compliquée qui nécessite un manuel à elle seule, dans cet article, je vais rester dans le comportement par défaut où, le reste étant en anglais, je l’écrirai en anglais.
import argparse parser = argparse.ArgumentParser() parser.add_argument("source_dir", help="Source directory of the files to process") parser.parse_args()
Et maintenant, si nous voulons afficher l’aide, nous aurons :
? % python -m demoargs -h usage: demoargs.py [-h] source_dir positional arguments: source_dir Source directory of the files to process options: -h, --help show this help message and exit
Récupérer l’argument
Dans notre programme, nous allons avoir besoin de récupérer la données qui nous a été communiquée en tant qu’argument positionnel. Cela va être relativement simple lorsqu’on aura compris comment argparse fonctionne.
Lorsque vous avez ajouté un argument par la méthode .add_argument()
, vous fournissez à cette méthode une chaine de caractères qui est le nom de l’argument.
Lors de l’appel à la méthode .parse_args()
, argparse va traiter les arguments de la ligne de commande et retourner un objet. Nous devons donc récupérer cet objet pour accéder à nos informations.
Et la magie est que argparse, lorsqu’il récupère les argument de la ligne de commande, crée des attributs avec le nom des arguments que vous avez créé. Ainsi, pour récupérer le nom de notre répertoire source, cela s’écrit ainsi :
import argparse parser = argparse.ArgumentParser() parser.add_argument("source_dir", help="Source directory of the files to process") args = parser.parse_args() print(args.source_dir)
Je vous laisse tester ce script.
Nous avons maintenant tout ce qu’il nous faut pour nos scripts simples de traitement photo.
Adaptation au script de suppression des jpgs
Dans l’article sur la suppression des jpgs lorsqu’on photographie en RAW+jpg, je vous ai proposé une fonction qui prends en premier argument le chemin du répertoire à traiter. Nous allons ajouter le code qui permet de lancer ce script avec un argument qui sera le répertoire à traiter.
Nous allons commencer par configurer le parser :
import argparse parser = argparse.ArgumentParser() parser.add_argument("source_dir", help="Source dir containing RAW+jpg files") args = parser.parse_args()
Puis nous allons créer un objet de type Path avec cet argument. Non, je ne fais aucune validation. L’idéal serait de gérer des exceptions si la chaine n’est pas conforme.
source_dir = Path(args.source_dir).resolve()
Et nous allons pouvoir lancer le traitement sur ce répertoire. Si il existe… Nous pouvons alors tester cela et informer si ce n’est pas le cas :
if source_dir.is_dir(): remove_jpg_from_raw(source_dir) else: print(f"Le répertoire {source_dir} n'existe pas")
Et voilà, 9 lignes en plus et nous pouvons utiliser ce programme avec un répertoire défini au lancement.
Les arguments positionnels sont intéressants pour écrire des scripts comme les commandes shell où des arguments bien définis sont attendus. Dans le prochain post, j’aborderai les arguments optionnels.
Si vous avez aimé ce post, n’hésitez pas à laisser un commentaire ci-dessous ou sur la page Facebook 😉
À propos de... Darko Stankovski
iT guy, photographe et papa 3.0, je vous fais partager mon expérience et découvertes dans ces domaines. Vous pouvez me suivre sur les liens ci-dessous.
1 réponse
[…] le premier article, nous avons vu comment paramétrer argparse pour récupérer les arguments de la ligne de commande. […]