(This question is not about transparent decompression of gzip
-encoded responses from a web server; I know that requests
handles that automatically.)
Problem
I'm trying to POST a file to a RESTful web service. Obviously, requests
makes this pretty easy to do:
files = dict(data=(fn, file))
response = session.post(endpoint_url, files=files)
In this case, my file is in a really highly-compressible format (yep, XML) so I'd like to make sure that the request body is compressed.
The server claims to accept gzip encoding (Accept-Encoding: gzip
in response headers), so I should be able to gzip the whole body request body, right?
Attempted solution
Here's my attempt to make this work: I first construct the request and prepare it, then I go into the PreparedRequest
object, yank out the body
, run it through gzip
, and put it back. (Oh, and don't forget to update the Content-Length
and Content-Encoding
headers.)
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)
Unfortunately, the server is not cooperating and returns 500 Internal Server Error
. Perhaps it doesn't really accept gzip
-encoded requests?
Or perhaps there is a mistake in my approach? It seems rather convoluted. Is there an easier way to do request body compression with python-requests
?
EDIT: Fixed (3) and (5) from @sigmavirus24's answer (these were basically just artifacts I'd overlooked in simplifying the code to post it here).