Ajoutez une interface graphique à votre script en 4 lignes avec Gooey

Vous venez de ter­mi­ner votre ana­lyse bio-infor­ma­tique. Pour cette der­nière, vous avez réa­li­sé un script qui pour l'instant, il faut le dire, n'est pas du tout réuti­li­sable par une tierce per­sonne. Même vous dans 6 mois vous n'êtes pas sûr de vous sou­ve­nir de ce que vous avez fait. Pour­tant, l'un des inté­rêts de la pro­gram­ma­tion est de pou­voir répé­ter des cal­culs de manière auto­ma­tique. Par consé­quent, ce serait pra­tique de rendre votre script un peu plus souple afin de ne pas devoir modi­fier son code source à chaque fois qu'un para­mètre de votre ana­lyse change. De plus, il serait bien que les bio­lo­gistes qui tra­vaillent avec vous puissent éga­le­ment uti­li­ser votre script, après tout le bou­lot d'un bio-infor­ma­ti­cien c'est aus­si de faire l'interface entre les bio­lo­gistes et les infor­ma­ti­ciens non ?

Nous allons voir com­ment rendre un script faci­le­ment uti­li­sable, en gar­dant un code clair, le tout en Python.

sys.argv : une fausse bonne idée

Contexte

Admet­tons que vous ayez un script (que nous nom­me­rons

 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 :

# coding: utf-8
import sys
print "Voici les paramètres entrés : "+sys.argv[1]+" "+sys.argv[2]

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 :

# coding: utf-8
import argparse
softPath="/usr/bin/soft"
parser = argparse.ArgumentParser()
parser.add_argument("input", help="Input File",type=argparse.FileType('r'))
parser.add_argument("output", help="Output File",type=argparse.FileType('w'))
parser.add_argument("-t", help="Print time",action='store_true')
parser.add_argument("--path", help="Path to software",default=softPath)
parser.parse_args()

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 :

# coding: utf-8
import argparse
from gooey import Gooey

@Gooey
def main():
softPath="/usr/bin/soft"
parser = argparse.ArgumentParser()
parser.add_argument("input", help="Input File",type=argparse.FileType('r'))
parser.add_argument("output", help="Output File",type=argparse.FileType('w'))
parser.add_argument("-t", help="Print time",action='store_true')
parser.add_argument("--path", help="Path to software",default=softPath)
parser.parse_args()

main()

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.



Pour continuer la lecture :


Commentaires

3 réponses à “Ajoutez une interface graphique à votre script en 4 lignes avec Gooey”

  1. Super lib !

    Elle est très confi­gu­rable, c'est fran­che­ment sym­pa pour faire un end-user rapi­de­ment.

    Le point vache­ment rigo­lo, c'est qu'en essayant d'implémenter la com­pa­ti­bi­li­té avec docopt (une autre lib pour CLI, que je conseille), les main­te­neurs ont per­mis l'usage simul­ta­né de docopt et arg­parse !

    Ç'eût été le but ini­tial que per­sonne n'aurais réus­si…

    1. Avatar de ClemBuntu
      ClemBuntu

      Wow docopt c'est hyper puis­sant je ne connais­sais pas oO ça existe dans plu­sieurs lan­gages en plus !
      Mer­ci pour la décou­verte.

      1. lien docopt : http://​docopt​.org/

        Si pour un CLI simple docopt c'est effec­ti­ve­ment excellent, je le trouve assez limi­té à l'usage, dans les cas plus com­plexe que l'exemple.

        Le pro­blème prin­ci­pal vient du fait que des options manquent, mais que les main­te­neurs veulent gar­der le pro­jet « simple ». C'est un choix, mais de fait, on fini par par­ser à la main le dic­tion­naire ren­voyé par docopt.
        J'ai plu­sieurs pro­jets per­so où un module est spé­ci­fi­que­ment dédié à l'appel de docopt et au post trai­te­ment des don­nées reçues.

        Dans ces cas là, pas­ser à arg­parse est, para­doxa­le­ment, plus lisible.

Laisser un commentaire