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