Flask Streaming mit JSON

Django, Flask, Bottle, WSGI, CGI…
Antworten
Sternenregen
User
Beiträge: 39
Registriert: Mittwoch 13. Januar 2021, 16:17

Ich möchte eine Liste von JSONs Häppchenweise an den Client zurücksenden.

Die Anfrage starte ich via einem Ajax Script.

Um das ganze zu Testen habe ich ein kleines Testkonstrukt aufgebaut. Texte Stückweise an den Client zu versenden funktioniert. Allerdings will ich es einfach nicht mit JSONs gelingen.

Folgender Code zeigt nur eine Momentaufnahme. Ich hab schon einiges ausprobiert.

Code: Alles auswählen

@app.route("/testloop", methods=['POST'])
def testloop():
    def generate():
        print("Testlooop")
        p1 = '{ "name":"John"}'
        dummy = json.loads(p1)
        list = ['1', '2']
        json_list = [dummy, dummy, dummy, dummy]

        for j in json_list:
            yield json.dumps(j).encode('utf-8')
    return Response(stream_with_context(generate()), mimetype="application/json")
Ohne das json.dumps(j).encode('utf-8') und encodieren, wird eine Exception geworfen, dass unbedingt Bytes verlangt sind.
So ist die Fehlermeldung zwar verschwunden, aber es schlägt in Ajax auf.

Das Ajax Script funktioniert. Datatype und Contenttype wurde natürlich umgestellt.

Code: Alles auswählen

,,,,,
     contentType: "application/json",
        dataType: 'json',
,,,,,
Über Vorschläge warum es nicht funktioniert, wäre ich sehr dankbar.
Sternenregen
User
Beiträge: 39
Registriert: Mittwoch 13. Januar 2021, 16:17

Ich konnte den Fehler etwas eingrenzen.

Es wird nach Bytes verlangt. Mache ich aber json.dumps(j).encode('utf-8'), ist es kein valides JSON mehr, da es den Präfix 'b' hat. Was macht man denn da jetzt?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Musst du für flask nicht einfach direkt das Datenobjekt abliefern? Also ohne JSON.dump?
Sternenregen
User
Beiträge: 39
Registriert: Mittwoch 13. Januar 2021, 16:17

Das hab ich grad probiert.

Da bekomme ich dann folgende Meldungen

Code: Alles auswählen

127.0.0.1 - - [02/Mar/2021 18:39:21] "GET /apple-touch-icon-precomposed.png HTTP/1.1" 404 -
127.0.0.1 - - [02/Mar/2021 18:39:21] "GET /apple-touch-icon.png HTTP/1.1" 404 -
127.0.0.1 - - [02/Mar/2021 18:39:21] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [02/Mar/2021 18:39:21] "GET /apple-touch-icon-precomposed.png HTTP/1.1" 404 -
127.0.0.1 - - [02/Mar/2021 18:39:21] "GET /apple-touch-icon.png HTTP/1.1" 404 -
127.0.0.1 - - [02/Mar/2021 18:39:21] "GET /favicon.ico HTTP/1.1" 404 -
Hier mal Sicherheitshalber das AJAX Script:

Code: Alles auswählen

 
function jsontestloop(){

 $.ajax({
        type: 'GET',
        url: 'http://127.0.0.1:5000/testloop',
        contentType: "application/json",
        dataType: 'json',
        success: function(data) {
        alert(data)
            $("#testtable").append(
                "<tr>"
                    +"<td>"+data.name+"</td>"
                +"</tr>" )
        }

    });
Das "GET" habe ich auch neben der app.route hinzugefügt.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das sind doch alles nur favicon requests, die der Browser einfach immer macht. Die sind egal,
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Sternenregen: Das funktioniert so nicht. Dein Ajax sendet *eine* Anfrage und erwartet *eine* Antwort. Die kommt auch, aber das ist dann nicht *ein* JSON-Dokument sondern mehrere einzelne JSON-Dokumente. Ich vermute mal das ist dann auch der Fehler der Dir im Browser aufschlägt weil das nicht als JSON-Dokument dekodierbar ist.

Was ist denn das Ziel? Hast Du bereits eine komplette Python-Datenstruktur und willst nur die Umwandlung in eine grosse Zeichenkette auf dem Server vermeiden?
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten