paint-brush
Comment créer un programme Python CLI pour la gestion de la carte Trello (Partie 1)par@elainechan01
2,031 lectures
2,031 lectures

Comment créer un programme Python CLI pour la gestion de la carte Trello (Partie 1)

par Elaine Yun Ru Chan19m2023/08/15
Read on Terminal Reader

Trop long; Pour lire

Comme indiqué sur Wikipedia, "Une interface de ligne de commande (CLI) est un moyen d'interagir avec un appareil ou un programme informatique avec les commandes d'un utilisateur ou d'un client, et les réponses de l'appareil ou du programme, sous la forme de lignes de texte." En d'autres termes, un programme CLI est un programme dans lequel l'utilisateur utilise la ligne de commande pour interagir avec le programme en fournissant des instructions à exécuter. De nombreux logiciels courants sont intégrés dans un programme CLI. Prenez l'éditeur de texte vim par exemple - un outil fourni avec n'importe quel système UNIX qui peut être activé simplement en exécutant vim <FILE> dans le terminal. Concernant la CLI Google Cloud, plongeons dans l'anatomie d'un programme CLI.
featured image - Comment créer un programme Python CLI pour la gestion de la carte Trello (Partie 1)
Elaine Yun Ru Chan HackerNoon profile picture
0-item

Clause de non-responsabilité : ce didacticiel suppose que les lecteurs ont une connaissance de base de Python, des API, de Git et des tests unitaires.

J'ai rencontré divers logiciels CLI avec les animations les plus cool, et cela m'a amené à me demander - pourrais-je jamais mettre à niveau mon projet d'école 'minimaliste' pierre-papier-ciseaux?


Salut, jouons ! Choisissez votre combattant (pierre, papier, ciseaux) : pierre

Qu'est-ce qu'un programme CLI ?

Comme indiqué sur Wikipedia, "Une interface de ligne de commande (CLI) est un moyen d'interagir avec un appareil ou un programme informatique avec les commandes d'un utilisateur ou d'un client, et les réponses de l'appareil ou du programme, sous la forme de lignes de texte."


En d'autres termes, un programme CLI est un programme dans lequel l'utilisateur utilise la ligne de commande pour interagir avec le programme en fournissant des instructions à exécuter.


De nombreux logiciels courants sont intégrés dans un programme CLI. Prenez l'éditeur de texte vim par exemple - un outil fourni avec n'importe quel système UNIX qui peut être activé simplement en exécutant vim <FILE> dans le terminal.


Concernant la CLI Google Cloud , plongeons dans l'anatomie d'un programme CLI.

Arguments

Les arguments (paramètres) sont des éléments d'information fournis à un programme. Il est souvent appelé arguments positionnels car ils sont identifiés par leur position.


Par exemple, lorsque nous voulons définir la propriété project dans la section principale, nous exécutons gcloud config set project <PROJECT_ID>


Notamment, nous pouvons traduire cela en

Argument

Contenu

Arg 0

gcloud

Arg 1

configuration

Commandes

Les commandes sont un tableau d'arguments qui fournissent des instructions à l'ordinateur.


Sur la base de l'exemple précédent, nous définissons la propriété project dans la section principale en exécutant gcloud config set project <PROJECT_ID>


En d'autres termes, set est une commande.

Commandes facultatives

Habituellement, des commandes sont requises mais nous pouvons faire des exceptions. En fonction du cas d'utilisation du programme, nous pouvons définir des commandes facultatives.


En se référant à la commande gcloud config , comme indiqué dans leur documentation officielle, gcloud config est un groupe de commandes qui vous permet de modifier les propriétés. L'utilisation est telle que :

 gcloud config GROUP | COMMAND [GCLOUD_WIDE_FLAG … ]

où COMMAND peut être soit set , list , etc. (Notez que GROUP est config )

Choix

Les options sont des types documentés de paramètres qui modifient le comportement d'une commande. Ce sont des paires clé-valeur désignées par '-' ou '--'.


Pour en revenir à l'utilisation du groupe de commandes gcloud config , la ou les options, dans ce cas, sont GCLOUD_WIDE_FLAG .


Par exemple, disons que nous voulions afficher l'utilisation détaillée et la description de la commande, nous exécutons gcloud config set –help . En d'autres termes, --help est l'option.


Un autre exemple est lorsque nous voulons définir la propriété de zone dans la section de calcul d'un projet spécifique, nous exécutons gcloud config set compute <ZONE_NAME> –project=<PROJECT_ID> . En d'autres termes, --project est une option qui contient la valeur <PROJECT_ID> .


Il est également important de noter que leurs positions n'ont généralement pas d'importance.

Options obligatoires

Les options, comme son nom, sont généralement facultatives, mais peuvent également être adaptées pour être obligatoires.


Par exemple, lorsque nous voulons créer un cluster dataproc, nous exécutons gcloud dataproc clusters create <CLUSTER_NAME> –region=<REGION> . Et comme indiqué dans leur documentation d'utilisation :

 gcloud dataproc clusters create (CLUSTER: –region=REGION)

L'indicateur --region est obligatoire s'il n'a pas été configuré précédemment.

Options courtes contre options longues

Les options courtes commencent par - suivi d'un seul caractère alphanumérique, tandis que les options longues commencent par -- suivi de plusieurs caractères. Considérez les options courtes comme des raccourcis lorsque l'utilisateur est sûr de ce qu'il veut, tandis que les options longues sont plus lisibles.


Vous avez choisi le rock ! L'ordinateur va maintenant faire sa sélection.

Qu'allons-nous réaliser grâce à ce tutoriel ?

Alors j'ai menti… Nous n'essaierons pas de mettre à jour le programme CLI de base pierre-papier-ciseaux.

Au lieu de cela, jetons un coup d'œil à un scénario du monde réel :

Aperçu et objectifs

Votre équipe utilise Trello pour suivre les problèmes et l'avancement du projet. Votre équipe recherche un moyen plus simplifié d'interagir avec le tableau - quelque chose de similaire à la création d'un nouveau référentiel GitHub via le terminal. L'équipe s'est tournée vers vous pour créer un programme CLI avec cette exigence de base de pouvoir ajouter une nouvelle carte à la colonne 'To Do' du tableau.


Sur la base de l'exigence mentionnée, élaborons notre programme CLI en définissant ses exigences :


Exigences fonctionnelles

  • L'utilisateur peut ajouter une nouvelle carte à une colonne du tableau
    • Entrées obligatoires : colonne, nom de la carte
    • Entrées facultatives : description de la carte, étiquettes de la carte (sélectionnez parmi celles existantes)

Prérogatives non fonctionnelles

  • Programme pour inviter l'utilisateur à donner accès au compte Trello (autorisation)
  • Programme pour inviter l'utilisateur à définir sur quelle carte Trello travailler (configuration)

Exigences facultatives

  • L'utilisateur peut ajouter une nouvelle colonne au tableau
  • L'utilisateur peut ajouter une nouvelle étiquette au tableau
  • L'utilisateur peut voir une vue simplifiée/détaillée de toutes les colonnes


Sur la base de ce qui précède, nous pouvons formaliser les commandes et les options de notre programme CLI comme telles :

Tableau détaillé de la structure CLI en fonction des exigences


Ps Ne vous inquiétez pas pour les deux dernières colonnes, nous en apprendrons plus tard…


En ce qui concerne notre pile technologique, nous nous en tiendrons à ceci :


Tests unitaires

  • pytest
  • pytest-mock
  • cli-test-helpers

Trello

  • py-trello (enveloppe Python pour le SDK Trello)

CLI

  • dactylographie
  • riche
  • menu-terme-simple

Utilitaires (Divers)

  • python-dotenv

Chronologie

Nous aborderons ce projet en plusieurs parties et voici un extrait de ce à quoi vous pouvez vous attendre :


Partie 1

  • Implémentation de la logique métier py-trello

Partie 2

  • Implémentation de la logique métier CLI
  • Distribution du programme CLI sous forme de package

Partie 3

  • Mise en œuvre des exigences fonctionnelles facultatives
  • Mise à jour du paquet


L'ordinateur a choisi les ciseaux ! Voyons qui gagnera cette bataille...

Commençons

Structure des dossiers

L'objectif est de distribuer le programme CLI sous forme de package sur PyPI . Ainsi, une telle configuration est nécessaire :

 trellocli/ __init__.py __main__.py models.py cli.py trelloservice.py tests/ test_cli.py test_trelloservice.py README.md pyproject.toml .env .gitignore


Voici une plongée en profondeur dans chaque fichier et/ou répertoire :

  • trellocli : agit comme le nom du package à utiliser par les utilisateurs, par exemple, pip install trellocli
    • __init__.py : représente la racine du package, conforme le dossier en tant que package Python
    • __main__.py : définit le point d'entrée et permet aux utilisateurs d'exécuter des modules sans spécifier le chemin du fichier en utilisant l'indicateur -m , par exemple, python -m <module_name> pour remplacer python -m <parent_folder>/<module_name>.py
    • models.py : stocke les classes utilisées globalement, par exemple, les modèles auxquels les réponses de l'API sont censées se conformer
    • cli.py : stocke la logique métier pour les commandes et options CLI
    • trelloservice.py : stocke la logique métier pour interagir avec py-trello
  • tests : stocke les tests unitaires du programme
    • test_cli.py : stocke les tests unitaires pour l'implémentation de la CLI
    • test_trelloservice.py : stocke les tests unitaires pour l'interaction avec py-trello
  • README.md : stocke la documentation du programme
  • pyproject.toml : stocke les configurations et les exigences du package
  • .env : stocke les variables d'environnement
  • .gitignore : spécifie les fichiers à ignorer (non suivis) lors du contrôle de version


Pour une explication plus détaillée de la publication de packages Python, voici un excellent article à consulter : How to Publish an Open-Source Python Package to PyPI by Geir Arne Hjelle

Installation

Avant de commencer, abordons la configuration du package.


En commençant par le fichier __init__.py dans notre package, qui serait l'endroit où les constantes et les variables du package sont stockées, telles que le nom et la version de l'application. Dans notre cas, nous souhaitons initialiser les éléments suivants :

  • nom de l'application
  • version
  • Constantes SUCCESS et ERROR
 # trellocli/__init__.py __app_name__ = "trellocli" __version__ = "0.1.0" ( SUCCESS, TRELLO_WRITE_ERROR, TRELLO_READ_ERROR ) = range(3) ERRORS = { TRELLO_WRITE_ERROR: "Error when writing to Trello", TRELLO_READ_ERROR: "Error when reading from Trello" }


Passant au fichier __main__.py , le flux principal de votre programme doit être stocké ici. Dans notre cas, nous allons stocker le point d'entrée du programme CLI, en supposant qu'il y aura une fonction appelable dans cli.py .

 # trellocli/__main__.py from trellocli import cli def main(): # we'll modify this later - after the implementation of `cli.py` pass if __name__ == "__main__": main()


Maintenant que le package est configuré, intéressons-nous à la mise à jour de notre fichier README.md (documentation principale). Il n'y a pas de structure spécifique que nous devons suivre, mais un bon README consisterait en ce qui suit :

  • Aperçu
  • Installation et exigences
  • Mise en route et utilisation

Un autre excellent article à lire si vous souhaitez approfondir: Comment écrire un bon README par merlos


Voici comment j'aimerais structurer le README pour ce projet

 <!--- README.md --> # Overview # Getting Started # Usage # Architecture ## Data Flow ## Tech Stack # Running Tests # Next Steps # References


Laissons le squelette tel qu'il est pour le moment - nous y reviendrons plus tard.


