Eine neue Python API

Ich freue mich, fluent-discourse vorstellen zu können, ein neues Python-Paket zum Abrufen der Discourse-API.

Es gibt bereits einige Pakete, die die Discourse-API über Python nutzen. Warum also ein weiteres entwickeln?

Die anderen verfügbaren Discourse-Pakete gehen das Problem meist ähnlich an: Für jeden Endpunkt der API wird eine eigene Python-Funktion erstellt.

Dieser Ansatz hat einige Nachteile:

  1. Es ist sehr schwierig, eine vollständige Funktionsäquivalenz zur API zu erreichen. Die Discourse-API ist teilweise unzureichend dokumentiert, und oft müssen Endpunkte durch Reverse Engineering erschlossen werden. Darüber hinaus gibt es zahlreiche Plugins, die API-Endpunkte bereitstellen, die nicht einmal zum Kern gehören. Das stellt den Nutzer der Bibliothek vor die schwierige Wahl, Pull Requests einzureichen, um benötigte Endpunkte zur Bibliothek hinzuzufügen, oder eine eigene Lösung für zusätzliche Endpunkte zu entwickeln.
  2. Man muss eine weitere API erlernen. Zusätzlich zum Erlernen der Methoden und Endpunkte der Discourse-API muss man herausfinden, welcher Funktionsaufruf in Python entspricht.
  3. Es gibt viel mehr Code zu testen, sodass eine 100-prozentige Testabdeckung schwerer zu erreichen ist. Das führt zu weniger Vertrauen in die Qualität der produzierten Software.

Im Gegensatz zu diesem Ansatz habe ich eine „fluent“-Schnittstelle verwendet, bei der man durch Methodenkettung Anfragen konstruiert. Nehmen wir ein Beispiel:
Um die neuesten Themen in einer Kategorie „foo“ mit der ID 5 zu erhalten, verwendet man diesen Endpunkt:
GET /c/foo/5.json.
Um diese Anfrage mit dieser Bibliothek durchzuführen, ruft man einfach auf:
client.c.foo[5].json.get()

Man erkennt, dass eine semantische Äquivalenz zwischen dem API-Endpunkt und dem entsprechenden Aufruf in Python besteht.

Dieser Ansatz

  1. bietet ab Werk eine vollständige Funktionsäquivalenz zur Discourse-API, einschließlich nicht dokumentierter Endpunkte, Endpunkte aus Plugins und Endpunkte, die noch nicht definiert sind (zukünftssicher).
  2. erfordert, dass man nur die Discourse-API erlernt. Es ist einfach, jeden API-Aufruf so zu übersetzen, sodass man nicht nach der passenden Funktion suchen muss.
  3. besteht aus nur etwa 150 Zeilen Code. Das macht es trivial, eine 100-prozentige Testabdeckung zu erreichen.

Es gibt eine 100-prozentige Testabdeckung mit einer Handvoll Integrationstests gegen einen live laufenden Discourse-Server.

Wenn das für dich klingt, hoffe ich, dass du dieses Paket ausprobierst!

21 „Gefällt mir“

Das ist ein interessanter Ansatz.

Um etwas Ähnliches in PHP zu tun, müssten wir uns auf magische Methoden verlassen und würden dabei den Vorteil der IDE-Autovervollständigung usw. verlieren. Aber es könnte ein lohnender Preis sein.

Was ist der Vorteil dieses Ansatzes gegenüber dem einfachen Übergeben der URL als Argument: client.get(url)?

Das ist ein guter Punkt, die IDE-Autovervollständigung wird hier nicht viel helfen. Wenn dir das wichtig ist, könnte es sich lohnen, eine andere Bibliothek zu verwenden.

Da jede Methodenverkettung einen neuen Client zurückgibt, ist ein Vorteil, den ich mir vorstellen kann, dass man eine bestimmte Methodenverkettung in einer Variable speichern und für nachfolgende Aufrufe wiederverwenden kann. Nehmen wir zum Beispiel an, du hättest eine Liste mit Daten für neue Beiträge, die du erstellen möchtest.

post_data = [
  {
    "raw": "Hallo Welt!",
    "topic_id": 123,
    ...
  },
  {
    "raw": "Tester",
    "topic_id": 501,
    ...
  },
  ...
]

Du könntest die Methodenverkettung für „Neuer Beitrag" speichern und sie wiederverwenden, um jeden der Beiträge in der Liste zu erstellen.

new_post_endpoint = client.posts.json

for post in post_data:
  new_post_endpoint.post(data=post) 

Du kannst dir wahrscheinlich andere Szenarien vorstellen, in denen diese Möglichkeit, einen Client wiederverwenden zu können, nützlich ist. Darüber hinaus gibt es keinen großen Vorteil gegenüber dem einfachen Übergeben der URL, wie du vorgeschlagen hast. Ich empfehle dir, die Bibliothek Universal Client zu lesen, die einige Informationen zur Begründung dieses Ansatzes enthält.

Außerdem findest du für eine PHP-spezifische Implementierung dieses Ansatzes unter SendGrids PHP-API weitere Informationen. Ich wurde inspiriert, dies zu entwickeln, als ich über SendGrids Python-API las.

3 „Gefällt mir“