Einführung
Mastodon hat eine sehr saubere und klare REST API, für eine Menge an Operationen. Im Prinzip alles, was man in einem Client durchführen kann (Lesen, Nachrichten schreiben, Favorisieren, Bilder hochladen, usw. usf.) lässt sich ebenfalls über die API realisieren. Allerdings erfordert das natürlich eine Authentifizierung. Ohne sich der Instanz “Bekanntzumachen”, kann man nicht auf die API zugreifen.
Mastodon verwendet dafür OAuth2, was sich deutlich von einer User/Password Authentifizierung, wie es BasicAuth erlaubt, unterscheidet. Ohne tiefer ins Detail zu gehen, ist es wichtig zu wissen, dass OAuth2 verschiedene Anmelde-Workflows bietet, die stufenweise funktionieren. Man muss sich das einfach so vorstellen: Da man als Mensch ja nicht direkt mit der Maschine “Mastodon-Instanz” (dem Host) reden kann, benutzt man immer einen Stellvertreter, eine Application (der Client). Ein Client, kann eine Smartphone-App wie Tusky oder Fedilab sein, es kann das Mastodon WebUI sein oder eben auch ein Python-Script.
Eine Client-App, die mit einem Host sprechen will, muss damit sich erstmal registrieren. Ansonsten akzeptiert der Host den Client nicht. Das funktioniert bei Mastodon auf zwei Arten. Entweder selbst über die API (denn über die API darf man alles machen) oder man registriert über das Mastodon WebUI eine Client Application.
Dass sich eine App einfach selber registrieren darf, ist übrigens nicht selbstverständlich. Im Fediverse ist das bei dezentralen Instanzen und den vielen Client-Implementationen aber deutlich einfacher zu handhaben. Man stelle sich vor jede App (Tusky, Fedilab, Mastodon, …) müsste auf jeder Instanz in Fediverse erstmal manuell von jedem Anwender oder Entwickler registriert werden, damit man Nachrichten schreiben kann! Das wäre eine riesige Hürde, die man in einem offenen Netzwerk so nicht haben will.
Wichtig ist zu wissen, dass mit der Registrierung einer App, die Mastodon Instanz sich diese Information merkt und dem Registrierenden ein paar Daten mitgibt, die man immer wieder verwenden sollte. Damit kommen wir zu wichtigen Merkmalen von OAuth2. Die App bekommt eine ID (Client-ID) und ein Geheimnis (Client-Secret) zugewiesen. Diese beiden Informationen reichen aber noch nicht, um tatsächlich auf die API zuzugreifen. Es gibt noch ein Zugangstoken. Ein Token ist eine zeitlich begrenzter Zugangsschlüssel. So wie eine Hotelkarte, mit der man nur zu den gebuchten Tagen in das Hotelzimmer darf, ist ein Zugangstoken ebenfalls auf eine bestimmte Zeit beschränkt. Ist der Token abgelaufen, muss man sich einen neuen besorgen.
Das ist ein recht aufwendiger Arbeitsablauf und erfordert ein paar Schritte. Zunächst registriert man sich als Application. Dafür denkt man sich einen Namen aus und gibt eine URL der eigenen Heimat an (oder man verwendet einen speziellen Platzhalter). Dann bekommt man eine ID, ein Secret und einen Token. Mit den drei Informationen darf man dann die ersten Abfragen durchführen. Da das immer wiederkehrende Arbeiten sind, verlässt man sich dabei besser auf Bibliotheken, die das für einen machen. Für Python gibt es Mastodon.py. Diese Bibliothek ist nicht nur ein Wrapper für die gesamte REST-API, sie kümmert sich auch um den ganzen Workflow der Registrierung und Authentifizierung. Es ist sozusagen der persönliche Hotelpage, der einem bei allem hilft, inkl. dem Öffnen der Türen.
Zwar erlaubt auch Mastodon.py das direkte Registrieren per API, aber es ist sinnvoller, das über das Web-UI zu machen. In dem Fall merkt sich das UI die Registrierung und speichert die Daten für einen. Nicht jede Instanz erlaubt das, aber die meisten.
Application Client registrieren
Grunddaten
Zunächst geht man über das WebUi in Einstellungen und dort auf Entwicklung:
Mit dem Button “Neue Anwendung” lässt sich nun eine Client-App registrieren:
Als Namen denkt man sich was Nettes aus, die URL kann das eigene Instanz-Profil sein und die Weiterleitungs-URL sollte mit dem Platzhalter “urn:ietf:wg:oauth:2.0:oob” beschrieben sein. Wir schreiben Scripte und werden keine Login-Eingaben an einen Benutzer weiterleiten.
Berechtigungen
Im untereren Bereich kann man bei “Befugnissen” festlegen, was die Client Application überhaupt alles darf. In OAuth2 nennt man das den “Scope”. Für die ersten Spielereien sollte man nur den Haken bei “read” aktiviert haben, damit man sich nicht aus Versehen was kaputt macht. Also “write” und “follow” erstmal deaktivieren. Man sieht aber, dass man sich sehr viele Einzelberechtigungen zusammenstellen kann:
OAuth2 Daten der Registrierung
Nachdem man alles mit dem großen blauen Speicherbutton am Ende gesichert hat, ist erstmal Verwirrung angesagt. Nirgendwo sieht man nun die Client-ID und das Secret und auch kein Token. Dafür nun in der Liste der Anwendungen wieder auf den Namen klicken, und voilà: die OAuth2 Daten:
Mastodon.py installieren
Ich gehe davon aus, dass Grundkenntnisse in Python existieren und vor allem eine Umgebung existiert, in Python zu entwickeln. Viele werden pip oder pip3 verwenden, also ist Mastodon.py schnell installiert.
pip3 install Mastodon.py
Das erste Script
Nun die IDE der Wahl öffnen und ein superkleines Beispiel (noch nicht vollständig):
import json
from mastodon import Mastodon
mastodon = Mastodon (
client_id='ep***************************************Xo',
client_secret='AY**********************************0s',
api_base_url='https://social.tchncs.de'
)
Wir brauchen “json” für bequemere Ausgaben und dann wird das installierte Mastodon.py importiert. Im nächsten Schritt wird das Mastodon-Object erzeugt und wir übergeben die client_id und das client_secret (aus dem Web-UI sind das Client-Schlüssel und Client-Secret). Die api_base muss die Instanz sein, wo wir die App registriert haben.
Ups, warum nicht das Token? Wir lassen unseren Hotelpagen “Mastodon.py” den Job machen. Fehlt der Token, fragt Mastodon.py direkt nach einem neuen Token an. Etwas verschwenderisch, aber hier sinnvoll. Denn der Token läuft sowieso irgendwann ab und wir wollen ja nicht jedes Mal das Script ändern…
Nun fügen wir aber noch was dem Script an:
nodeinfo = mastodon.instance_nodeinfo()
print (json.dumps(nodeinfo, indent=4, default=str))
activity = mastodon.instance_activity()
print (json.dumps(activity, indent=4, default=str))
Node-Info gibt eine kleine Information der Instanz zurück, Activity eine Statistik darüber, was eigentlich so los ist. Es muss beachtet werden, dass manche Instanzen diese Abfragen nicht erlauben. Dann hagelt es Fehlermeldungen.
Was abschließend noch wichtig ist. Wir haben hiermit auf öffentliche Daten der Instanz zugegriffen. Die Registrierung der Client-App (also unseres Scriptes) wurde zwar über das Web-UI (unter unserem Account) angelegt, aber wir verwendeten hier noch keinerlei Benutzerdaten. Das war für diese API Aufrufe auch nicht notwendig, weil wir keine benutzerbezogenen Aktionen ausführten. Es ist sogar möglich über den Mastodon.py Wrapper sich nur als App zu registrieren und die Informationen abzurufen. Das ist eine sehr offene Art, mit einer API umzugehen. Allerdings gibt es immer Einschränkungen. Jede Instanz kann selbst entscheiden, was abrufbar ist und auch die Häufigkeit der Abfragen ist limitiert. Fragt man zu oft einer eine Zeitperiode bestimmte Endpunkte ab, bekommt man Fehlermeldungen. Mastodon.py hat in diesem Fall verschiedene Strategien, wie es damit umgeht. Dazu aber in einem späteren Beitrag.
Comments
May 2, 2022 16:21
@momentum
😬😉
@beandev@fediverse.blog