Continuons, configurons les métadonnées de notre package en fonction de la documentation officielle

 # pyproject.toml [project] name = "trellocli_<YOUR_USERNAME>" version = "0.1.0" authors = [ { name = "<YOUR_NAME>", email = "<YOUR_EMAIL>" } ] description = "Program to modify your Trello boards from your computer's command line" readme = "README.md" requires-python = ">=3.7" classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ] dependencies = [] [project.urls] "Homepage" = ""


Remarquez comment il y a des espaces réservés que vous devez modifier, par exemple, votre nom d'utilisateur, votre nom…


Sur une autre note, nous laisserons l'URL de la page d'accueil vide pour le moment. Nous apporterons des modifications après l'avoir publié sur GitHub. Nous allons également laisser la partie dépendances vide pour le moment et l'ajouter au fur et à mesure.


Le prochain sur la liste serait notre fichier .env où nous stockons nos variables d'environnement telles que les secrets et les clés de l'API. Il est important de noter que ce fichier ne doit pas être suivi par Git car il contient des informations sensibles.


Dans notre cas, nous allons stocker nos informations d'identification Trello ici. Pour créer un Power-Up dans Trello, suivez ce guide . Plus précisément, en fonction de l'utilisation par py-trello , comme nous avons l'intention d'utiliser OAuth pour notre application, nous aurons besoin des éléments suivants pour interagir avec Trello :

  • Clé API (pour notre application)
  • API Secret (pour notre application)
  • Token (token de l'utilisateur pour accorder l'accès à ses données)


Une fois que vous avez récupéré votre clé API et votre secret, stockez-les dans le fichier .env en tant que tels

 # .env TRELLO_API_KEY=<your_api_key> TRELLO_API_SECRET=<your_api_secret>


Enfin, utilisons le modèle Python .gitignore qui peut être trouvé ici . Notez que cela est crucial pour s'assurer que notre fichier .env n'est jamais suivi - si à un moment donné, notre fichier .env a été suivi, même si nous avons supprimé le fichier dans les étapes ultérieures, le dommage est fait et les acteurs malveillants peuvent retracer le précédent correctifs pour les informations sensibles.


Maintenant que la configuration est terminée, poussons nos modifications vers GitHub. En fonction des métadonnées spécifiées dans pyproject.toml , n'oubliez pas de mettre à jour votre LICENCE et l'URL de votre page d'accueil en conséquence. Pour référence sur la façon d'écrire de meilleurs commits : Write Better Commits, Build Better Projects par Victoria Dye


Autres étapes notables :

Tests unitaires

Avant de commencer à écrire nos tests, il est important de noter que parce que nous travaillons avec une API, nous allons implémenter des tests fictifs pour pouvoir tester notre programme sans risque de temps d'arrêt de l'API. Voici un autre excellent article sur les tests simulés par Real Python : Mocking External APIs in Python


En fonction des exigences fonctionnelles, notre principale préoccupation est de permettre aux utilisateurs d'ajouter une nouvelle carte. Référencer la méthode dans py-trello : add_card . Pour ce faire, il faut appeler la méthode add_card de la classe List , dont on peut récupérer la fonction get_list de la classe Board , dont on peut récupérer…


Vous comprenez l'essentiel - nous aurons besoin de nombreuses méthodes d'assistance pour atteindre notre destination finale, disons-le en mots :

  • Test pour récupérer le jeton du client
  • Test pour récupérer les planches
  • Test pour récupérer une planche
  • Test pour récupérer les listes du tableau
  • Test pour récupérer une liste
  • Test pour récupérer les étiquettes du tableau
  • Test pour récupérer une étiquette
  • Tester pour ajouter une carte
  • Test pour ajouter une étiquette à la carte


Il est également important de noter que lors de l'écriture de tests unitaires, nous voulons que nos tests soient aussi étendus que possible - Gère-t-il bien les erreurs ? Couvre-t-il tous les aspects de notre programme ?


Cependant, juste pour les besoins de ce didacticiel, nous allons simplifier les choses en ne vérifiant que les cas de réussite.


