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.

Vous aimerez aussi...

1 réponse

  1. 19 février 2024

    […] le premier article, nous avons vu comment paramétrer argparse pour récupérer les arguments de la ligne de commande. […]