Top 5 asynchrone Web-Frameworks für Python

Die asynchrone Programmierung hat sich in Python zu einem vollwertigen Bestandteil entwickelt. Für Webentwickler stehen beeindruckende Frameworks zur Auswahl!

Asynchronität ist in der Python-Community kein reines Modewort mehr. Mit der Einführung der asyncio-Bibliothek in Version 3.5 erkannte Python die Auswirkungen von Node.js auf die Webentwicklung und führte die Schlüsselwörter `async` und `await` ein. Dies war ein bedeutender Schritt, da Python sehr zurückhaltend bei der Erweiterung der Kernsyntax ist, es sei denn, es ist dringend erforderlich, was die Wichtigkeit der asynchronen Fähigkeiten für Python-Entwickler unterstreicht.

Diese Entwicklung hat eine Flut an Möglichkeiten für asynchrone Programmierung eröffnet: Neue und bestehende Bibliotheken nutzen Coroutinen, asynchrone Frameworks werden immer beliebter, und es werden kontinuierlich neue entwickelt. Eine Performance auf Augenhöhe oder sogar besser als die von Node.js ist keine Seltenheit. Wenn Ihre Lastmuster nicht durch CPU-intensive Aufgaben gekennzeichnet sind, können Sie problemlos mehrere tausend Anfragen pro Sekunde bearbeiten.

Doch genug der Motivation!

Betrachten wir die aktuelle Python-Landschaft und einige der führenden asynchronen Frameworks.

Tornado

Überraschenderweise ist Tornado kein neues Framework. Es wurde erstmals 2009 veröffentlicht und hat sich seitdem auf die Bereitstellung robuster asynchroner Programmierung mit hoher Parallelität konzentriert.

Tornado ist nicht nur ein Webframework, sondern eine Sammlung asynchroner Module, die auch für den Aufbau des Webframework-Moduls verwendet werden. Genauer gesagt handelt es sich um folgende Module:

  • Coroutinen und andere Primitive (tornado.gen, tornado.locks, tornado.queues etc.)
  • Netzwerkmodule (tornado.ioloop, tornado.iostream etc.)
  • Asynchrone Server und Clients (tornado.httpser, tornado.httpclient etc.)

Diese Module wurden kombiniert, um die Framework-Module wie `tornado.web`, `tornado.routing` und `tornado.template` zu erstellen.

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hallo Welt")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Tornado hat eine starke Anhängerschaft in der Python-Community und wird von erfahrenen Architekten für den Aufbau hochleistungsfähiger Systeme verwendet. Es ist ein Framework, das seit langem eine Lösung für Parallelitätsprobleme bietet, aber aufgrund fehlender WSGI-Standardunterstützung und des hohen Einarbeitungsaufwands (viele Python-Bibliotheken sind immer noch synchron) möglicherweise nicht zum Mainstream geworden ist.

Sanic

Sanic ist ein „modernes“ Framework im wahrsten Sinne des Wortes: Es unterstützt keine Python-Versionen unter 3.6, nutzt die einfache und universelle `async`/`await`-Syntax und erfordert nicht, dass Sie umfangreiche Dokumentationen studieren oder Fallstricke im Hinterkopf behalten, bevor Sie Ihren ersten HTTP-Handler schreiben.

Die resultierende Syntax ist recht ansprechend; sie ähnelt Code, den man mit anderen Mikroframeworks schreiben würde (wie Flask, CherryPy), mit einigen wenigen Async-Elementen:

from sanic import Sanic
from sanic.response import json

app = Sanic()

@app.route("/")
async def test(request):
    return json({"hello": "world"})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

Sanic ist wahrscheinlich das beliebteste asynchrone Framework in der Python-Welt. Es bietet fast alle Funktionen, die Sie sich für Ihre Projekte wünschen – Routing, Middleware, Cookies, Versionierung, Blueprints, klassenbasierte Views, statische Dateien, Streaming, Sockets usw. – und was nicht direkt verfügbar ist – Templating, Datenbankunterstützung, Datei-I/O, Warteschlangen – kann einfach hinzugefügt werden, da es mittlerweile genügend asynchrone Bibliotheken dafür gibt.

Vibora

Vibora ist eng mit Sanic verwandt, hat sich jedoch zum Ziel gesetzt, der schnellste Python-Webserver überhaupt zu werden. Die Webseite wirbt mit einem Benchmark-Vergleich:

Wie ersichtlich, beansprucht Vibora, um ein Vielfaches schneller zu sein als klassische Frameworks und mehr als doppelt so schnell wie sein direkter Konkurrent Sanic. Benchmarks sind natürlich mit Vorsicht zu genießen. 🙂

Obwohl Vibora in Syntax und Funktionen mit Sanic vergleichbar ist (oder sogar etwas besser, da es beliebte Bibliotheken integriert und Funktionen wie Templating sofort verfügbar sind), ist Sanic ausgereifter, da es länger existiert und eine größere Community hat.

from vibora import Vibora, JsonResponse

app = Vibora()

@app.route('/')
async def home():
    return JsonResponse({'hello': 'world'})

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8000)

Für Performance-Enthusiasten ist Vibora sicherlich interessant. Allerdings wird Vibora zum Zeitpunkt der Erstellung dieses Artikels komplett neu geschrieben, um noch schneller zu werden. Der Link zur Performance-Version deutet darauf hin, dass sich das Projekt in „intensiver Entwicklung“ befindet. Dies wird diejenigen enttäuschen, die Vibora bereits nutzen und sich nun mit tiefgreifenden Änderungen auseinandersetzen müssen. Jedoch ist es noch früh in der asynchronen Python-Welt, und Stabilität ist nicht immer gegeben.