Avant de plonger dans le code, modifions notre fichier pyproject.toml pour inclure les dépendances nécessaires à l'écriture/exécution des tests unitaires.

 # pyproject.toml [project] dependencies = [ "pytest==7.4.0", "pytest-mock==3.11.1" ]


Ensuite, activons notre virtualenv et exécutons pip install . pour installer les dépendances.


Une fois cela fait, écrivons enfin quelques tests. En général, nos tests doivent inclure une réponse simulée à renvoyer, un correctif à la fonction que nous essayons de tester en fixant la valeur de retour avec la réponse simulée, et enfin un appel à la fonction. Voici un exemple de test pour récupérer les jetons d'accès de l'utilisateur :

 # tests/test_trelloservice.py # module imports from trellocli import SUCCESS from trellocli.trelloservice import TrelloService from trellocli.models import * # dependencies imports # misc imports def test_get_access_token(mocker): """Test to check success retrieval of user's access token""" mock_res = GetOAuthTokenResponse( token="test", token_secret="test", status_code=SUCCESS ) mocker.patch( "trellocli.trelloservice.TrelloService.get_user_oauth_token", return_value=mock_res ) trellojob = TrelloService() res = trellojob.get_user_oauth_token() assert res.status_code == SUCCESS


Remarquez dans mon exemple de code que GetOAuthTokenResponse est un modèle qui n'a pas encore été défini dans models.py . Il fournit une structure pour écrire du code plus propre, nous verrons cela en action plus tard.


Pour exécuter nos tests, exécutez simplement python -m pytest . Remarquez comment nos tests échoueront, mais ce n'est pas grave - cela finira par s'arranger.


Challenge Corner 💡 Pouvez-vous essayer d'écrire plus de tests par vous-même ? N'hésitez pas à vous référer àce patch pour voir à quoi ressemblent mes tests


Pour l'instant, construisons notre trelloservice . En commençant par ajouter une nouvelle dépendance, c'est le wrapper py-trello .

 # pyproject.toml dependencies = [ "pytest==7.4.0", "pytest-mock==3.11.1", "py-trello==0.19.0" ]


Encore une fois, lancez pip install . pour installer les dépendances.

Des modèles

Maintenant, commençons par construire nos modèles - pour réguler les réponses que nous attendons dans trelloservice . Pour cette partie, il est préférable de se référer à nos tests unitaires et au code source py-trello pour comprendre le type de valeur de retour auquel nous pouvons nous attendre.


Par exemple, disons que nous voulons récupérer le jeton d'accès de l'utilisateur, en nous référant à la fonction create_oauth_token de py-trello ( code source ), nous savons que la valeur de retour doit ressembler à ceci

 # trellocli/models.py # module imports # dependencies imports # misc imports from typing import NamedTuple class GetOAuthTokenResponse(NamedTuple): token: str token_secret: str status_code: int


D'autre part, soyez conscient des conventions de nommage conflictuelles. Par exemple, le module py-trello a une classe nommée List . Une solution de contournement consisterait à fournir un alias lors de l'importation.

 # trellocli/models.py # dependencies imports from trello import List as Trellolist


N'hésitez pas à profiter également de cette occasion pour adapter les modèles aux besoins de votre programme. Par exemple, supposons que vous n'ayez besoin que d'un seul attribut de la valeur de retour, vous pouvez refactoriser votre modèle pour vous attendre à extraire ladite valeur de la valeur de retour plutôt que de la stocker dans son ensemble.

 # trellocli/models.py class GetBoardName(NamedTuple): """Model to store board id Attributes id (str): Extracted board id from Board value type """ id: str


Challenge Corner 💡 Pouvez-vous essayer d'écrire plus de modèles par vous-même ? N'hésitez pas à vous référer àce patch pour voir à quoi ressemblent mes modèles

Logique métier

Installation

Modèles en bas, commençons officiellement à coder le trelloservice . Encore une fois, nous devrions nous référer aux tests unitaires que nous avons créés - disons que la liste actuelle des tests ne fournit pas une couverture complète pour le service, revenez toujours et ajoutez plus de tests si nécessaire.


