2016-07-12 8 views
0

Ich erstelle eine REST-API in Google App Engine (keine Endpunkte), mit der Nutzer eine CSV- oder Tabulator-getrennte Datei hochladen und nach möglichen Duplikaten suchen können. Da es sich um eine API handelt, kann ich <form> s oder BlobStores upload_url nicht verwenden. Ich kann mich auch nicht darauf verlassen, einen einzigen Webclient zu haben, der diese API aufruft. Stattdessen senden Benutzer im Idealfall die Datei in der body der Anfrage.Newlines im POST-Anfragetext entfernt? (Google App Engine)

Mein Problem ist, wenn ich versuche, den Inhalt einer durch Tabulatoren getrennten Datei zu lesen, finde ich, dass alle Newline-Zeichen entfernt wurden, so dass es keine Möglichkeit gibt, den Inhalt in Zeilen aufzuteilen.

Wenn ich den Inhalt der Datei direkt an den Interpreter Python zu überprüfen, ich sehe, dass Tabs und Zeilenvorschübe sind (Ausgang im Beispiel abgeschnitten wird)

>>> with open('./data/occ_sample.txt') as o: 
...  o.read() 
... 
'id\ttype\tmodified\tlanguage\trights\n123456\tPhysicalObject\t2015-11-11 11:50:59.0\ten\thttp://creativecommons.org/licenses/by-nc/3.0\n...' 

Der RequestHandler protokolliert den Inhalt der Anforderung Körper So

import logging 
class ReportApi(webapp2.RequestHandler): 
    def post(self): 
     logging.info(self.request.body) 
     ... 

, wenn ich rufe die API in der dev_appserver über curl

curl -X POST -d @data/occ_sample.txt http://localhost:8080/api/v0/report 
ausgeführt wird:

Dies zeigt sich in den Protokollen nach oben:

id type modified language rights123456 PhysicalObject 2015-11-11 11:50:59.0 en http://creativecommons.org/licenses/by-nc/3.0 

Wie Sie sehen können, gibt es nichts zwischen dem letzten Wert der Header und dem ersten Datensatz (rights und 123456 respectively) und das gleiche passiert mit dem letzten Wert von jedem Datensatz und dem ersten der nächsten.

Fehle ich etwas offensichtlich hier? Ich habe versucht, die Daten mit self.request.body, self.request.body_file und self.request.POST zu laden, und keiner scheint zu arbeiten. Ich habe auch versucht, die Content-Type Werte text/csv, text/plain, application/csv in den Anforderungsheadern, ohne Erfolg anzuwenden. Sollte ich einen anderen Content-Type hinzufügen?

Antwort

1

Sie verwenden die falsche Befehlszeilenoption curl, um Ihre Dateidaten zu senden, und es ist diese Option, die die Zeilenumbrüche entfernt.

Die -d Option analysiert Ihre Daten aus und sendet eine application/x-www-form-urlencoded Anfrage, und es Streifen Newlines. Von dem curl manpage:

-d, --data <data>

[...]

Wenn Sie die Daten mit dem Buchstaben @ beginnen, sollte der Rest ein Dateiname sein, die Daten aus zu lesen, oder - Wenn Sie möchten, dass curl die Daten von stdin liest. Mehrere Dateien können ebenfalls angegeben werden. Das Übertragen von Daten aus einer Datei mit dem Namen 'foobar' würde somit mit --data @foobar erfolgen. Wenn --data aufgefordert wird, aus einer Datei wie diesem zu lesen, werden Zeilenumbrüche und Zeilenumbrüche entfernt.

Fett Hervorhebung meins.

Verwenden Sie die Option --data-binary statt:

--data-binary <data>

(HTTP) Diese Beiträge Daten genau so, wie auch immer ohne zusätzliche Bearbeitung angegeben.

Wenn Sie die Daten mit dem Buchstaben @ starten, sollte der Rest ein Dateiname sein. Daten werden auf ähnliche Weise wie --data-ascii does, geschrieben, außer dass Zeilenumbrüche und Zeilenumbrüche beibehalten werden und keine Konvertierungen vorgenommen werden.

Sie kann wollen eine Content-Type Header in diesem Fall aufzunehmen; Das hängt natürlich von Ihrem Handler ab, wenn Sie sich für diesen Header interessieren.

+0

Danke! Ich versuchte es mit '--data-binary' und es funktionierte wie ein Zauber. – JOT