{"id":173487,"date":"2026-01-28T12:42:43","date_gmt":"2026-01-28T11:42:43","guid":{"rendered":"https:\/\/liora.io\/de\/?p=173487"},"modified":"2026-02-06T04:38:32","modified_gmt":"2026-02-06T03:38:32","slug":"api-programmierung-und-dokumentation-mit-python-flask-swagger-und-connexion","status":"publish","type":"post","link":"https:\/\/liora.io\/de\/api-programmierung-und-dokumentation-mit-python-flask-swagger-und-connexion","title":{"rendered":"API-Programmierung und -Dokumentation mit Python, Flask, Swagger und Connexion"},"content":{"rendered":"<h2 class=\"wp-block-heading\" id=\"h-in-den-beiden-vorherigen-artikeln-haben-wir-ein-erstes-beispiel-fur-die-programmierung-einer-web-api-unter-flask-gesehen-und-wie-man-eine-web-api-mit-einer-sqlite-datenbank-verbindet\">In den beiden vorherigen Artikeln haben wir ein erstes Beispiel f\u00fcr die <a href=\"https:\/\/liora.io\/de\/api-erstellen-mit-verschiedenen-apps-teil-i\">Programmierung einer Web-API unter Flask<\/a> gesehen und wie man eine Web-API mit einer SqLite-Datenbank verbindet.<\/h2>\n<p>Im Folgenden werden wir sehen, wie man REST-APIs mit Input- und Output-Validierung und automatisch erstellter Dokumentation von Swagger\/OpenAPI baut. Wir werden auch sehen, wie die API mit JavaScript verwendet werden kann, um das <strong>DOM (Document Object Model)<\/strong>, d. h. die Struktur der angezeigten Webseite, zu aktualisieren.<\/p>\n<p>Die <a href=\"https:\/\/liora.io\/de\/api\">REST-API<\/a>, die wir bauen werden, wird es erm\u00f6glichen, ein Personenverzeichnis zu manipulieren, wobei die Personen durch ihre Nachnamen identifiziert werden. Aktualisierungen werden mit einem &#8222;Timestamp&#8220; (Datum\/Uhrzeit) markiert.<\/p>\n<p>Man k\u00f6nnte das Verzeichnis in Form einer Datenbank, einer Datei oder \u00fcber ein Netzwerkprotokoll manipulieren, aber um die Dinge zun\u00e4chst zu vereinfachen, werden wir Daten im Speicher verwenden.<\/p>\n<blockquote><p>Eines der Ziele von APIs ist es, die Daten von den Anwendungen, die sie nutzen, zu entkoppeln, indem die Details der Datenimplementierung transparent gemacht werden.<\/p><\/blockquote>\n<style>\nbody.elementor-page .elementor-widget-menu-anchor{margin-bottom:0}<\/style>\n<style>\n.elementor-heading-title{padding:0;margin:0;line-height:1}.elementor-widget-heading .elementor-heading-title[class*=elementor-size-]>a{color:inherit;font-size:inherit;line-height:inherit}.elementor-widget-heading .elementor-heading-title.elementor-size-small{font-size:15px}.elementor-widget-heading .elementor-heading-title.elementor-size-medium{font-size:19px}.elementor-widget-heading .elementor-heading-title.elementor-size-large{font-size:29px}.elementor-widget-heading .elementor-heading-title.elementor-size-xl{font-size:39px}.elementor-widget-heading .elementor-heading-title.elementor-size-xxl{font-size:59px}<\/style>\n<h2 class=\"wp-block-heading\" id=\"h-1-die-rest-methode\">1. Die REST Methode<\/h2>\n<p>Die REST-Methode wurde im ersten Artikel erw\u00e4hnt. Nun wollen wir sie genauer betrachten.<\/p>\n<p>REST kann als eine Reihe von Konventionen betrachtet werden, die das <a href=\"https:\/\/liora.io\/de\/python-http-request-requests-alles-wichtige\">HTTP<\/a>-Protokoll nutzen, um CRUD-Tools (Create, Read, Update, Delete) bereitzustellen, die mit Entit\u00e4ten oder Sammlungen von Entit\u00e4ten im Internet arbeiten.<\/p>\n<p>CRUD kann wie folgt auf HTTP abgebildet werden:<\/p>\n<p>Du kannst jede dieser Aktionen an einer Entit\u00e4t oder einer Ressource durchf\u00fchren.<\/p>\n<p>Eine<strong> Ressource<\/strong> kann man sich als eine Entit\u00e4t vorstellen, der man einen Namen zuordnen kann: eine Person, eine Adresse, eine Transaktion.<\/p>\n<p>Die Idee einer Ressource kann mit der Idee einer URL in Verbindung gebracht werden, wie im ersten Artikel beschrieben.<\/p>\n<p>Eine URL muss eine einzigartige Ressource im Web identifizieren, etwas, das immer mit derselben URL \u00fcbereinstimmt.<\/p>\n<p>Mit den Konzepten der<strong> Ressource und der URL<\/strong> sind wir in der Lage, Anwendungen zu entwerfen, die auf eindeutig identifizierte Dinge im Web einwirken.<\/p>\n<p>Dies ist ein erster Schritt auf dem Weg zur Entwicklung von eigentlichen APIs, die es erm\u00f6glichen, die gew\u00fcnschten Aktionen \u00fcber das Netz auszuf\u00fchren.<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-2-was-rest-nicht-ist\">2.Was REST nicht ist<\/h2>\n<p>Da die <strong>REST-Methode<\/strong> sehr n\u00fctzlich ist und dabei hilft, die Art und Weise zu entwickeln, wie man mit einer <strong>API<\/strong> interagiert, wird sie manchmal f\u00e4lschlicherweise f\u00fcr Probleme verwendet, f\u00fcr die sie nicht geeignet ist.<\/p>\n<p>In vielen F\u00e4llen m\u00f6chte man eine Aktion direkt ausf\u00fchren. Nehmen wir als Beispiel das Ersetzen einer Zeichenkette.<\/p>\n<p>Hier ist ein Beispiel f\u00fcr eine URL, die dies auf den ersten Blick erm\u00f6glicht:<\/p>\n<p><em>\/api\/substituteString\/&lt;string&gt;\/&lt;search_string&gt;\/&lt;sub_string&gt;<\/em><\/p>\n<p>Hier bezeichnet, die<strong> Zeichenkette,<\/strong> die ersetzt werden soll, ist die zu ersetzende Teilzeichenkette und ist die neue Teilzeichenkette.<\/p>\n<p>Man kann sicherlich einen Code auf dem Server entwerfen, mit dem die gew\u00fcnschte Operation durchgef\u00fchrt werden kann, aber das wirft in Bezug auf REST einige Probleme auf.<\/p>\n<ul>\n<li>Erstes Problem: Die <strong>URL<\/strong> verweist nicht auf eine einzelne Ressource; was sie zur\u00fcckgibt, h\u00e4ngt also vollst\u00e4ndig vom angegebenen Pfad ab.<\/li>\n<li>Zweites Problem: Es gibt kein <strong>CRUD-Konzept,<\/strong> das zu dieser URL passt.<\/li>\n<li>Drittes Problem: Die Bedeutung der Pfadvariablen h\u00e4ngt von ihrer Position in der URL ab.<\/li>\n<\/ul>\n<p>Dies k\u00f6nnte behoben werden, indem die URL so ge\u00e4ndert wird, dass eine Abfrage :<\/p>\n<p>\/api\/substituteString? string=&lt;string&gt;&amp;search_string=&lt;search_string&gt;&amp;sub_string=&lt;sub_string&gt;.<\/p>\n<p>Aber der URL-Teil \/api\/substituteString bezeichnet keine Entit\u00e4t (kein Name) oder eine Sammlung von Entit\u00e4ten.<br \/>\nSammlung von Entit\u00e4ten: Er bezeichnet eine Aktion (es ist ein Verb).<\/p>\n<p>Dies entspricht nicht den <strong>REST-Konventionen<\/strong> und ist daher keine API. Was die vorherige URL darstellt, ist in Wirklichkeit ein<strong> RPC (Remote Procedure Call).<\/strong><\/p>\n<p>Es ist sinnvoller, das, was du tun willst, als RPC zu konzeptualisieren. Dies gilt umso mehr, als die REST- und RPC-Konventionen innerhalb einer API problemlos koexistieren k\u00f6nnen.<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-3-erste-schritte\">3. Erste Schritte<\/h2>\n<p>Im folgenden Beispiel soll eine <strong>REST-API<\/strong> entwickelt werden, mit der du auf ein Personenverzeichnis zugreifen und <strong>CRUD-Operationen<\/strong> darauf ausf\u00fchren kannst.<\/p>\n<p>Hier ist das Design der API :<\/p>\n<p>Wir beginnen damit, einen sehr einfachen Webserver mithilfe des <strong>Flask-Entwicklungsframeworks<\/strong> zu erstellen.<\/p>\n<p>Wir erstellen ein Verzeichnis api, ein Unterverzeichnis version_1 und dann ein Unterverzeichnis templates, in dem wir die folgenden Programme speichern:<\/p>\n<p>server.py<\/p>\n<p><b>templates\/home.html<\/b><\/p>\n<p>Das HTML-Programm hei\u00dft home.html und nicht wie \u00fcblich index.html, da index.html Probleme bereitet, wenn man das Modul Login importiert, was wir im Folgenden tun werden.<\/p>\n<p>Wir starten ein<strong> Terminal-Fenster<\/strong>, wechseln in das Verzeichnis projects\/api\/version_1 und starten die Anwendung, indem wir nacheinander Folgendes eingeben:<\/p>\n<ul>\n<li>$ export FLASK_APP = server.py<\/li>\n<li>$ export FLASK_ENV = development<\/li>\n<li>$ flask run<\/li>\n<\/ul>\n<p>Das folgende Ergebnis erh\u00e4lt man, wenn man http:\/\/127.0.0.1:5000 in die Browserleiste eingibt:<\/p>\n<style>\n.elementor-widget-image{text-align:center}.elementor-widget-image a{display:inline-block}.elementor-widget-image a img[src$=\".svg\"]{width:48px}.elementor-widget-image img{vertical-align:middle;display:inline-block}<\/style>\n<figure>\n\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-1-3.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-1-3.png 512w, https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-1-3-300x200.png 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" width=\"512\" height=\"341\"><figcaption><\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\" id=\"h-4-connexion\">4. Connexion<\/h2>\n<p>Nachdem wir nun einen funktionierenden Webservice haben, f\u00fcgen wir einen <strong>REST API<\/strong> Endpunkt hinzu. Zu diesem Zweck installieren wir das Modul Connection.<\/p>\n<p>Dazu gibst du in einem Terminalfenster ein (dies setzt voraus, dass du unter Anaconda arbeitest):<\/p>\n<p><strong>$ conda install -c conda-forge Connection.<\/strong><\/p>\n<p>Nun k\u00f6nnen wir das Modul in Python importieren.<\/p>\n<p>Wir erstellen dann ein Unterverzeichnis version_2 im Verzeichnis api und speichern dort die folgenden Programme:<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-server-py\">server.py<\/h2>\n<h2 class=\"wp-block-heading\" id=\"h-swagger-yml\">swagger.yml<\/h2>\n<p>Um <strong>Connexion<\/strong> zu verwenden, importieren wir es zun\u00e4chst und erstellen dann die Anwendung mithilfe von Connexion statt mit Flask. Die <strong>Flask-Anwendung<\/strong> wird trotzdem unterschwellig erstellt, jedoch mit zus\u00e4tzlichen Funktionen.<\/p>\n<p>Die Erstellung der Instanz der Anwendung enth\u00e4lt einen Parameter specification_dir. Er teilt Connexion mit, wo die Konfigurationsdatei zu finden ist, hier das aktuelle Verzeichnis.<\/p>\n<p>Die Zeile app.add_api (&#8217;swagger.yml&#8216;) weist die Instanz an, die Datei swagger.yml im specification_dir zu lesen und das System f\u00fcr Connexion zu konfigurieren.<\/p>\n<p>Die Datei swagger.yml ist eine YAML- (oder JSON-) Datei, die die notwendigen Informationen f\u00fcr die Konfiguration des Servers enth\u00e4lt, um die Validierung der Inputs und Outputs zu gew\u00e4hrleisten, die Anfrage-URLs bereitzustellen und die Swagger-Benutzeroberfl\u00e4che (UI) zu konfigurieren.<\/p>\n<p>Der vorherige Code definiert die <strong>GET \/ api\/people-Anfrage.<\/strong> Der Code ist hierarchisch organisiert, wobei die Einr\u00fcckung den Grad der Zugeh\u00f6rigkeit oder Reichweite definiert.<\/p>\n<p>Zum Beispiel definiert paths die Wurzel aller API-URLs. Der nachtr\u00e4glich einger\u00fcckte Wert \/people definiert die Wurzel aller \/api\/people-URLs. Das nachtr\u00e4glich einger\u00fcckte get: definiert eine GET-Anfrage an die URL \/api\/people, und so weiter f\u00fcr die gesamte Konfigurationsdatei.<\/p>\n<p>In der Datei swagger.yml wird Connection mit dem Wert operationId konfiguriert, um das Modul people und die Funktion read dieses Moduls aufzurufen, wenn die API eine HTTP-Anfrage vom Typ GET \/api\/people erh\u00e4lt. Das bedeutet, dass ein Modul people.py existieren und eine read( )-Funktion enthalten muss.<\/p>\n<p>Hier ist das Modul people.py :<\/p>\n<p><strong>people.py<\/strong><\/p>\n<p>Im Modul people.py erscheint zun\u00e4chst die Funktion get_timestamp( ), die eine Darstellung des aktuellen Datums\/der aktuellen Uhrzeit in Form einer Zeichenkette erzeugt. Sie wird verwendet, um die Daten zu \u00e4ndern, wenn eine \u00c4nderungsanforderung an die <strong>API<\/strong> gesendet wird.<\/p>\n<p>Als N\u00e4chstes definieren wir ein PEOPLE-W\u00f6rterbuch, das eine einfache Namensdatenbank ist, die als Schl\u00fcssel den Nachnamen hat.<\/p>\n<p>PEOPLE ist eine Modulvariable und ihr Status bleibt daher zwischen den API-Aufrufen bestehen.<\/p>\n<p>In einer echten Anwendung w\u00fcrden sich die PEOPLE-Daten in einer Datenbank, einer Datei oder einer Webressource befinden, d. h. sie w\u00fcrden unabh\u00e4ngig von der Ausf\u00fchrung der Anwendung bestehen bleiben.<\/p>\n<p>Als n\u00e4chstes kommt die Funktion read( ), die aufgerufen wird, wenn der Server eine HTTP-GET-Anfrage nach \/api\/people erh\u00e4lt.<\/p>\n<p>Der R\u00fcckgabewert dieser Funktion wird in das <strong>JSON-Format<\/strong> umgewandelt (wie von produces: in der Konfigurationsdatei swagger.yml angegeben).<\/p>\n<p>Er besteht aus der Liste der Personen, die alphabetisch nach Nachnamen sortiert ist. An dieser Stelle k\u00f6nnen wir das Programm server.py mit dem Befehl :<\/p>\n<p><strong>$ python server.py<\/strong><\/p>\n<p>was zu folgendem Ergebnis f\u00fchrt, wenn man als Adresse http:\/\/0.0.0.0:8080\/api\/people in die Leiste des Browsers eingibt:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-2.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-2.png 512w, https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-2-300x200.png 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" width=\"512\" height=\"341\"><\/p>\n<h2 class=\"wp-block-heading\" id=\"h-5-swagger-openapi\">5. Swagger\/OpenAPI<\/h2>\n<p>Wir haben also eine einfache API gebaut, die eine einzige Anfrage zul\u00e4sst. Es stellt sich jedoch die Frage, wie man das gleiche Ergebnis auf viel einfachere Weise mit <a href=\"https:\/\/liora.io\/de\/api-erstellen-mit-verschiedenen-apps-teil-i\">Flask<\/a> erreichen kann, wie wir in unserem ersten Artikel gesehen haben:<\/p>\n<p><em>Was bringt die Konfiguration mithilfe der Datei swagger.yml?<\/em><\/p>\n<p>Zus\u00e4tzlich zur API wurde von Connexion eine Swagger-Benutzeroberfl\u00e4che (<a href=\"https:\/\/liora.io\/de\/open-source-definition\">OpenAPI<\/a>) erstellt. Um darauf zuzugreifen, gib einfach <strong>http:\/\/localhost:8080\/api\/ui ein<\/strong>.<\/p>\n<p><em>Man erh\u00e4lt folgendes Ergebnis:<\/em><\/p>\n<figure>\n\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-3-1.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-3-1.png 512w, https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-3-1-300x200.png 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" width=\"512\" height=\"341\"><figcaption><\/figcaption><\/figure>\n<p>Wenn du auf People klickst, erscheint die potenzielle Abfrage :<\/p>\n<figure>\n\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-4-1.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-4-1.png 512w, https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-4-1-300x200.png 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" width=\"512\" height=\"341\"><figcaption><\/figcaption><\/figure>\n<p>Wenn Du auf die Anfrage klickst, werden die folgenden zus\u00e4tzlichen Informationen von der Schnittstelle angezeigt:<\/p>\n<ul>\n<li>Die Struktur der Antwort<\/li>\n<li>Das Format der Antwort (content-type)<\/li>\n<\/ul>\n<p>Der Text, der in swagger.yml \u00fcber die Anfrage eingegeben wurde.<\/p>\n<figure>\n\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-5.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-5.png 512w, https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-5-300x200.png 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" width=\"512\" height=\"341\"><figcaption><\/figcaption><\/figure>\n<p>Man kann die Abfrage sogar ausprobieren, indem man auf die Schaltfl\u00e4che<strong> Try It Out!<\/strong> am unteren Rand des Bildschirms klickt.<\/p>\n<p>Die Schnittstelle erweitert die Anzeige noch weiter und man erh\u00e4lt als Ergebnis :<\/p>\n<figure>\n\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-6.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-6.png 512w, https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-6-300x200.png 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" width=\"512\" height=\"341\"><figcaption><\/figcaption><\/figure>\n<p>All das ist sehr n\u00fctzlich, wenn du eine vollst\u00e4ndige API hast, da es dir erlaubt, mit der API zu testen und zu experimentieren, ohne Code zu schreiben. Die <strong>Swagger\/OpenAPI-Schnittstelle<\/strong> ist nicht nur praktisch, um auf die Dokumentation zuzugreifen, sondern hat auch den Vorteil, dass sie aktualisiert wird, sobald die Datei swagger.yml aktualisiert wird.<\/p>\n<p>Au\u00dferdem bietet die <strong>swagger.yml-Datei<\/strong> einen methodischen Weg, um alle Abfragen zu entwerfen, was ein rigoroses API-Design sicherstellt. Schlie\u00dflich erm\u00f6glicht sie es, den Python-Code von der Konfiguration der Abfragen zu entkoppeln, was sehr n\u00fctzlich sein kann, wenn man APIs entwirft, die Webanwendungen unterst\u00fctzen. Ein Beispiel daf\u00fcr wird im Folgenden gezeigt.<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-6-komplette-api\">6. Komplette API<\/h2>\n<p>Unser Ziel war es, eine API zu erstellen, die <strong>CRUD-Zugriff<\/strong> auf unsere <strong>PEOPLE-Daten<\/strong> bietet. Zu diesem Zweck erg\u00e4nzen wir die Konfigurationsdatei swagger.yml und das Modul people.py, um die Spezifikationen unserer API zu erf\u00fcllen.<\/p>\n<p>Die erg\u00e4nzten Dateien sind im Unterverzeichnis version_3 auf GitHub verf\u00fcgbar: https:\/\/github.com\/salimlardjane1\/projects\/tree\/version_3.<\/p>\n<p>Die Ausf\u00fchrung von <strong>server.py<\/strong> ergibt dann in Bezug auf die Swagger\/OpenAPI-Schnittstelle :<\/p>\n<figure>\n\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-7.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-7.png 512w, https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-7-300x200.png 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" width=\"512\" height=\"341\"><figcaption><\/figcaption><\/figure>\n<p>Die vorherige Schnittstelle erm\u00f6glicht den Zugriff auf die Dokumentation in der Datei <strong>swagger.yml<\/strong> und die Interaktion mit allen URLs, die die CRUD-Funktionen der API implementieren.<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-7-web-app\">7. Web App<\/h2>\n<p>Wir haben jetzt eine dokumentierte <strong>REST-API,<\/strong> mit der wir mithilfe von <strong>Swagger\/OpenAPI<\/strong> interagieren k\u00f6nnen.<\/p>\n<p>Wie geht es weiter?<\/p>\n<p>Der n\u00e4chste Schritt besteht darin, eine Webanwendung zu erstellen, die die konkrete Verwendung der <strong>API<\/strong> veranschaulicht.<\/p>\n<p>Wir erstellen eine Webanwendung, die die Personen in der Datenbank auf dem Bildschirm anzeigt und es erm\u00f6glicht, Personen hinzuzuf\u00fcgen, die Daten der Personen zu aktualisieren und Personen aus der Datenbank zu l\u00f6schen. Dies geschieht mithilfe von AJAX-Anfragen, die von JavaScript an die URLs unserer API gesendet werden.<\/p>\n<p>Als Erstes m\u00fcssen wir die Datei home.html, die die Struktur und das Aussehen der Startseite der Webanwendung steuert, wie folgt erg\u00e4nzen:<\/p>\n<p>Die Datei home.html ist auf GitHub verf\u00fcgbar:<\/p>\n<p>Im Unterverzeichnis templates des Verzeichnisses version_4.<\/p>\n<p>Das HTML-Programm erg\u00e4nzt das urspr\u00fcngliche home.html-Programm um einen Aufruf der externen Datei normalize.min.css (https:\/\/ necolas.github.io\/normalize.css\/), mit der die Darstellung in verschiedenen Browsern standardisiert werden kann.<\/p>\n<p>Au\u00dferdem wird die Datei jquery-3.3.1.min.js (https:\/\/ jquery.com) verwendet, die die jQuery-Funktionen in JavaScript zur Verf\u00fcgung stellt. Diese werden verwendet, um die Interaktivit\u00e4t der Seite zu programmieren.<\/p>\n<p>Der HTML-Code definiert den statischen Teil der Anwendung. Die dynamischen Teile werden von JavaScript eingebracht, wenn auf die Seite zugegriffen wird und wenn der Nutzer mit ihr interagiert.<\/p>\n<p>Die Datei home.html verweist auf zwei statische Dateien: static\/css\/home.css und static\/js\/home.js. Das Verzeichnis mit dem Namen static wird von der Flask-Anwendung sofort erkannt und der Inhalt der Verzeichnisse css und js ist somit von der Datei home.html aus zug\u00e4nglich.<\/p>\n<p>Die Dateien home.css und home.js sind auf <a href=\"\/\">GitHub<\/a> verf\u00fcgbar:<\/p>\n<p>Wir werden im n\u00e4chsten Artikel mehr \u00fcber CSS und <a href=\"https:\/\/liora.io\/de\/coden-lernen-warum-sollte-es-jeder-versuchen\">JavaScript<\/a> sprechen.<\/p>\n<p>Wenn man in das Verzeichnis version_4 wechselt und server.py ausf\u00fchrt, erh\u00e4lt man im Browser folgendes Ergebnis:<\/p>\n<figure>\n\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-8.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-8.png 512w, https:\/\/liora.io\/app\/uploads\/sites\/8\/2023\/03\/unnamed-8-300x200.png 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" width=\"512\" height=\"341\"><figcaption><\/figcaption><\/figure>\n<p>Mit der <strong>Schaltfl\u00e4che Erstellen<\/strong> kann der Nutzer eine Person zum Katalog auf dem Server hinzuf\u00fcgen.<\/p>\n<p>Ein Doppelklick auf eine Zeile in der Tabelle l\u00e4sst den Vor- und Nachnamen in den Eingabefeldern erscheinen.<\/p>\n<p>Um zu aktualisieren, muss der Nutzer den Vornamen \u00e4ndern, da der Name der Suchschl\u00fcssel ist.<\/p>\n<p>Um eine <strong>Person aus dem Verzeichnis zu entfernen,<\/strong> klicke einfach auf L\u00f6schen.<\/p>\n<p>Zur\u00fccksetzen leert die Eingabefelder.<\/p>\n<p>Damit haben wir eine kleine, funktionierende Webanwendung gebaut.<\/p>\n<p>Wie sie funktioniert, werden wir im n\u00e4chsten Artikel genauer betrachten.<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-8-bibliografische-referenzen\">8. Bibliografische Referenzen<\/h2>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><i>Creating Web APIs with Python and Flask, <\/i>Patrick Smyth, 2022 :<a style=\"color: #5e36f3;\" href=\"https:\/\/programminghistorian.org\/en\/lessons\/creating-apis-with-python-and-flask\"> https:\/\/programminghistorian.org\/en\/lessons\/creating-apis-with-python-and-flask<\/a>.<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><i>Python REST APIs With Flask, Connexion, and SQLAlchemy<\/i>, Doug Farrell, 2022 :&nbsp; <a style=\"color: #5e36f3;\" href=\"https:\/\/realpython.com\/flask-connexion-rest-api\/\">https:\/\/realpython.com\/flask-connexion-rest-api\/<\/a>.&nbsp;&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><i>Python REST APIs With Flask, Connexion, and SQLAlchemy<\/i>, Doug Farrell, 2022 : <a style=\"color: #5e36f3;\" href=\"https:\/\/realpython.com\/flask-connexion-rest-api-part-2\/\">https:\/\/realpython.com\/flask-connexion-rest-api-part-2\/<\/a>.<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><i>Flask RESTful documentation<\/i>, 2020 :<a style=\"color: #5e36f3;\" href=\"https:\/\/flask-restful.readthedocs.io\/en\/latest\/index.html\"> https:\/\/flask-restful.readthedocs.io\/en\/latest\/index.html<\/a>.<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><i>Flask Web Development : Developing Web Applications with Python<\/i> (2\u00e8me \u00e9dition). M. Grinberg. O\u2019Reilly 2018.<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><i style=\"color: #000000;\">Architectural Styles and the Design of Network-Based Software Architectures<\/i>. T. Fielding. Th\u00e8se, Universit\u00e9 de Californie, 2000.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In den beiden vorherigen Artikeln haben wir ein erstes Beispiel f\u00fcr die Programmierung einer Web-API unter Flask gesehen und wie man eine Web-API mit einer SqLite-Datenbank verbindet. Im Folgenden werden wir sehen, wie man REST-APIs mit Input- und Output-Validierung und automatisch erstellter Dokumentation von Swagger\/OpenAPI baut. Wir werden auch sehen, wie die API mit JavaScript [\u2026]<\/p>\n","protected":false},"author":85,"featured_media":173488,"comment_status":"open","ping_status":"open","sticky":false,"template":"elementor_theme","format":"standard","meta":{"_acf_changed":false,"editor_notices":[],"footnotes":""},"categories":[2476],"class_list":["post-173487","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud-dev"],"acf":[],"_links":{"self":[{"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/posts\/173487","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/users\/85"}],"replies":[{"embeddable":true,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/comments?post=173487"}],"version-history":[{"count":3,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/posts\/173487\/revisions"}],"predecessor-version":[{"id":216544,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/posts\/173487\/revisions\/216544"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/media\/173488"}],"wp:attachment":[{"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/media?parent=173487"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/categories?post=173487"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}