Bonne pratique pour lib+cli

Plop,

Pour un projet (Prismedia) d’upload de vidéos sur Youtube et Peertube depuis la CLI, on se dit que ça serait intéressant d’exposer une bibliothèque que d’autres pourraient utiliser dans leur projet. Ça nous permettrais aussi sûrement d’améliorer notre base de code.

  • Quels sont les bonnes pratiques en python pour faire une lib et une cli ? (Je sais que rust propose d’avoir lib.rs et main.rs dans le même projet, mais en python je ne sais pas si plusieurs projets sont nécessaires ou si un moyen existe et que pip reste « content ».)

On pense aussi à autoriser/créer des plugins, en se disant que certaines nouvelles fonctionnalités ne seront peut êtres pas voulus par tout le monde, ou voulues avec des hypothèse et donc algo/résolutions différentes.
Par exemple : 1) un moyen d’utiliser la cli depuis un cron donc avoir toujours les mêmes arguments qui uploadent des vidéos différentes (sans doublons).
2) Un outil qui maintiens un caldav en fonction des dates de publications des vidéos.

  • Y a t’il une bonne pratique pour l’architecture de plugins ? (Un projet = un repo git ? Tout dans le même repo avec possibilité de remplacer pour des plugin « non officiels » ?)
  • Une autre architecture nous correspondrait-elle mieux ?

Je ne vais répondre que pour la partie lib+cli, il y a deux-trois écoles :

À l’échelle d’un module Python

Dans ce cas, c’est le if __name__ == "__main__": qui fait le job :

def fib(n):
    if n < 2:
        return 1
    return fib(n - 1) + fib(n - 2)

if __name__ == "__main__":
    import sys
    print(fib(int(sys.argv[1])))

J’ai pris beaucoup de raccourcis discutables, mais l’idée est là, c’est utilisable en CLI :

$ python3 fib.py 4
5

et en lib :

$ python3
>>> from fib import fib
>>> print(fib(4))
5

À l’échelle d’un paquet

Lorsqu’on importe un paquet, c’est l’espace de nom du __init__.py qui est importé, donc ça se comporte comme une lib.

Lorsqu’on utilise python3 -m foo (c.f. la doc) c’est le fichier __main__.py du paquet foo qui est exécuté, ça se comporte “comme un programme”.

À l’échelle d’un projet

Tu peux utiliser les entry points de setuptools, ça se présente par exemple comme je fais dans le projet oeis. La ligne oeis=oeis:main signifie : « À l’installation, fait moi un programme oeis qui lorsqu’il est appelé exécute la fonction main du module oeis.

1 J'aime

Merci pour ces explications.
De ce que je comprends l’architecture de base qu’on as est bien faite (fichiers __init__.py et __main__.py, configuration poetry pour le projet). Il n’y a plus qu’a organiser le projet pour avoir une API correct et si possible documentée.

Donc en vrai dès aujourd’hui un projet pourrait dépendre de Prismedia. Sauf qu’il aurait sûrement du mal à l’utiliser en tant que lib vue qu’on n’a pas prévue le code en tant que tel. Ça me rassure sur ce point :slight_smile:

Pour l’idée des plugins je vais voir pendant ma modification prévue pour l’utilisation en tant que lib si des idées me viennent.