Comme d'habitude, incluez toutes les instructions d'importation vers le haut. Créez ensuite la classe TrelloService et les méthodes d'espace réservé comme prévu. L'idée est que nous allons initialiser une instance partagée du service dans cli.py et appeler ses méthodes en conséquence. De plus, nous visons l'évolutivité, d'où le besoin d'une couverture étendue.

 # trellocli/trelloservice.py # module imports from trellocli import TRELLO_READ_ERROR, TRELLO_WRITE_ERROR, SUCCESS from trellocli.models import * # dependencies imports from trello import TrelloClient # misc imports class TrelloService: """Class to implement the business logic needed to interact with Trello""" def __init__(self) -> None: pass def get_user_oauth_token() -> GetOAuthTokenResponse: pass def get_all_boards() -> GetAllBoardsResponse: pass def get_board() -> GetBoardResponse: pass def get_all_lists() -> GetAllListsResponse: pass def get_list() -> GetListResponse: pass def get_all_labels() -> GetAllLabelsResponse: pass def get_label() -> GetLabelResponse: pass def add_card() -> AddCardResponse: pass


Ps remarquez comment cette fois-ci, lorsque nous exécutons nos tests, nos tests passeront. En fait, cela nous aidera à nous assurer que nous restons sur la bonne voie. Le flux de travail devrait consister à étendre nos fonctions, à exécuter nos tests, à vérifier la réussite/l'échec et à refactoriser en conséquence.

Autorisation et initialisation de TrelloClient

Commençons par la fonction __init__ . L'idée est d'appeler la fonction get_user_oauth_token ici et d'initialiser le TrelloClient . Encore une fois, soulignant la nécessité de stocker ces informations sensibles uniquement dans le fichier .env , nous utiliserons la dépendance python-dotenv pour récupérer les informations sensibles. Après avoir modifié notre fichier pyproject.toml en conséquence, commençons à implémenter les étapes d'autorisation.

 # trellocli/trelloservice.py class TrelloService: """Class to implement the business logic needed to interact with Trello""" def __init__(self) -> None: self.__load_oauth_token_env_var() self.__client = TrelloClient( api_key=os.getenv("TRELLO_API_KEY"), api_secret=os.getenv("TRELLO_API_SECRET"), token=os.getenv("TRELLO_OAUTH_TOKEN") ) def __load_oauth_token_env_var(self) -> None: """Private method to store user's oauth token as an environment variable""" load_dotenv() if not os.getenv("TRELLO_OAUTH_TOKEN"): res = self.get_user_oauth_token() if res.status_code == SUCCESS: dotenv_path = find_dotenv() set_key( dotenv_path=dotenv_path, key_to_set="TRELLO_OAUTH_TOKEN", value_to_set=res.token ) else: print("User denied access.") self.__load_oauth_token_env_var() def get_user_oauth_token(self) -> GetOAuthTokenResponse: """Helper method to retrieve user's oauth token Returns GetOAuthTokenResponse: user's oauth token """ try: res = create_oauth_token() return GetOAuthTokenResponse( token=res["oauth_token"], token_secret=res["oauth_token_secret"], status_code=SUCCESS ) except: return GetOAuthTokenResponse( token="", token_secret="", status_code=TRELLO_AUTHORIZATION_ERROR )


Dans cette implémentation, nous avons créé une méthode d'assistance pour gérer toutes les erreurs prévisibles, par exemple lorsque l'utilisateur clique sur Deny lors de l'autorisation. De plus, il est configuré pour demander récursivement l'autorisation de l'utilisateur jusqu'à ce qu'une réponse valide soit renvoyée, car le fait est que nous ne pouvons pas continuer tant que l'utilisateur n'autorise pas notre application à accéder aux données de son compte.


Challenge Corner 💡 Avis TRELLO_AUTHORIZATION_ERROR ? Pouvez-vous déclarer cette erreur en tant que constante de package ? Reportez-vous à Configuration pour plus d'informations

