Expliquez les points d'entrée Python?

181

J'ai lu la documentation sur les points d'entrée des œufs dans Pylons et sur les pages Peak, et je ne comprends toujours pas vraiment. Quelqu'un pourrait-il me les expliquer?

Brad Wright
la source

Réponses:

168

Un "point d'entrée" est généralement une fonction (ou un autre objet de type fonction appelable) qu'un développeur ou un utilisateur de votre package Python pourrait vouloir utiliser, bien qu'un objet non appelable puisse également être fourni comme point d'entrée (aussi correctement souligné dans les commentaires!).

Le type de point d'entrée le plus populaire est le point d'entrée console_scripts , qui pointe vers une fonction que vous souhaitez rendre disponible en tant qu'outil de ligne de commande pour quiconque installe votre package. Cela va dans votre setup.py comme:

entry_points={
    'console_scripts': [
        'cursive = cursive.tools.cmd:cursive_command',
    ],
},

J'ai un package que je viens de déployer appelé "cursive.tools", et je voulais qu'il rende disponible une commande "cursive" que quelqu'un pourrait exécuter à partir de la ligne de commande, comme:

$ cursive --help
usage: cursive ...

La façon de faire est de définir une fonction, comme peut-être une fonction "cursive_command" dans cursive / tools / cmd.py qui ressemble à:

def cursive_command():
    args = sys.argv[1:]
    if len(args) < 1:
        print "usage: ..."

et ainsi de suite; il devrait supposer qu'il a été appelé à partir de la ligne de commande, analyser les arguments fournis par l'utilisateur et ... eh bien, faire tout ce que la commande est conçue pour faire.

Installez le package docutils pour un excellent exemple d'utilisation du point d'entrée: il installera quelque chose comme une demi-douzaine de commandes utiles pour convertir la documentation Python vers d'autres formats.

Brandon Rhodes
la source
3
les docutils actuels setup.pyne contiennent pas entry_pointsdu tout.
matt wilkie
2
C'est une excellente réponse car elle démontre la puissance de plusieurs projets partageant un seul nom de groupe entry_point, qui est "console_scripts". Comparez cette réponse à la réponse plus générale de Petri. Vous verrez que setuptools doit utiliser ce mécanisme pkg_resources pour obtenir les console_scripts, puis créer un wrapper shell autour d'eux. Inspirant? Utilisez ceux-ci. Ils sont bons pour plus que de simples scripts de console.
Bruno Bronosky
188

Points d'entrée fournit un enregistrement de nom d'objet permanent basé sur le système de fichiers et un mécanisme d'importation directe d'objet basé sur le nom (implémenté par le package setuptools ).

Ils associent les noms d'objets Python à des identificateurs de forme libre. Ainsi, tout autre code utilisant la même installation Python et connaissant l'identifiant peut accéder à un objet avec le nom associé, quel que soit l'endroit où l'objet est défini. le noms associés peuvent être n'importe quel nom existant dans un module Python ; par exemple le nom d'une classe, d'une fonction ou d'une variable. Le mécanisme du point d'entrée ne se soucie pas de ce à quoi le nom fait référence, tant qu'il est importable.

À titre d'exemple, utilisons (le nom de) une fonction et un module python imaginaire avec un nom complet 'myns.mypkg.mymodule':

def the_function():
   "function whose name is 'the_function', in 'mymodule' module"
   print "hello from the_function"

Les points d'entrée sont enregistrés via une déclaration de points d'entrée dans setup.py. Pour enregistrer la_fonction sous le point d'entrée appelé 'my_ep_func':

    entry_points = {
        'my_ep_group_id': [
            'my_ep_func = myns.mypkg.mymodule:the_function'
        ]
    },

Comme le montre l'exemple, les points d'entrée sont regroupés; il existe une API correspondante pour rechercher tous les points d'entrée appartenant à un groupe (exemple ci-dessous).

Lors d'une installation de paquet (c'est-à-dire en exécutant 'python setup.py install'), la déclaration ci-dessus est analysée par setuptools. Il écrit ensuite les informations analysées dans un fichier spécial. Après cela, l' API pkg_resources (qui fait partie de setuptools) peut être utilisée pour rechercher le point d'entrée et accéder aux objets avec le (s) nom (s) associé (s):

import pkg_resources

named_objects = {}
for ep in pkg_resources.iter_entry_points(group='my_ep_group_id'):
   named_objects.update({ep.name: ep.load()})

Ici, setuptools lit les informations de point d'entrée écrites dans des fichiers spéciaux. Il a trouvé le point d'entrée, importé le module (myns.mypkg.mymodule), et récupéré la_fonction définie ici, lors de l'appel à pkg_resources.load ().

En supposant qu'il n'y ait pas d'autres enregistrements de point d'entrée pour le même identifiant de groupe, appeler la fonction_fonction serait alors simple:

>>> named_objects['my_ep_func']()
hello from the_function

Ainsi, bien que peut-être un peu difficile à comprendre au début, le mécanisme du point d'entrée est en fait assez simple à utiliser. Il fournit un outil utile pour le développement de logiciels Python enfichables.

Pétri
la source
4
Où est le nom 'my_ep_func' utilisé dans tout ce processus? Il ne semble pas être utilisé pour quoi que ce soit par l'itérateur pkg_resources.
Kamil Kisiel
2
@KamilKisiel: dans l'exemple utilisé ici à titre d'illustration, le nom du point d'entrée n'est en effet utilisé pour rien, ni n'en a besoin; Que le nom du point d'entrée soit utilisé ou non pour quoi que ce soit dépend de l'application. Le nom est disponible simplement comme attribut de nom de l'instance de point d'entrée.
Petri
3
Je pense que supprimer le ep.name et faire de named_objects une liste au lieu d'un dictionnaire était déroutant, j'ai donc modifié la réponse. C'est ce que la réponse montre à la fois où obtenir le nom et s'il faut s'attendre à ce qu'il soit «the_function» ou «my_ep_func». Sinon, le lecteur devait trouver de la documentation supplémentaire ailleurs. C'est une excellente réponse et c'est l'explication la plus courte et la plus claire des points d'entrée que j'ai jamais vue!
Bruno Bronosky
3
J'ai créé un projet sur github qui illustre ce concept. github.com/RichardBronosky/entrypoint_demo
Bruno Bronosky
1
Ceci est une explication très claire des points d'entrée, que vous avez pour l'explication détaillée. Le EntryPointslien est périmé, bien que l'explication soit très claire.
Rahul Nair
18

D'un point de vue abstrait, les points d'entrée sont utilisés pour créer un registre à l'échelle du système d'appels Python qui implémentent certaines interfaces. Il existe des API dans pkg_resources pour voir quels points d'entrée sont annoncés par un package donné, ainsi que des API pour déterminer quels packages annoncent un certain point d'entrée.

Les points d'entrée sont utiles pour permettre à un package d'utiliser des plugins qui se trouvent dans un autre package. Par exemple, le projet Paste d' Ian Bicking utilise largement les points d'entrée. Dans ce cas, vous pouvez écrire un package qui annonce sa fabrique d'applications WSGI à l'aide du point d'entrée paste.app_factory.

Une autre utilisation des points d'entrée consiste à énumérer tous les packages du système qui fournissent des fonctionnalités de plug-in. Le framework Web TurboGears utilise le python.templating.enginespoint d'entrée pour rechercher des bibliothèques de modèles installées et disponibles.

Rick Copeland
la source