Ich habe versucht, einen Flask Restful Endpoint mit dem webargs-Framework zu implementieren, welches ich bereits 2020 verwendet habe. Obwohl ich den alten Code kopiert und einige winzige Anpassungen am Request-Aufruf vorgenommen habe, konnte ich ihn 2023 nicht mehr zum Laufen bringen. Indem ich ChatGPT um Hilfe bat, erlangte ich ein klareres Verständnis für alle Komponenten des Frameworks. Letztendlich gab es mir gute Hinweise, was ich googeln sollte. Es stellte sich heraus, dass der @use_kwargs-Dekorator (beginnend mit Version 6.0.0) einen zusätzlichen Parameter namens location benötigt, um auf Parameter zuzugreifen, die über die Abfrage übergeben werden. Obwohl ChatGPT einen Beispielcode zur Verfügung stellte, enthielt er diesen Hinweis nicht, dies liegt vermutlich daran. dass es sich um Informationen handelt, die sich mit der Zeit ändern. Nichtsdestotrotz war es sehr hilfreich, mit einer “Gummi-Ente” zu sprechen, die über zusätzliches Hintergrundwissen verfügt.
Erstellen eines Flask Restful Endpunktes mit Webargs in 2020
2020 habe ich einen einfachen API-Endpunkt für ein Freizeitprojekt entwickelt und offensichtlich webargs==5.5
verwendet. Ein Snippet der API und wie sie aufgerufen wird, ist in dem folgenden Code beschrieben. Damals funktionierte es für mich noch einwandfrei.
# Flask Restful Endpoint
class UsageTime(Resource):
@use_kwargs( {"deviceID":fields.String(required=True) } )
def get(self, deviceID):
usageTime = readFile(deviceID,"usageTime")
message = readFile(deviceID,"message")
return {'usageTime':usageTime, 'message':message}, 200
# Powershell Get request
$r = Invoke-WebRequest -Uri ${server}:5000/UsageTime?deviceID=ID -TimeoutSec 60 -Method GET
Erstellen eines Flask Restful Endpunktes mit Webargs in 2023
Für ein anderes Projekt habe ich also angefangen, das gleiche zu tun:
# Flask Restful Endpoint
class TopicOverview(Resource):
@use_kwargs({"hash_id": fields.Str(required=True), })
def get(self, hash_id):
print(hash_id)
return {'message': 'Hello, ' + hash_id}, 200
# curl get request
curl http://127.0.0.1/topicoverview?hash_id=a
Allerdings würde der Aufruf immer eien Fehler hervorrufen:
LookupError: no exception for None
# or if i remove the required=True
TypeError: get() missing 1 required positional argument: 'hash_id'
Der Fehler zeigte an, dass das GET-Argument irgendwie nicht geparst oder nicht korrekt an meinen Endpunkt übergeben werden konnte, aber ich wusste nicht, wie ich dieses Problem googeln sollte.
Wie ChatGPT mir beim Debuggen geholfen hat
Also habe ich ChatGPT um Hilfe gebeten. Der Anfang war etwas holprig, weil ich nicht wusste, was mein Assistent von mir brauchen würde und wie ich mein Problem formulieren sollte. Schließlich stieß ich auf eine recht interessante Antwort:
Tatsächlich war die Erklärung nicht sehr hilfreich, aber der bereitgestellte Code funktionierte und ich fragte mich nun, warum er funktionierte. Anscheinend erkennt der Dekorator use_kwargs
die Parameter nicht, die ich in der Abfrage übergeben habe, aber die Übergabe der Parameter hat korrekt funktioniert. Der nächste Schritt ist also Google zu fragen, warum use_kwargs
nicht wie erwartet funktioniert.
Dies führte zu einem sehr ähnlichen Github-Problem mit dem webargs-Framework ab Version 6.0.0 (die nur 2 Monate nach meinem ersten Versuch in 2020 veröffentlicht wurde). Mit dem major Update ist es nun offenbar erforderlich, @use_kwargs
mitzuteilen, wo sich der gewünschte Parameter befindet, indem der Parameter location=’query’ gesetzt wird.
Außerdem habe ich ChatGPT gebeten, den obigen Code so zu refactoren, dass er mit dem webargs-Framework funktioniert, aber er enthält nicht das Schlüsselwort location. Meine Vermutung ist, dass entweder die Trainingsdaten diese Information nicht enthielten, oder es noch nicht gut genug mit Informationen umgehen, die sich einer zeitlichen Veränderungen unterziehen.
Wie man einen Python Flask RESTful Endpunkt mit Webargs erstellt
Um diesen Blogeintrag noch ein erfolgreiches Ende zu bescheren, anbei der Codeausschnitt, um einen Endpunkt mit einer GET Anfrage anzusteuern, inklusiver der Übergabe des Parameters hash_id.
class TopicOverview(Resource):
@use_kwargs({"hash_id": fields.Str(), }, location="query")
def get(self, hash_id):
print(hash_id)
return {'message': 'Hello, ' + hash_id}, 200
Für einige mag dies offensichtlich gewesen sein, aber für mich, der nie Frontend-Entwicklung betreibt, war das ein reiner Kampf sich mit der API Anfrage und dem zu erwartetem payload zu beschäftigen. Hier half ChatGPT durch die Erklärung vieler Konzepte um somit einen etwas klareren Überblick zu haben, welche Komponenten den wahrscheinlicher den Fehler verursacht haben könnten.