Quart

Wenn Sie gerne mit Flask arbeiten, aber die fehlende asynchrone Unterstützung bedauern, wird Ihnen Quart gefallen.

Quart ist konform mit dem ASGI-Standard, der eine Weiterentwicklung des WSGI-Standards mit Async-Unterstützung darstellt. Das Besondere an Quart ist, dass es nicht nur Flask ähnelt, sondern sogar mit der Flask-API kompatibel ist! Der Autor wollte das Flask-Feeling erhalten und lediglich Async-Unterstützung, WebSockets und HTTP 2 hinzufügen. Somit können Sie Quart direkt aus der Flask-Dokumentation erlernen, wobei Sie beachten müssen, dass Funktionen in Quart asynchron sind.

from quart import Quart

app = Quart(__name__)

@app.route('/')
async def hello():
    return 'hello'

app.run()

Fühlt sich fast genauso an wie Flask, nicht wahr?

Da Quart eine Weiterentwicklung von Flask ist, sind alle Funktionen von Flask verfügbar: Routing, Middleware, Sessions, Templating, Blueprints usw. Sie können sogar Flask-Erweiterungen direkt in Quart nutzen. Ein Nachteil ist, dass nur Python 3.7+ unterstützt wird. Wer jedoch nicht die neueste Python-Version verwendet, sollte sich mit asynchroner Programmierung nicht auseinandersetzen. 🙂

Die Dokumentation ist verbesserungswürdig, besonders wenn Sie keine Vorkenntnisse in Flask haben. Trotzdem ist Quart empfehlenswert, da es sich wahrscheinlich dem Release der Version 1.0 nähert.

FastAPI

Das letzte (aber beeindruckendste) Framework dieser Liste ist FastAPI. Es ist kein reines API-Framework. Tatsächlich ist FastAPI das funktionsreichste und am besten dokumentierte Framework, das ich bei meiner Recherche gefunden habe.

Es ist erwähnenswert, dass der Autor des Frameworks verschiedene andere Frameworks gründlich untersucht hat, darunter Django, Sanic, und sich auch mit NestJS (einem Node.js- und Typescript-Webframework) auseinandergesetzt hat. Die Entwicklungsphilosophie und ausführliche Vergleiche können hier nachgelesen werden.

Die Syntax ist sehr ansprechend; man könnte sogar sagen, dass sie viel angenehmer ist als bei den anderen vorgestellten Frameworks:

from fastapi import FastAPI

app = FastAPI()

@app.get("/users/me")
async def read_user_me():
    return {"user_id": "der aktuelle Benutzer"}

@app.get("/users/{user_id}")
async def read_user(user_id: str):
    return {"user_id": user_id}

Hier ist eine Liste der Killer-Features, die FastAPI in den Schatten stellt:

Automatische API-Dokumentengenerierung: Sobald Sie Ihre Endpunkte geschrieben haben, können Sie die API über eine standardkonforme Oberfläche verwenden. SwaggerUI, ReDoc und andere werden unterstützt.

Das Framework führt auch eine automatische Dokumentation der Datenmodelle mit JSON-Schema durch.

Moderne Entwicklung: Der Begriff „modern“ wird oft verwendet, aber FastAPI wird seinem Ruf wirklich gerecht. Dependency Injection und Type Hinting sind integrale Bestandteile, die nicht nur gute Codierungsgrundsätze durchsetzen, sondern auch Fehler und Verwirrung vorbeugen.

Umfangreiche Dokumentation: Eine gute Dokumentation ist unerlässlich, und in diesem Bereich ist FastAPI unschlagbar. Die umfangreichen Dokumente erklären fast jede Einzelheit und geben Entwicklern aller Erfahrungsstufen wichtige Hinweise. Die Dokumentation ist mit viel Herzblut geschrieben, und ein Vergleich mit der Django-Dokumentation ist angemessen.

Über die Grundlagen hinaus: FastAPI unterstützt WebSockets, Streaming und GraphQL und bietet traditionelle Hilfsfunktionen wie CORS, Sessions, Cookies usw.

Wie sieht es mit der Leistung aus? FastAPI basiert auf der beeindruckenden Starlette-Bibliothek und bietet eine Performance, die mit Node und in manchen Fällen sogar mit Go vergleichbar ist. Insgesamt habe ich das Gefühl, dass FastAPI die Führung als bestes Async-Framework für Python übernehmen wird.

Fazit

In der asynchronen Python-Landschaft ist derzeit viel in Bewegung. Neue Frameworks erscheinen, alte werden neu geschrieben und Bibliotheken werden an asynchrone Paradigmen angepasst. Obwohl Python eine integrierte Unterstützung für Ereignisschleifen bietet und es möglich ist, Teile Ihrer Anwendung asynchron zu gestalten, können Sie sich dafür entscheiden, alles asynchron zu machen und auf einem der vorgestellten Frameworks aufzubauen. Achten Sie auf die langfristigen Auswirkungen: Einige asynchrone Python-Frameworks befinden sich noch in einer frühen Entwicklungsphase, was zu einem schnellen Wandel führt, der Ihre Entwicklungsprozesse beeinträchtigen und die Kosten erhöhen kann. Vorsicht ist geboten!

Dennoch ist Python bereit, eine hohe Leistung bei Webframeworks zu liefern. Wenn Sie schon länger über eine Migration zu Node nachgedacht haben, ist das nicht mehr notwendig! 🙂

Interessiert? Lernen Sie Python noch heute!