Komprimieren request-body mit python-requests?
(Diese Frage ist nicht über die transparente Dekompression gzip
-codiert Antworten von einem web-server; ich weiß, dass requests
Griffe, die automatisch.)
Problem
Ich versuche zu POSTEN eine Datei in einen RESTful web service. Offensichtlich requests
macht dies ziemlich einfach zu tun:
files = dict(data=(fn, file))
response = session.post(endpoint_url, files=files)
In diesem Fall, meine Datei ist in einem wirklich hoch komprimierbaren format (yep, XML), so würde ich mag, um sicherzustellen, dass die Anfrage Körper komprimiert wird.
Server Forderungen zu akzeptieren, gzip-Codierung (Accept-Encoding: gzip
im Antwort-Header), so dass ich in der Lage sein sollten, um gzip-der ganze Körper-request-body, richtig?
Versuchte Lösung
Hier ist mein Versuch, diese Arbeit zu machen: ich habe zunächst konstruieren Sie die Anfrage aus und bereiten Sie es, dann gehe ich in die PreparedRequest
Objekt, reißen sich die body
, führen Sie es durch gzip
, und setzen Sie Sie zurück. (Oh, und vergessen Sie nicht, aktualisieren Sie die Content-Length
und Content-Encoding
Header.)
files = dict(data=(fn, file))
request = request.Request('POST',endpoint_url, files=files)
prepped = session.prepare_request(request)
with NamedTemporaryFile(delete=True) as gzfile:
gzip.GzipFile(fileobj=gzfile, mode="wb").write(prepped.body)
prepped.headers['Content-Length'] = gzfile.tell()
prepped.headers['Content-Encoding'] = 'gzip'
gzfile.seek(0,0)
prepped.body = gzfile.read()
response = session.send(prepped)
Leider ist der server nicht zusammen und zurück 500 Internal Server Error
. Vielleicht ist es nicht wirklich akzeptieren gzip
-codierten Anforderungen?
Oder gibt es vielleicht einen Fehler in meinem Ansatz? Es scheint ziemlich verworren. Gibt es ein einfacher Weg, dies zu tun-request-body Kompression mit python-requests
?
EDIT: Fixiert (3) und (5) von @sigmavirus24 s Antwort (diese waren im Grunde nur Artefakte habe ich übersehen, bei der Vereinfachung der code, es hier zu posten).
- Anfrage Dekompression ist eher schlecht unterstützt von Webservern und aus Gründen der Sicherheit deaktiviert (vulnerability to gzip-Bomben). Für apache, die Sie brauchen, um es zu aktivieren mit mod_deflate. Sind Sie sicher, dass der server wirklich unterstützt?
Accept-Encoding
ist in der Regel nicht vom server gesendet, sondern der client. - Ich bin nicht wirklich sicher, dass der server unterstützt gzip ' ed Anfragen, keine. Es scheint widersprüchlich in seiner Werbung für diese Funktion. Das macht es viel härter, um herauszufinden, ob in dem versenden ist es eine vernünftige Anfrage...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin mir nicht sicher, wie Sie angekommen in Ihrem Ansatz, ehrlich gesagt, aber es ist sicherlich ein einfacher Weg, dies zu tun.
Erste, ein paar Dinge:
files
parameter erstellt einemultipart/form-data
Körper. Sie sind also etwas komprimieren, dass der server möglicherweise keine Ahnung.Content-Encoding
undTransfer-Encoding
sind zwei sehr verschiedene Dinge. Sie möchtenTransfer-Encoding
hier.NamedTemporaryFile
.multipart/form-data
Anfrage, gehe ich davon aus, dass Sie nicht wirklich wollen, das zu tun.session.Request
(was ich davon ausgehen sollte,requests.Request
) fehlt eine Methode, d.h., es sollte sein:requests.Request('POST', endpoint_url, ...)
Mit jenen aus dem Weg, hier ist, wie würde ich dies tun:
Unter der Annahme, dass
file
hat diexml
Inhalt in es und alles, was Sie bedeutete, war zu komprimieren, sollte dies für Sie arbeiten. Sie wahrscheinlich wollen eineContent-Type
Kopf-obwohl, zum Beispiel, würden Sie nur tun,Den
Transfer-Encoding
sagt dem server, dass die Anfrage wird komprimiert, nur im transit und sollte es Dekomprimieren Sie es. DieContent-Type
sagt dem server, wie behandeln die Inhalte einmal dieTransfer-Encoding
behandelt wurde.multipart/form-data
Körper: der Dienst benötigt, um zu akzeptieren, die Datei in unkomprimierter form. Du hast Recht, ich bin definitiv verwirrt über die Semantik vonContent-Encoding
im Gegensatz zuTransfer-Encoding
. Hier ist eine klarere Gespräche, die ich gefunden habe... eine bessere Erklärung gibt?multipart/form-data
weil ich dachte, dass die Wirkung vonContent-Encoding: gzip
wäre zu sagen, die server transparent gunzip gesamte request-body vor der Behandlung ist es in keiner Weise. Scheint so, das ist eine fehlerhafte Annahme?Transfer-Encoding
. Alternativ, wenn Sie nicht wollen, zu entführen die Anfrage Vorbereitung-Teil von Anfragen, können Sie das Anfragen-toolbelt zu generieren, die den Körper und die entsprechenden Header und dann die gzip-es mit der richtigen Transfer-Encoding.Hatte ich eine Frage, die markiert war, als ein exaktes Duplikat. Ich war concernd mit beiden enden der Transaktion.
Den code aus sigmavirus24 war nicht eine direkte Ausschneiden und einfügen-fix, aber es war die inspiration für diese version.
Hier ist, wie meine Lösung endete auf der Suche:
senden von der python-Ende
, die am äußern Ende
Gibt es eine gist hier mit Ausführlicher Protokollierung enthalten. Diese version hat keine Sicherheit oder Kontrolle in.