Suivez l'guide :
Ajoutez une interface graphique à votre script en 4 lignes avec Gooey

Vous venez de terminer votre analyse bio-informatique. Pour cette dernière, vous avez réalisé un script qui pour l'instant, il faut le dire, n'est pas du tout réutilisable par une tierce personne. Même vous dans 6 mois vous n'êtes pas sûr de vous souvenir de ce que vous avez fait. Pourtant, l'un des intérêts de la programmation est de pouvoir répéter des calculs de manière automatique. Par conséquent, ce serait pratique de rendre votre script un peu plus souple afin de ne pas devoir modifier son code source à chaque fois qu'un paramètre de votre analyse change. De plus, il serait bien que les biologistes qui travaillent avec vous puissent également utiliser votre script, après tout le boulot d'un bio-informaticien c'est aussi de faire l'interface entre les biologistes et les informaticiens non ?

Nous allons voir comment rendre un script facilement utilisable, en gardant un code clair, le tout en Python.

sys.argv : une fausse bonne idée

Contexte

Admettons que vous ayez un script (que nous nommerons monScript.py ) qui prend comme paramètres le nom d'un fichier d'entrée et le nom d'un fichier de sortie. La première idée peut être de se dire que le programme doit être appelé de la façon suivante : monScript.py input output

Pour cela vous pouvez utiliser la bibliothèque sys de Python. Cette dernière vous fournira un tableau qui permet d'accéder aux paramètres de votre ligne de commande :

Pour ceux qui se posent la question, sys.argv[0] correspond au nom de votre script.

Ça se complique

Vous pouvez tout à fait faire fonctionner votre script ainsi, seulement il y aura des tests à effectuer, notamment pour savoir si le fichier d'entrée existe. Certes un if au début de votre code pourrait faire l'affaire.

Cependant, imaginons maintenant que votre script qui réalise plusieurs étapes, puisse afficher le temps de calcul de chaque traitement, ou pas, selon les désirs de l'utilisateur. Pour cela il faudrait rajouter une option, par exemple "-t" comme Time. Votre script se base sur un logiciel dont il connaît la localisation mais que faire si un jour il est installé dans un autre répertoire ? Ça peut être le cas si plusieurs versions d'un même logiciel coexistent sur une machine. Il faudrait que votre script par défaut fasse appel au répertoire d'installation classique du logiciel (ex : /usr/bin/soft) mais, qu'il soit également possible de spécifier un autre chemin, dans le cas où on voudrait tester une nouvelle version par exemple. Une option "--path" serait la bienvenue pour cela. Enfin, comme dans tout logiciel utilisable en ligne de commande, on aimerait que l'option "-h" ou "--help" affiche l'aide.

Pour réaliser tout ceci vous pouvez vous engouffrer dans des if sans fin en utilisant la bibliothèque sys mais vous voyez bien que cela devient vite compliqué.

args parse : gérer plus finement les options en ligne de commande

Les différentes options décrites précédemment peuvent simplement être implémentées de la manière suivante :

Et voilà !

Deux choses intéressantes sont à noter :

  1. Vous avez séparé la gestion des options de l’exécution du programme. Plus besoin d'ajouter une tonne de if au début de votre script. Tout ceci est fait automatiquement, vous avez juste à vous concentrer sur votre programme en lui-même. Si vous désirez rajouter une option vous n'avez qu'une ligne à ajouter, vous n'avez pas besoin de "tout casser" dans votre code.
  2. L'aide est réalisée automatiquement. Vous pouvez l'afficher avec l'option "-h" ou "--help", cf. ci-dessous.

    Exemple d'aide crée par argsparse

    Exemple d'aide créée par argsparse

La bibliothèque argsparse  permet de faire de nombreuses choses, je vous invite à lire la doc pour obtenir plus d'informations.

Gooey : l'ajout d'interface graphique

Notre script peut maintenant afficher une aide conviviale, ce qui est bien sympathique pour les utilisateurs sensibilisés aux lignes de commande. Mais que faire pour les autres ?

Bonne nouvelle, la bibliothèque Gooey permet de réaliser une interface graphique en ajoutant 4 lignes à notre code précédent !

  1. Mettez votre programme dans une fonction, vous pouvez choisir main par exemple
  2. Ajoutez @Gooey au dessus de votre fonction
  3. Importez la bibliothèque : from gooey import Gooey
  4. N'oubliez pas d’appeler votre fonction main dans votre code 🙂

Voilà ce que ça donne pour notre exemple :

Et voici la fenêtre obtenue :

Exemple de fenêtre créée par Gooey

Exemple de fenêtre créée par Gooey

 

Bien entendu, la fenêtre est "simple" mais par rapport au peu de lignes de code demandées pour la générer ça me semble être un bon compromis.

Vous savez maintenant comment faire pour ajouter des options à votre script sans que ça soit l'anarchie dans votre code, puis comment ajouter une fenêtre en seulement quelques lignes de code, à vous de jouer !

 

Merci à Nico M., NiGoPol et Nisaea_ pour les commentaires et discussions lors de l’édition de cet article.

  • À propos de
  • Bordelais d'origine, je pratique le pierre-feuille-ciseaux en club.

3 commentaires sur “Ajoutez une interface graphique à votre script en 4 lignes avec Gooey

  1. Super lib !

    Elle est très configurable, c\'est franchement sympa pour faire un end-user rapidement.

    Le point vachement rigolo, c\'est qu\'en essayant d\'implémenter la compatibilité avec docopt (une autre lib pour CLI, que je conseille), les mainteneurs ont permis l\'usage simultané de docopt et argparse !

    Ç\'eût été le but initial que personne n\'aurais réussi…

    • Wow docopt c\'est hyper puissant je ne connaissais pas oO ça existe dans plusieurs langages en plus !
      Merci pour la découverte.

      • lien docopt : http://docopt.org/

        Si pour un CLI simple docopt c\'est effectivement excellent, je le trouve assez limité à l\'usage, dans les cas plus complexe que l\'exemple.

        Le problème principal vient du fait que des options manquent, mais que les mainteneurs veulent garder le projet «simple». C\'est un choix, mais de fait, on fini par parser à la main le dictionnaire renvoyé par docopt.
        J\'ai plusieurs projets perso où un module est spécifiquement dédié à l\'appel de docopt et au post traitement des données reçues.

        Dans ces cas là, passer à argparse est, paradoxalement, plus lisible.

Laisser un commentaire