Die Bequemlichkeit und Vielseitigkeit von Python bedeutet, dass es für die Erstellung von Software in fast jedem Bereich des IT-Lebens verwendet wird. Eine wichtige Nische sind Web-Services, wo die Entwicklungsgeschwindigkeit und die flexiblen Metaphern von Python es leicht machen, Websites schnell zum Laufen zu bringen.
Und wie man sich denken kann, bietet Python eine große Auswahl und einen großen Spielraum für Web-Frameworks, sowohl für kleine als auch für große. Schließlich muss nicht jedes Webprojekt im Unternehmensmaßstab angelegt sein. Die meisten sollten gerade groß genug sein, um die Aufgabe zu bewältigen, und nicht größer. Dieser Artikel gibt einen Überblick über acht der bekanntesten Python-Frameworks, die sich durch Einfachheit, Leichtgewichtigkeit und einen engen Fokus auszeichnen.
Bottle
Bottle könnte man als eine Art Mini-Flask bezeichnen, da es noch kompakter und prägnanter ist als dieses andere „Mikro-Framework“. Aufgrund seines geringen Platzbedarfs ist Bottle ideal für die Einbindung in andere Projekte oder für die schnelle Bereitstellung kleiner Projekte wie REST-APIs. (Flask wird weiter unten besprochen.)
Die gesamte Codebasis von Bottle passt in eine einzige Datei und hat absolut keine externen Abhängigkeiten. Trotzdem ist Bottle mit genügend Funktionalität ausgestattet, um gängige Webanwendungen zu erstellen, ohne auf externe Hilfe angewiesen zu sein.
Das Routing-System in Bottle, das URLs auf Funktionen abbildet, hat fast genau die gleiche Syntax wie Flask. Man ist auch nicht auf fest verdrahtete Pfade beschränkt, sondern kann sie dynamisch erstellen. Auf Anfrage- und Antwortdaten, Cookies, Abfragevariablen, Formulardaten aus einer POST-Aktion, HTTP-Header und Dateiuploads kann in Bottle über Objekte zugegriffen und diese manipuliert werden.
Jede Fähigkeit wurde mit viel Liebe zum Detail implementiert. Bei Datei-Uploads beispielsweise müssen Sie die Datei nicht umbenennen, wenn ihre Namenskonvention mit dem Zieldateisystem kollidiert (z. B. Schrägstriche im Namen unter Windows). Bottle kann das für Sie erledigen.
Bottle enthält eine eigene einfache HTML-Vorlagenerstellungsfunktion. Auch hier ist die Templating-Engine zwar minimal, aber sie enthält alles Wesentliche. Variablen, die in einer Vorlage enthalten sind, werden standardmäßig mit sicherem HTML wiedergegeben; Sie müssen angeben, welche Variablen sicher sind, um sie wörtlich wiederzugeben. Wenn Sie die Template-Engine von Bottle lieber gegen eine andere austauschen möchten, wie z.B. Jinja2, können Sie dies ohne viel Aufhebens tun. Ich bevorzuge das mit Bottle gebündelte Simple-Template-System; es ist schnell, seine Syntax ist unprätentiös, und es erlaubt Ihnen, Code und Template-Text ohne übermäßige Schwierigkeiten zu vermischen.
Bottle unterstützt sogar mehrere Server-Backends. Es kommt mit seinem eigenen eingebauten Miniserver für schnelle Tests, unterstützt aber auch generisches WSGI, eine Vielzahl von WSGI-kompatiblen HTTP-Servern und einfaches altes CGI, wenn nötig.
Bottle braucht nicht so viel Dokumentation wie andere Frameworks, aber die Dokumentation ist keineswegs dürftig. Alle wichtigen Informationen finden auf einer einzigen (wenn auch langen) Webseite Platz. Darüber hinaus finden Sie eine vollständige Dokumentation für jede API, Beispiele für die Bereitstellung auf verschiedenen Infrastrukturen, eine Erklärung der eingebauten Templating-Sprache und eine Reihe von allgemeinen Rezepten.
Wie bei Flask können Sie die Funktionalität von Bottle manuell oder über Plug-ins erweitern. Die Plug-ins von Bottle sind bei weitem nicht so zahlreich wie die von Flask, aber es gibt nützliche Teile, wie die Integration mit verschiedenen Datenbankschichten und die grundlegende Benutzerauthentifizierung. Für die asynchrone Unterstützung kann Bottle einen der vorhandenen Serveradapter verwenden, der asynchron läuft, wie z. B. aiohttp/uvloop, aber async/await
wird nicht nativ unterstützt.
Eine Folge des Minimalismus von Bottle ist, dass einige Elemente einfach nicht vorhanden sind. Formularvalidierung, einschließlich Funktionen wie CSRF (Cross-Site Request Forgery) Schutz, ist nicht enthalten. Wenn Sie eine Webanwendung erstellen möchten, die ein hohes Maß an Benutzerinteraktion unterstützt, müssen Sie diese Unterstützung selbst hinzufügen.
Ein weiteres Problem bei Bottle ist, dass die Entwicklung ins Stocken geraten ist; die letzte Version 0.12 stammt aus dem Jahr 2013. Nichtsdestotrotz wird Bottle weiterhin gepflegt, und die Entwicklungsversionen sind weiterhin für die Produktion verwendbar. Die Entwickler beabsichtigen, neue Versionen zu liefern, die die Unterstützung für ältere Python-Versionen aufheben.
CherryPy
CherryPy gibt es in der einen oder anderen Form seit fast 20 Jahren, hat aber den Minimalismus und die Eleganz, die es von Anfang an auszeichneten, nicht verloren.
Abgesehen davon, dass CherryPy nur das Nötigste enthält, um Webseiten auszuliefern, soll es sich so weit wie möglich nicht wie ein „Web-Framework“ anfühlen, sondern wie jede andere Art von Python-Anwendung. Websites wie Hulu und Netflix haben CherryPy in der Produktion eingesetzt, weil das Framework eine sehr unauffällige Basis bietet, auf der man aufbauen kann. CherryPy verwendet unter der Haube gepoolte Threads, um Multithreading-Serveradapter besser unterstützen zu können.
Mit CherryPy können Sie Ihre Webanwendung von der Kernlogik getrennt halten. Um die Funktionen Ihrer Anwendung auf URLs oder Routen abzubilden, die von CherryPy bedient werden, erstellen Sie eine Klasse, in der die Namespaces der Objekte direkt auf die URLs abgebildet werden, die Sie bedienen wollen. Zum Beispiel wird die Wurzel der Website von einer Funktion namens „index“ bereitgestellt. Parameter, die an diese Funktionen übergeben werden, dienen der Handhabung von Variablen, die von GET- oder POST-Methoden bereitgestellt werden.
Die Bits, die CherryPy enthält, sind als Bausteine auf niedriger Ebene gedacht. Session-Identifikatoren und Cookie-Handling sind enthalten, aber kein HTML-Templating. Wie Bottle bietet CherryPy eine Möglichkeit, Routen auf Verzeichnisse auf der Festplatte abzubilden, um statische Dateien bereitzustellen.
CherryPy wird oft auf eine bestehende Bibliothek eines Drittanbieters zurückgreifen, um eine Funktion zu unterstützen, anstatt sie nativ anzubieten. WebSocket-Anwendungen werden zum Beispiel nicht direkt von CherryPy unterstützt, sondern über die ws4py-Bibliothek.
Die Dokumentation von CherryPy enthält ein praktisches Tutorial, das die verschiedenen Aspekte des Programms erläutert. Es führt Sie nicht durch eine komplette End-to-End-Anwendung, im Gegensatz zu einigen anderen Framework-Tutorials, aber es ist immer noch nützlich. Die Dokumentation enthält praktische Hinweise zum Einsatz in virtuellen Hosts, zum Reverse Proxying über Apache und Nginx und zu vielen anderen Szenarien.
Falcon
Wenn Sie REST-basierte APIs und nichts anderes bauen, ist Falcon genau das Richtige für Sie. Schlank und schnell, mit fast keinen Abhängigkeiten über die Standardbibliothek hinaus, bietet Falcon alles, was Sie für REST-APIs brauchen, und nichts mehr. Falcon 2.0, das 2019 veröffentlicht wird, unterstützt Python 2.x nicht mehr und erfordert mindestens Python 3.5.
Ein großer Teil der Gründe, warum Falcon das Etikett „leicht und schlank“ verdient, hat wenig mit der Anzahl der Codezeilen des Frameworks zu tun. Es liegt daran, dass Falcon den Anwendungen fast keine eigene Struktur auferlegt. Eine Falcon-Anwendung muss lediglich angeben, welche Funktionen auf welche API-Endpunkte abgebildet werden. Die Rückgabe von JSON von einem Endpunkt erfordert nicht viel mehr als das Einrichten einer Route und die Rückgabe der Daten über die json.dumps
-Funktion aus der Python-Standardbibliothek. Unterstützung für async gibt es in Falcon noch nicht, aber es wird daran gearbeitet, dies in Falcon 3.0 zu ermöglichen.
Falcon verwendet auch vernünftige Standardeinstellungen, so dass für die Einrichtung nur wenig Bastelei erforderlich ist. Zum Beispiel werden standardmäßig 404s für jede Route ausgelöst, die nicht explizit deklariert ist. Wenn Sie Fehler an den Client zurückgeben möchten, können Sie eine der zahlreichen Standardausnahmen auslösen, die mit dem Framework gebündelt sind (z. B. HTTPBadRequest
), oder eine generische falcon.HTTPError
-Ausnahme verwenden. Wenn Sie Vor- oder Nachbearbeitung für eine Route benötigen, bietet Falcon auch dafür Hooks an.
Falcons Fokus auf APIs bedeutet, dass es hier wenig für die Erstellung von Webanwendungen mit herkömmlichen HTML-Benutzeroberflächen gibt. Erwarten Sie zum Beispiel nicht viel in Bezug auf Formularverarbeitungsfunktionen und CSRF-Schutztools. Allerdings bietet Falcon elegante Optionen zur Erweiterung seiner Funktionalität, so dass auch anspruchsvollere Elemente erstellt werden können. Neben dem oben erwähnten Hooking-Mechanismus finden Sie eine Schnittstelle zur Erstellung von Middleware, mit der Sie alle APIs von Falcon umhüllen können.
Die Dokumentation für Falcon ist im Vergleich zu anderen Frameworks schlank, aber nur, weil es weniger zu behandeln gibt. Das Benutzerhandbuch enthält eine formale Schritt-für-Schritt-Anleitung für alle wichtigen Funktionen sowie einen Schnellstart-Abschnitt, in dem Sie sich Beispielcode mit oder ohne Anmerkungen ansehen können.
FastAPI
Der Name von FastAPI fasst gut zusammen, was es tut. Es wurde entwickelt, um API-Endpunkte schnell zu erstellen, und es läuft auch schnell.
FastAPI nutzt das Starlette-Projekt für seinen Hochgeschwindigkeits-Netzwerkkern, aber Sie müssen die Interna von Starlette nicht kennen, um FastAPI zu verwenden. Sie definieren Endpunkte auf die gleiche Weise wie eine Flask- oder Bottle-Anwendung – verwenden Sie Dekoratoren, um anzugeben, welche Funktionen welche Routen handhaben – und geben Sie dann Wörterbücher zurück, die automatisch in JSON übersetzt werden.
Sie können leicht überschreiben, wie Dinge zurückgegeben werden. Wenn Sie zum Beispiel HTML/XML von einigen Endpunkten zurückgeben möchten, können Sie das tun, indem Sie einfach ein benutzerdefiniertes Response
-Objekt zurückgeben. Wenn Sie benutzerdefinierte Middleware hinzufügen möchten, können Sie alles einfügen, was dem ASGI-Standard entspricht.
FastAPI nutzt Pythons Type Hinting, um die Art der Daten, die Routen akzeptieren, einzuschränken. Wenn Sie zum Beispiel eine Route mit dem Typ Optional
haben, lehnt FastAPI alle Eingaben außer Ganzzahlen ab. Sie müssen keinen Datenvalidierungscode zu Ihren Endpunkten hinzufügen; Sie können einfach Typhinweise verwenden und FastAPI die Arbeit machen lassen.
Natürlich werden einige Dinge ausgelassen. Es gibt zum Beispiel keine native HTML-Vorlagen-Engine, aber es gibt keinen Mangel an Lösungen von Drittanbietern, die diese Lücke füllen. Dasselbe gilt für die Datenbankanbindung, aber die Dokumentation enthält Details darüber, wie man bestimmte ORMs (z.B. Peewee) dazu bringt, mit dem asynchronen Verhalten von FastAPI zu arbeiten.
Flask
Viele Diskussionen über Python-Web-Frameworks beginnen mit Flask, und das aus gutem Grund. Flask ist ein gut etabliertes, gut verstandenes Framework, das einfach zu benutzen und ziemlich stabil ist. Es ist so gut wie unmöglich, mit Flask etwas falsch zu machen, wenn man ein leichtes Webprojekt oder eine einfache REST-API entwickeln will, aber wenn man versucht, etwas Größeres zu bauen, wird es schwierig.
Flask besticht vor allem durch seine niedrige Einstiegshürde. Eine einfache „Hallo Welt“-Anwendung lässt sich in weniger als 10 Zeilen Python einrichten. Flask enthält ein weit verbreitetes HTML-Templating-System, Jinja2, um das Rendern von Text zu vereinfachen, aber Jinja2 kann gegen eine beliebige Anzahl anderer Template-Engines (wie Mustache) ausgetauscht werden, oder Sie können Ihre eigene entwickeln.
Im Namen der Einfachheit verzichtet Flask auf Feinheiten wie eine Datenschicht oder ORM und bietet keine Vorkehrungen für Formularvalidierung. Flask kann jedoch durch Erweiterungen erweitert werden, von denen es Dutzende gibt, die viele gängige Anwendungsfälle wie Caching, Formularverarbeitung und -validierung sowie Datenbankanbindung abdecken. Dieses schlanke Design ermöglicht es Ihnen, die Entwicklung einer Flask-Anwendung mit dem absoluten Minimum an Funktionalität zu beginnen und dann nur die Teile hinzuzufügen, die Sie benötigen, wenn Sie sie brauchen.
Die Dokumentation von Flask ist genial und leicht zu lesen. Das Quick-Start-Dokument leistet hervorragende Arbeit und erklärt gleichzeitig die Bedeutung der Standardeinstellungen für eine einfache Flask-Anwendung, und die API-Dokumente sind voll von guten Beispielen. Hervorragend ist auch die Sammlung von Flask-Snippets, bei denen es sich um schnell umsetzbare Beispiele für bestimmte Aufgaben handelt, z. B. wie man ein Objekt zurückgibt, wenn es existiert, oder einen 404-Fehler, wenn es nicht existiert.
Flask hat 2018 seinen Meilenstein 1.0 erreicht, wobei Python 2.6 und Python 3.3 die minimal unterstützten Versionen sind und viele seiner Verhaltensweisen endlich in Stein gemeißelt sind. Flask unterstützt nicht explizit die async-Syntax von Python, aber eine API-kompatible Variante von Flask namens Quart wurde ausgegliedert, um diese Anforderung zu erfüllen.
Pyramid
Klein und leicht, eignet sich Pyramid gut für Aufgaben wie die Offenlegung von bestehendem Python-Code als REST-API oder die Bereitstellung des Kerns für ein Webprojekt, bei dem der Entwickler die meiste Arbeit leistet.
„Pyramid ermöglicht es Ihnen, schnell produktiv zu werden, und wächst mit Ihnen“, heißt es in der Dokumentation. „Es wird Sie nicht zurückhalten, wenn Ihre Anwendung klein ist, und es wird Ihnen nicht im Weg stehen, wenn Ihre Anwendung groß wird.“
Ein guter Weg, den Minimalismus von Pyramid zu beschreiben, wäre „frei von Richtlinien“, ein Begriff, der in dem Abschnitt der Dokumentation verwendet wird, in dem erörtert wird, wie Pyramid im Vergleich zu anderen Web-Frameworks aussieht. Grundsätzlich bedeutet „frei von Richtlinien“, dass es für Pyramid nicht von Belang ist, welche Datenbank oder welche Templating-Sprache Sie verwenden möchten.
Sehr wenig Arbeit ist nötig, um eine grundlegende Pyramid-Anwendung zu erstellen. Wie bei Bottle und Flask kann eine Pyramid-Anwendung aus einer einzigen Python-Datei bestehen, abgesehen von den Dateien für das Framework selbst. Eine einfache Ein-Route-API erfordert nicht mehr als ein Dutzend Codezeilen. Das meiste davon ist Boilerplate wie from … import
-Anweisungen und das Einrichten des WSGI-Servers.
Standardmäßig enthält Pyramid mehrere Elemente, die in Webanwendungen üblich sind, aber sie werden als Komponenten bereitgestellt, die zusammengefügt werden können, nicht als vollständige Lösungen. Die Unterstützung für Benutzersitzungen beispielsweise wird sogar mit CSRF-Schutz geliefert. Aber Unterstützung für Benutzerkonten, wie z. B. Anmeldungen oder Kontoverwaltung, ist nicht Teil der Lösung. Sie müssen sie selbst entwickeln oder über ein Plug-in hinzufügen. Dasselbe gilt für die Handhabung von Formularen und Datenbankverbindungen.
Pyramid bietet sogar eine Möglichkeit, Vorlagen aus früheren Pyramid-Projekten zu erstellen, um frühere Arbeiten wiederzuverwenden. Diese Vorlagen, „Scaffolds“ genannt, generieren eine Pyramid-Anwendung mit einfachem Routing und einigen HTML/CSS-Startvorlagen. Zu den mitgelieferten Scaffolds gehören ein Beispiel-Starterprojekt und ein Projekt, das über die beliebte Python-Bibliothek SQLAlchemy eine Verbindung zu Datenbanken herstellt.
Die schlanken Test- und Debugging-Tools von Pyramid erfüllen den Zweck. Wenn Sie die debugtoolbar
-Erweiterung in eine Pyramid-App einbinden, erhalten Sie auf jeder Webseite ein anklickbares Symbol, das Details über die Ausführung der App generiert, einschließlich eines detaillierten Tracebacks im Falle von Fehlern. Logging und Unit-Tests sind ebenfalls vorhanden.
Die Dokumentation von Pyramid ist hervorragend. Neben einer kurzen Einführung in die Grundlagen und einer Anleitung im Stil eines Tutorials finden Sie eine Reihe von Tutorials, die von der Community beigesteuert wurden, und ein Kochbuch mit allgemeinen Rezepten. Letzteres enthält Einsatztechniken für eine Reihe von Zielumgebungen, von Google App Engine bis Nginx.
Pyramid unterstützt sowohl Python 2 als auch Python 3, verwendet aber nicht die async-Syntax von Python 3. Wenn Sie async in Pyramid nutzen wollen, sehen Sie sich das aiopyramid-Projekt an, das ein Gerüst für eine async-getriebene „Hallo Welt“-Anwendung enthält.
Sanic
Das auf Geschwindigkeit und Einfachheit ausgelegte Sanic arbeitet mit Python 3.6 oder höher und verwendet die Syntax async/await
von Python (verfügbar ab Python 3.5), um effiziente Webanwendungen zu erstellen.
Wie bei Flask oder Bottle umfasst eine einfache Sanic-„Hallo Welt“-Anwendung etwa 10 Zeilen Code, wovon das meiste auf Importe und andere Boilerplate zurückzuführen ist. Der Hauptunterschied besteht darin, dass Anwendungsrouten als async def
-Funktionen deklariert werden müssen, und Sie müssen await
verwenden, um diese Funktionen innerhalb Ihres asynchronen Codes aufzurufen. Wenn Sie schon einmal asynchrone Anwendungen geschrieben haben, haben Sie den schwierigsten Teil bereits hinter sich.
Viele der Mechanismen, die Sanic für die Handhabung von Verbindungen und Antworten verwendet, werden Ihnen bekannt vorkommen. Anfragen und Antworten sind einfach Objekte mit vertrauten Eigenschaften, wie hochgeladene Dateien, Formulare, JSON-Objekte, Kopfzeilen und so weiter.
Anwendungen mit vielen Routen werden unhandlich in der Verwaltung. Sanic begegnet diesem Problem mit „Blueprints“, Objekten, die Gruppen von Routen beschreiben können und es ermöglichen, diese über eine High-Level-Schnittstelle zu verwalten. Anstatt jede Route explizit zu schreiben oder ein Übermaß an Routen mit Variablen zu verwenden, können Sie ein paar Blueprints schreiben, um allgemein zu beschreiben, wie die Routen in Ihrer Anwendung funktionieren (z. B. /object/object_id/action
). Blueprints können eine gemeinsame Middleware haben, was nützlich ist, wenn Sie die Verwaltungsfunktionalität auf einige Routen anwenden wollen, auf andere aber nicht.
Sanic arbeitet auch mit anderen Protokollen als HTTP. WebSocket-Endpunkte erfordern nur einen anderen Dekorator und ein wenig mehr interne Logik (z.B. das Warten und Verarbeiten von Antworten). Benutzerdefinierte Netzwerkprotokolle können durch Unterklassen von asyncio.protocol
unterstützt werden.
Sanic lässt absichtlich Funktionalitäten wie Datenbankkonnektivität und HTML-Templating weg, während es die Funktionen beibehält, die man verwenden würde, um diese Fähigkeiten einzubauen: Middleware, zentralisierte Anwendungskonfiguration, und so weiter.
Tornado
Tornado ist ein weiteres kleines Framework, das auf einen speziellen Anwendungsfall abzielt: asynchrone Netzwerkanwendungen. Tornado eignet sich gut für die Erstellung von Diensten, die viele Netzwerkverbindungen öffnen und am Leben erhalten – also alles, was WebSockets oder langes Polling beinhaltet. Tornado 6.0 erfordert Python 3.5 oder höher und verzichtet vollständig auf die Unterstützung von Python 2.
Wie Bottle oder Falcon verzichtet Tornado auf Funktionen, die für seinen zentralen Zweck irrelevant sind. Tornado verfügt über ein eingebautes Templating-System zur Erzeugung von HTML- und anderen Ausgaben und bietet Mechanismen zur Internationalisierung, Formularverarbeitung, Cookie-Einstellung, Benutzerauthentifizierung und CSRF-Schutz. Allerdings fehlen Funktionen wie die Formularvalidierung und ein ORM, die hauptsächlich für Webanwendungen mit Benutzeroberfläche gedacht sind.
Tornado zeichnet sich durch die Bereitstellung einer Infrastruktur für Anwendungen aus, die eine genaue Kontrolle über asynchrone Netzwerke benötigen. Zum Beispiel bietet Tornado nicht nur einen eingebauten asynchronen HTTP-Server, sondern auch einen asynchronen HTTP-Client. Damit eignet sich Tornado hervorragend für die Entwicklung von Anwendungen wie Web Scraper oder Bot, die parallel andere Websites abfragen und auf die zurückgegebenen Daten reagieren.
Wenn Sie eine Anwendung erstellen möchten, die andere Protokolle als HTTP verwendet, ist Tornado die richtige Wahl. Tornado bietet Zugang zu Low-Level-TCP-Verbindungen und Sockets zu Dienstprogrammen wie DNS-Resolvern sowie zu Authentifizierungsdiensten von Drittanbietern und unterstützt die Interaktion mit anderen Frameworks über den WSGI-Standard. Die Dokumentation, die zwar klein, aber nicht spärlich ist, enthält reichlich Beispiele für all dies.
Tornado nutzt und ergänzt die nativen Funktionen von Python für asynchrones Verhalten. Wenn Sie Python 3.5 verwenden, unterstützt Tornado die eingebauten Schlüsselwörter async
und await
, die Anwendungen einen Geschwindigkeitsschub verleihen. Sie können auch Futures oder Callbacks verwenden, um Antworten auf Ereignisse zu verarbeiten.
Tornado bietet eine Bibliothek von Synchronisationsprimitiven -emaphores, Locks, usw. – um Ereignisse zwischen asynchronen Coroutines zu koordinieren. Beachten Sie, dass Tornado normalerweise im Single-Thread-Betrieb läuft, so dass diese Primitive nicht mit ihren Namensvettern im Thread-Betrieb identisch sind. Wenn Sie Tornado jedoch in parallelen Prozessen laufen lassen wollen, um mehrere Sockets und Kerne zu nutzen, stehen Ihnen entsprechende Werkzeuge zur Verfügung.
Die Dokumentation von Tornado deckt jedes wichtige Konzept des Frameworks und alle wichtigen APIs des Modells ab. Sie enthält zwar eine Beispielanwendung (einen Web-Crawler), dient aber hauptsächlich zur Demonstration des Warteschlangenmoduls von Tornado.