In einem vorherigen Artikel haben wir einige Prinzipien für den Aufbau von REST-APIs und ein erstes Beispiel für deren Implementierung unter Python mit Flask gesehen.
In diesem Beispiel wurden die Daten in Form einer Liste von Wörterbüchern in den Code eingebunden.
Wir haben auch einen Artikel darüber, wie man eine API mit Python, Flask, Swagger und Connection programmiert und dokumentiert.
Im folgenden Beispiel sehen wir uns an, wie man eine API mit einer externen relationalen Datenbank verbindet und das Filtern von Items nach verschiedenen Bedingungen zulässt:
1. Relationale Datenbanken
In relationalen Datenbanken können Daten gespeichert und abgerufen werden, wobei die Daten in Form von Tabellen gespeichert werden.
Tabellen sind ähnlich wie Arbeitsblätter: Sie haben Zeilen und Spalten, wobei die Spalten angeben, worauf sich die Daten beziehen, z. B. auf einen Titel oder ein Datum. Die Zeilen repräsentieren einzelne Daten, die Nutzern, Transaktionen oder anderen Arten von Einheiten entsprechen können.
2. SQLite
Die in der Suite verwendete Datenbank-Engine ist SQLite, eine sehr schlanke Datenbank-Engine, die standardmäßig unter Python verfügbar ist.
Die Standard-Dateierweiterung von SQLite ist .db.
Die verwendete Datenbank ist die Chinook-Datenbank (verfügbar über den Nächster Link), die aus 11 Tabellen besteht. Im Folgenden werden wir uns besonders für die Tabelle employees interessieren: Diese enthält Daten über die Angestellten der Firma Chinook, wie z. B. die ID, den Namen, den Vornamen etc.
3. Eine API mit der Chinook-Datenbank verbinden
Wir beginnen damit, die Datenbank chinook.db in unser Api-Verzeichnis zu kopieren.
Unsere API wird diese Datenbank abfragen, um die gewünschten Ergebnisse an die Benutzer zurückzugeben.
Der entsprechende Code lautet wie folgt:
Du speicherst sie im Verzeichnis api unter dem Namen api4.py.
Um es auszuführen, starte ein Kommandozeilenfenster aus dem Verzeichnis api und gib folgende Befehle ein:
$ export FLASK_APP = api4.py
$ export FLASK_ENV = development
$ flask run
(um die Ausführung zu stoppen, drücke Strg-C).
Du erhältst unter anderem folgende Meldungen:
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Nachdem das Programm ausgeführt wurde, kannst du Anfragen wie diese an den verwendeten Browser stellen:
Die Tabelle Arbeitnehmer in der Datenbank Chinook hat 8 Datensätze, einen für jeden Arbeitnehmer der Firma Chinook.
Die Daten umfassen unter anderem die ID, den Vornamen, den Nachnamen, den Wohnort, das Geburtsdatum und das Einstellungsdatum.
Unsere API ermöglicht es, nach drei Feldern zu filtern: EmployeeId (Benutzerkennung), LastName (Nachname) und City (Wohnort).
Die neue API beantwortet Nutzeranfragen, indem sie die Informationen mithilfe von SQL-Abfragen aus der Datenbank extrahiert.
Sie ermöglicht es auch, nach mehr als einem Feld zu filtern.
4. Die neue API verstehen
4. Die Tabelle Arbeitnehmer in der Chinook-Datenbank besteht aus acht Spalten: EmployeeId, LastName, FirstName, Title, ReportsTo, BirthDate, HireDate und Address.
Jede Zeile steht für einen Mitarbeiter der Firma Chinook.
Anstatt die Daten im Code anzugeben, ruft unsere Funktion api_all sie aus der Chinook-Datenbank ab:neue API
Wir beginnen mit der Datenbankverbindung über die Bibliothek sqlite3.
Ein Objekt, das die Datenbankverbindung darstellt, wird mit der Variablen conn. verknüpft.
Die Anweisung conn. row_factory = dict_factory sagt dem Objekt, das der Verbindung entspricht, die Funktion dict_factory zu verwenden, die Ergebnisse in Form von Wörterbüchern statt Listen zurückgibt – was sich besser in JSON umwandeln lässt.
Als Nächstes erstellen wir ein Cursor-Objekt (cur = conn.cursor( )), das die Datenbank durchsucht, um die Daten zu extrahieren.
Endlich führen wir eine SQL-Abfrage mit der Methode cur.execute aus, um alle verfügbaren Daten ( * ) aus der Tabelle employeesunserer Datenbank zu extrahieren..
Am Ende unserer Funktion werden die abgerufenen Daten in das JSON-Format umgewandelt: jsonify(all_employees)..
Die andere Funktion, die Daten zurückgibt, api_filter, verwendet denselben Ansatz, um bestimmte Daten aus der Datenbank zu extrahieren..
Der Zweck der Funktion page_not_found ist es, eine Fehlerseite zu erstellen, die dem Benutzer angezeigt wird, wenn er eine Route angibt, die nicht von der API unterstützt wird:.
In HTML-Ergebnissen bedeutet der Code 200 „OK“ (Daten übertragen), während der Code 404 „not found“ (keine Ressourcen unter der angegebenen Adresse verfügbar) bedeutet.
Die Funktion page_not_found gibt 404 zurück, wenn etwas schief läuft..
api_filter Die Funktion api_filter erlaubt es, nach drei Feldern zu filtern: EmployeeId, LastName und City. .
Er identifiziert zunächst alle Anfrageparameter, die in der URL angegeben sind, mithilfe der folgenden Anweisung:.
query_parameters = request.args.
Sie ruft dann die Werte der Parameter ab und verknüpft sie mit Variablen:.
employeeid = query_parameters.get(‚EmployeeId‘).
lastname = query_parameters.get(‚LastName‘).
city = query_parameters.get(‚City‘).
Der folgende Codeabschnitt erstellt eine SQL-Abfrage, die verwendet wird, um die gesuchten Informationen aus der Datenbank zu extrahieren..
Die einfachsten SQL-Abfragen haben die folgende Form:.
SELECT <columns> FROM <table> WHERE <column=match> AND <column=match>;.
Um die gesuchten Daten zu erhalten, müssen wir sowohl eine SQL-Abfrage der oben genannten Art als auch eine Liste mit den angegebenen Filtern (Werten) erstellen..
Wir beginnen mit der Definition der Abfrage und der Filterliste:.
Wenn der Nutzer keinen dieser Anfrageparameter angegeben hat, wird die Fehlerseite 404 zurückgegeben:
Um unsere SQL-Abfrage zu vervollständigen, entfernen wir das letzte AND und vervollständigen die Abfrage mit dem von SQL geforderten Semikolon:
5. Die neue API verwenden
Unsere neue API ermöglicht anspruchsvollere Abfragen durch die Benutzer.
Außerdem stehen neue Daten, die der Datenbank hinzugefügt werden, sofort für Projekte zur Verfügung, die mithilfe der API erstellt wurden.
Daher ist es in vielen Fällen sinnvoll, zunächst eine API-Schnittstelle für Projektdaten zu erstellen, bevor man eine Visualisierung, Anwendung oder Website auf der Grundlage der Daten baut.
Im nächsten Artikel werden wir die zuvor vorgestellten Techniken weiterentwickeln, um zu sehen, wie man eine professionelle REST-API unter Python mithilfe von Flask, OpenAPI (ehemals Swagger) und Connexion programmieren kann.
6. Bibliografische Referenzen
- Creating Web APIs with Python and Flask, Patrick Smyth : https://programminghistorian.org/en/lessons/creating-apis-with-python-and-flask.
- Flask RESTful documentation : https://flask-restful.readthedocs.io/en/latest/index.html.
- Flask Web Development : Developing Web Applications with Python (2ème édition). M. Grinberg. O’Reilly 2018.
- Architectural Styles and the Design of Network-Based Software Architectures. T. Fielding. Thèse, Université de Californie, 2000.