Haftungsausschluss: In diesem Tutorial wird davon ausgegangen, dass die Leser über grundlegende Kenntnisse in Python, APIs, Git und Unit Tests verfügen.
Ich bin auf verschiedene CLI-Software mit den coolsten Animationen gestoßen und habe mich gefragt: Könnte ich jemals mein „minimalistisches“ Stein-Schere-Papier-Schulprojekt aktualisieren?
Hallo, lass uns spielen! Wählen Sie Ihren Kämpfer (Stein, Papier, Schere): Stein
Wie es auf Wikipedia heißt: „Eine Befehlszeilenschnittstelle (CLI) ist ein Mittel zur Interaktion mit einem Gerät oder Computerprogramm mit Befehlen von einem Benutzer oder Client und Antworten vom Gerät oder Programm in Form von Textzeilen.“
Mit anderen Worten ist ein CLI-Programm ein Programm, bei dem der Benutzer die Befehlszeile verwendet, um mit dem Programm zu interagieren, indem er Anweisungen zur Ausführung gibt.
Viele alltägliche Software ist als CLI-Programm verpackt. Nehmen Sie zum Beispiel den vim
Texteditor – ein Tool, das mit jedem UNIX-System geliefert wird und einfach durch Ausführen vim <FILE>
im Terminal aktiviert werden kann.
Lassen Sie uns in Bezug auf die Google Cloud CLI in die Anatomie eines CLI-Programms eintauchen.
Argumente (Parameter) sind Informationselemente, die einem Programm bereitgestellt werden. Sie werden oft als Positionsargumente bezeichnet, weil sie durch ihre Position identifiziert werden.
Wenn wir beispielsweise die project
im Kernabschnitt festlegen möchten, führen wir gcloud config set project <PROJECT_ID>
aus
Insbesondere können wir dies in übersetzen
Streit | Inhalt |
---|---|
Argument 0 | gcloud |
Argument 1 | config |
… | … |
Befehle sind eine Reihe von Argumenten, die dem Computer Anweisungen geben.
Basierend auf dem vorherigen Beispiel legen wir die project
im Kernabschnitt fest, indem wir gcloud config set project <PROJECT_ID>
ausführen
Mit anderen Worten, set
ist ein Befehl.
Normalerweise sind Befehle erforderlich, wir können jedoch Ausnahmen machen. Basierend auf dem Anwendungsfall des Programms können wir optionale Befehle definieren.
Bezugnehmend auf den Befehl gcloud config
, wie in der offiziellen Dokumentation angegeben, handelt es sich bei gcloud config
um eine Befehlsgruppe, mit der Sie Eigenschaften ändern können. Die Verwendung ist als solche:
gcloud config GROUP | COMMAND [GCLOUD_WIDE_FLAG … ]
wobei COMMAND entweder set
, list
usw. sein kann ... (Beachten Sie, dass GROUP config
ist)
Optionen sind dokumentierte Parametertypen, die das Verhalten eines Befehls ändern. Es handelt sich um Schlüssel-Wert-Paare, die mit „-“ oder „--“ gekennzeichnet sind.
Zurück zur Verwendung der gcloud config
Befehlsgruppe: Die Option(en) sind in diesem Fall GCLOUD_WIDE_FLAG
.
Angenommen, wir möchten die detaillierte Verwendung und Beschreibung des Befehls anzeigen, führen wir gcloud config set –help
aus. Mit anderen Worten: --help
ist die Option.
Ein weiteres Beispiel: Wenn wir die Zoneneigenschaft im Compute-Abschnitt eines bestimmten Projekts festlegen möchten, führen wir gcloud config set compute <ZONE_NAME> –project=<PROJECT_ID>
aus. Mit anderen Worten: --project
ist eine Option, die den Wert <PROJECT_ID>
enthält.
Es ist auch wichtig zu beachten, dass ihre Positionen normalerweise keine Rolle spielen.
Optionen wie der Name sind normalerweise optional, können aber auch so angepasst werden, dass sie obligatorisch sind.
Wenn wir beispielsweise einen Dataproc-Cluster erstellen möchten, führen wir gcloud dataproc clusters create <CLUSTER_NAME> –region=<REGION>
aus. Und wie in ihrer Nutzungsdokumentation angegeben:
gcloud dataproc clusters create (CLUSTER: –region=REGION)
Das Flag --region
ist obligatorisch, wenn es nicht zuvor konfiguriert wurde.
Kurze Optionen beginnen mit -
gefolgt von einem einzelnen alphanumerischen Zeichen, während lange Optionen mit --
gefolgt von mehreren Zeichen beginnen. Stellen Sie sich kurze Optionen als Abkürzungen vor, wenn der Benutzer sicher ist, was er möchte, während lange Optionen besser lesbar sind.
Du hast dich für Rock entschieden! Der Computer trifft nun seine Auswahl.
Also habe ich gelogen ... Wir werden nicht versuchen, das CLI-Programm „Stein-Papier-Schere“ zu aktualisieren.
Schauen wir uns stattdessen ein reales Szenario an:
Ihr Team verwendet Trello, um die Probleme und den Fortschritt des Projekts zu verfolgen. Ihr Team sucht nach einer einfacheren Möglichkeit, mit dem Board zu interagieren – ähnlich wie beim Erstellen eines neuen GitHub-Repositorys über das Terminal. Das Team hat sich an Sie gewandt, um ein CLI-Programm mit der Grundvoraussetzung zu erstellen, dass Sie der Spalte „Zu erledigen“ des Boards eine neue Karte hinzufügen können.
Basierend auf der genannten Anforderung entwerfen wir unser CLI-Programm, indem wir seine Anforderungen definieren:
Funktionale Anforderungen
Nicht-funktionale Anforderungen
Optionale Anforderungen
Basierend auf dem oben Gesagten können wir die Befehle und Optionen unseres CLI-Programms wie folgt formalisieren:
Ps. Machen Sie sich keine Sorgen wegen der letzten beiden Spalten, wir werden später mehr darüber erfahren …
Was unseren Tech-Stack betrifft, bleiben wir dabei:
Unit-Tests
Trello
CLI
Dienstprogramme (Verschiedenes)
Wir werden dieses Projekt in Teilen angehen und hier ist ein Ausschnitt dessen, was Sie erwarten können:
Teil 1
py-trello
GeschäftslogikTeil 2
Teil 3
Der Computer hat sich für die Schere entschieden! Mal sehen, wer diesen Kampf gewinnt ...
Ziel ist es, das CLI-Programm als Paket auf PyPI zu verteilen. Daher ist ein solches Setup erforderlich:
trellocli/ __init__.py __main__.py models.py cli.py trelloservice.py tests/ test_cli.py test_trelloservice.py README.md pyproject.toml .env .gitignore
Hier ist ein tiefer Einblick in jede Datei und/oder jedes Verzeichnis:
trellocli
: fungiert als Paketname, der von Benutzern verwendet werden soll, z. B. pip install trellocli
__init__.py
: Stellt das Stammverzeichnis des Pakets dar und passt den Ordner als Python-Paket an__main__.py
: Definiert den Einstiegspunkt und ermöglicht Benutzern das Ausführen von Modulen ohne Angabe des Dateipfads durch Verwendung des Flags -m
, z. B. python -m <module_name>
, um python -m <parent_folder>/<module_name>.py
zu ersetzenmodels.py
: speichert global verwendete Klassen, z. B. Modelle, denen API-Antworten entsprechen sollencli.py
: speichert die Geschäftslogik für CLI-Befehle und -Optionentrelloservice.py
: speichert die Geschäftslogik für die Interaktion mit py-trello
tests
: speichert Unit-Tests für das Programmtest_cli.py
: speichert Unit-Tests für die CLI-Implementierungtest_trelloservice.py
: speichert Unit-Tests für die Interaktion mit py-trello
README.md
: speichert die Dokumentation für das Programmpyproject.toml
: speichert die Konfigurationen und Anforderungen des Pakets.env
: speichert Umgebungsvariablen.gitignore
: Gibt die Dateien an, die während der Versionskontrolle ignoriert (nicht verfolgt) werden sollen
Eine ausführlichere Erklärung zum Veröffentlichen von Python-Paketen finden Sie in diesem großartigen Artikel: „How to Publish an Open-Source Python Package to PyPI“ von Geir Arne Hjelle
Bevor wir beginnen, gehen wir zunächst auf die Einrichtung des Pakets ein.
Beginnend mit der Datei __init__.py
in unserem Paket, in der Paketkonstanten und -variablen wie App-Name und -Version gespeichert werden. In unserem Fall wollen wir Folgendes initialisieren:
# 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" }
Wenn wir zur Datei __main__.py
übergehen, sollte hier der Hauptablauf Ihres Programms gespeichert sein. In unserem Fall speichern wir den Einstiegspunkt des CLI-Programms, vorausgesetzt, dass es in cli.py
eine aufrufbare Funktion gibt.
# 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()
Nachdem das Paket nun eingerichtet wurde, werfen wir einen Blick auf die Aktualisierung unserer README.md
Datei (Hauptdokumentation). Es gibt keine bestimmte Struktur, der wir folgen müssen, aber eine gute README-Datei würde aus Folgendem bestehen:
Ein weiterer toller Beitrag zum Nachlesen, wenn Sie tiefer eintauchen möchten: How to Write a Good README von merlos
So möchte ich die README-Datei für dieses Projekt strukturieren
<!--- README.md --> # Overview # Getting Started # Usage # Architecture ## Data Flow ## Tech Stack # Running Tests # Next Steps # References
Lassen wir das Grundgerüst vorerst so, wie es ist – wir kommen später darauf zurück.
Lassen Sie uns nun die Metadaten unseres Pakets basierend auf der offiziellen Dokumentation konfigurieren
# 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" = ""
Beachten Sie, dass es Platzhalter gibt, die Sie ändern müssen, z. B. Ihren Benutzernamen, Ihren Namen usw.
Außerdem lassen wir die Homepage-URL vorerst leer. Wir werden Änderungen vornehmen, nachdem wir es auf GitHub veröffentlicht haben. Außerdem lassen wir den Abschnitt „Abhängigkeiten“ vorerst leer und fügen ihn nach und nach hinzu.
Als nächstes auf der Liste wäre unsere .env
Datei, in der wir unsere Umgebungsvariablen wie API-Geheimnisse und Schlüssel speichern. Es ist wichtig zu beachten, dass diese Datei nicht von Git verfolgt werden sollte, da sie vertrauliche Informationen enthält.
In unserem Fall speichern wir hier unsere Trello-Zugangsdaten. Befolgen Sie diese Anleitung , um ein Power-Up in Trello zu erstellen. Genauer gesagt, basierend auf der Verwendung durch py-trello
, da wir OAuth für unsere Anwendung verwenden möchten, benötigen wir Folgendes, um mit Trello zu interagieren:
Sobald Sie Ihren API-Schlüssel und Ihr Geheimnis abgerufen haben, speichern Sie sie als solche in der .env
Datei
# .env TRELLO_API_KEY=<your_api_key> TRELLO_API_SECRET=<your_api_secret>
Zu guter Letzt verwenden wir die Vorlage Python .gitignore
, die Sie hier finden. Beachten Sie, dass dies von entscheidender Bedeutung ist, um sicherzustellen, dass unsere .env
Datei niemals verfolgt wird. Wenn unsere .env
Datei irgendwann verfolgt wurde, ist der Schaden bereits angerichtet und böswillige Akteure können die vorherige Datei aufspüren, auch wenn wir sie in späteren Schritten entfernt haben Patches für vertrauliche Informationen.
Nachdem die Einrichtung nun abgeschlossen ist, übertragen wir unsere Änderungen auf GitHub. Denken Sie je nach den in pyproject.toml
angegebenen Metadaten daran, Ihre LIZENZ und Homepage-URL entsprechend zu aktualisieren. Als Referenz zum Schreiben besserer Commits: Write Better Commits, Build Better Projects von Victoria Dye
Weitere bemerkenswerte Schritte:
Bevor wir mit dem Schreiben unserer Tests beginnen, ist es wichtig zu beachten, dass wir, da wir mit einer API arbeiten, Scheintests implementieren werden, um unser Programm ohne das Risiko von API-Ausfällen testen zu können. Hier ist ein weiterer großartiger Artikel über Mock-Tests von Real Python: Mocking External APIs in Python
Basierend auf den funktionalen Anforderungen besteht unser Hauptanliegen darin, Benutzern das Hinzufügen einer neuen Karte zu ermöglichen. Verweisen auf die Methode in py-trello
: add_card . Dazu müssen wir die Methode add_card
aus der Klasse List
aufrufen, die über die Funktion get_list
aus der Klasse „ Board
abgerufen werden kann.
Sie verstehen das Wesentliche – wir werden viele Hilfsmethoden benötigen, um unser endgültiges Ziel zu erreichen. Sagen wir es in Worten:
Es ist auch wichtig zu beachten, dass wir beim Schreiben von Unit-Tests darauf achten, dass unsere Tests so umfangreich wie möglich sind. Werden Fehler gut verarbeitet? Deckt es jeden Aspekt unseres Programms ab?
Allerdings werden wir in diesem Tutorial die Dinge vereinfachen, indem wir nur nach Erfolgsfällen suchen.
Bevor wir in den Code eintauchen, ändern wir unsere Datei pyproject.toml
so, dass sie die Abhängigkeiten enthält, die zum Schreiben/Ausführen von Komponententests erforderlich sind.
# pyproject.toml [project] dependencies = [ "pytest==7.4.0", "pytest-mock==3.11.1" ]
Als nächstes aktivieren wir unsere virtuelle Umgebung und führen pip install .
um die Abhängigkeiten zu installieren.
Sobald das erledigt ist, schreiben wir endlich einige Tests. Im Allgemeinen sollten unsere Tests eine zurückgegebene simulierte Antwort, einen Patch für die Funktion, die wir testen möchten, indem wir den Rückgabewert mit der simulierten Antwort korrigieren, und schließlich einen Aufruf der Funktion umfassen. Ein Beispieltest zum Abrufen der Zugriffstoken des Benutzers würde wie folgt aussehen:
# 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
Beachten Sie in meinem Beispielcode, dass GetOAuthTokenResponse
ein Modell ist, das noch in models.py
festgelegt werden muss. Es bietet Struktur zum Schreiben sauberer Codes. Wir werden dies später in Aktion sehen.
Um unsere Tests auszuführen, führen Sie einfach python -m pytest
aus. Beachten Sie, dass unsere Tests scheitern werden, aber das ist in Ordnung – am Ende wird es klappen.
Challenge Corner 💡 Können Sie versuchen, weitere Tests selbst zu schreiben? Sehen Sie sich gernediesen Patch an, um zu sehen, wie meine Tests aussehen
Lassen Sie uns zunächst unseren trelloservice
aufbauen. Beginnen Sie mit dem Hinzufügen einer neuen Abhängigkeit, dem py-trello
-Wrapper.
# pyproject.toml dependencies = [ "pytest==7.4.0", "pytest-mock==3.11.1", "py-trello==0.19.0" ]
Führen Sie erneut pip install .
um die Abhängigkeiten zu installieren.
Beginnen wir nun mit dem Aufbau unserer Modelle – um die Antworten zu regulieren, die wir in trelloservice
erwarten. Für diesen Teil lesen Sie am besten unsere Unit-Tests und den py-trello
Quellcode, um zu verstehen, welche Art von Rückgabewert wir erwarten können.
Angenommen, wir möchten das Zugriffstoken des Benutzers abrufen und beziehen uns dabei auf die Funktion create_oauth_token
von py-trello
( Quellcode ). Wir wissen, dass wir einen Rückgabewert wie diesen erwarten können
# trellocli/models.py # module imports # dependencies imports # misc imports from typing import NamedTuple class GetOAuthTokenResponse(NamedTuple): token: str token_secret: str status_code: int
Beachten Sie andererseits widersprüchliche Namenskonventionen. Das py-trello
Modul hat beispielsweise eine Klasse namens List
. Eine Lösung hierfür wäre die Bereitstellung eines Alias beim Import.
# trellocli/models.py # dependencies imports from trello import List as Trellolist
Nutzen Sie diese Gelegenheit gerne auch, um die Modelle an die Bedürfnisse Ihres Programms anzupassen. Angenommen, Sie benötigen nur ein Attribut aus dem Rückgabewert. Sie könnten Ihr Modell so umgestalten, dass es den besagten Wert aus dem Rückgabewert extrahiert, anstatt ihn als Ganzes zu speichern.
# 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 💡 Kannst du versuchen, selbst mehr Modelle zu schreiben? Sehen Sie sich gernediesen Patch an, um zu sehen, wie meine Modelle aussehen
Modelle runter, lasst uns offiziell mit dem Codieren des trelloservice
beginnen. Auch hier sollten wir uns auf die von uns erstellten Unit-Tests beziehen. Nehmen wir an, dass die aktuelle Testliste den Dienst nicht vollständig abdeckt. Kommen Sie immer zurück und fügen Sie bei Bedarf weitere Tests hinzu.
Fügen Sie wie üblich alle Importanweisungen oben ein. Erstellen Sie dann wie erwartet die TrelloService
Klasse und die Platzhaltermethoden. Die Idee ist, dass wir eine gemeinsame Instanz des Dienstes in cli.py
initialisieren und seine Methoden entsprechend aufrufen. Darüber hinaus streben wir nach Skalierbarkeit und damit nach einer umfassenden Abdeckung.
# 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: Beachten Sie, dass unsere Tests dieses Mal bestanden werden, wenn wir unsere Tests durchführen. Tatsächlich wird uns das dabei helfen, sicherzustellen, dass wir auf dem richtigen Weg bleiben. Der Arbeitsablauf sollte darin bestehen, unsere Funktionen zu erweitern, unsere Tests auszuführen, auf Pass/Fail zu prüfen und entsprechend umzugestalten.
Beginnen wir mit der Funktion __init__
. Die Idee ist, hier die Funktion get_user_oauth_token
aufzurufen und den TrelloClient
zu initialisieren. Um die Notwendigkeit zu betonen, solche vertraulichen Informationen nur in der .env
Datei zu speichern, verwenden wir die Abhängigkeit python-dotenv
, um vertrauliche Informationen abzurufen. Nachdem wir unsere Datei pyproject.toml
entsprechend geändert haben, beginnen wir mit der Implementierung der Autorisierungsschritte.
# 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 )
In dieser Implementierung haben wir eine Hilfsmethode erstellt, um alle vorhersehbaren Fehler zu behandeln, z. B. wenn der Benutzer während der Autorisierung auf Deny
klickt. Darüber hinaus ist es so eingerichtet, dass es rekursiv nach der Autorisierung des Benutzers fragt, bis eine gültige Antwort zurückgegeben wird, denn Tatsache ist, dass wir nicht fortfahren können, es sei denn, der Benutzer autorisiert unsere App, auf seine Kontodaten zuzugreifen.
Challenge Corner 💡 Beachten Sie TRELLO_AUTHORIZATION_ERROR
? Können Sie diesen Fehler als Paketkonstante deklarieren? Weitere Informationen finden Sie unter „Setup“.
Nachdem der Autorisierungsteil nun abgeschlossen ist, gehen wir zu den Hilfsfunktionen über und beginnen mit dem Abrufen der Trello-Boards des Benutzers.
# 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 )
Zum Abrufen der Listen (Spalten) müssen wir die Board
Klasse von py-trello
auschecken, oder mit anderen Worten, wir müssen einen neuen Parameter des Board
Werttyps akzeptieren.
# 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 💡 Könnten Sie die Funktionen get_all_labels
und get_label
selbst implementieren? Überarbeiten Sie die Board
Klasse von py-trello
. Sehen Sie sich gernediesen Patch an, um zu sehen, wie meine Implementierung aussieht
Zu guter Letzt haben wir endlich das erreicht, was wir die ganze Zeit angestrebt haben – das Hinzufügen einer neuen Karte. Beachten Sie, dass wir hier nicht alle zuvor deklarierten Funktionen verwenden – das Ziel der Hilfsfunktionen besteht darin, die Skalierbarkeit zu erhöhen.
# 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 )
🎉 Nachdem das erledigt ist, denken Sie daran, Ihre README-Datei entsprechend zu aktualisieren und Ihren Code auf GitHub zu übertragen.
Glückwunsch! Du hast gewonnen. Nochmals spielen (j/n)?
Vielen Dank für Ihr Verständnis :) Durch dieses Tutorial haben Sie erfolgreich gelernt, Mocking beim Schreiben von Unit-Tests zu implementieren, Modelle für Kohärenz zu strukturieren, Quellcode zu lesen, um wichtige Funktionalitäten zu finden, und Geschäftslogik mithilfe eines Wrappers eines Drittanbieters zu implementieren.
Halten Sie Ausschau nach Teil 2, in dem wir uns eingehend mit der Implementierung des CLI-Programms selbst befassen.
Bleiben wir in der Zwischenzeit in Kontakt 👀
GitHub-Quellcode: https://github.com/elainechan01/trellocli