Fonctions d'assistance

Maintenant que la partie autorisation est terminée, passons aux fonctions d'assistance, en commençant par récupérer les tableaux Trello de l'utilisateur.

 # trellocli/trelloservice.py def get_all_boards(self) -> GetAllBoardsResponse: """Method to list all boards from user's account Returns GetAllBoardsResponse: array of user's trello boards """ try: res = self.__client.list_boards() return GetAllBoardsResponse( res=res, status_code=SUCCESS ) except: return GetAllBoardsResponse( res=[], status_code=TRELLO_READ_ERROR ) def get_board(self, board_id: str) -> GetBoardResponse: """Method to retrieve board Required Args board_id (str): board id Returns GetBoardResponse: trello board """ try: res = self.__client.get_board(board_id=board_id) return GetBoardResponse( res=res, status_code=SUCCESS ) except: return GetBoardResponse( res=None, status_code=TRELLO_READ_ERROR )


Comme pour récupérer les listes (colonnes), il va falloir sortir la classe Board de py-trello , autrement dit, il faut accepter un nouveau paramètre de type valeur Board .

 # trellocli/trelloservice.py def get_all_lists(self, board: Board) -> GetAllListsResponse: """Method to list all lists (columns) from the trello board Required Args board (Board): trello board Returns GetAllListsResponse: array of trello lists """ try: res = board.all_lists() return GetAllListsResponse( res=res, status_code=SUCCESS ) except: return GetAllListsResponse( res=[], status_code=TRELLO_READ_ERROR ) def get_list(self, board: Board, list_id: str) -> GetListResponse: """Method to retrieve list (column) from the trello board Required Args board (Board): trello board list_id (str): list id Returns GetListResponse: trello list """ try: res = board.get_list(list_id=list_id) return GetListResponse( res=res, status_code=SUCCESS ) except: return GetListResponse( res=None, status_code=TRELLO_READ_ERROR )


Challenge Corner 💡 Pourriez-vous implémenter vous-même les fonctions get_all_labels et get_label ? Révisez la classe Board de py-trello . N'hésitez pas à vous référer àce patch pour voir à quoi ressemble mon implémentation

Fonction pour ajouter une nouvelle carte

Enfin et surtout, nous avons enfin atteint ce que nous visons depuis tout ce temps : ajouter une nouvelle carte. Gardez à l'esprit que nous n'utiliserons pas toutes les fonctions précédemment déclarées ici - le but des fonctions d'assistance est d'augmenter l'évolutivité.

 # trellocli/trelloservice.py def add_card( self, col: Trellolist, name: str, desc: str = "", labels: List[Label] = [] ) -> AddCardResponse: """Method to add a new card to a list (column) on the trello board Required Args col (Trellolist): trello list name (str): card name Optional Args desc (str): card description labels (List[Label]): list of labels to be added to the card Returns AddCardResponse: newly-added card """ try: # create new card new_card = col.add_card(name=name) # add optional description if desc: new_card.set_description(description=desc) # add optional labels if labels: for label in labels: new_card.add_label(label=label) return AddCardResponse( res=new_card, status_code=SUCCESS ) except: return AddCardResponse( res=new_card, status_code=TRELLO_WRITE_ERROR )


🎉 Maintenant que c'est fait et dépoussiéré, n'oubliez pas de mettre à jour votre README en conséquence et de pousser votre code sur GitHub.


Toutes nos félicitations! Tu as gagné. Rejouer (o/N) ?

Conclure

Merci de m'avoir supporté :) Grâce à ce didacticiel, vous avez appris à implémenter la simulation lors de l'écriture de tests unitaires, à structurer des modèles pour la cohérence, à lire le code source pour trouver des fonctionnalités clés et à implémenter une logique métier à l'aide d'un wrapper tiers.


Gardez un œil sur la partie 2, où nous approfondirons la mise en œuvre du programme CLI lui-même.


En attendant, restons en contact 👀