Stream you content
==================

With Restkit you can easily stream your content to an from a server.

Stream to
---------

To stream a content to a server, pass to your request a file (or file-like object) or an iterator as `body`. If you use an iterator or a file-like object and Restkit can't determine its size (by reading `Content-Length` header or fetching the size of the file), sending will be chunked and Restkit add `Transfer-Encoding: chunked` header to the list of headers.

Here is a quick snippet with a file::

  from restkit import request

  with open("/some/file", "r") as f:
    request("/some/url", 'POST', body=f)

Here restkit will put the file size in `Content-Length` header.  Another example with an iterator::

  from restkit import request

  myiterator = ['line 1', 'line 2']
  request("/some/url", 'POST', body=myiterator)

Sending will be chunked. If you want to send without TE: chunked, you need to add the `Content-Length` header::

  request("/some/url", 'POST', body=myiterator,
      headers={'content-Length': 12})

Stream from
-----------

Each requests return a :class:`restkit.wrappers.Response` object. If you want to receive the content in a streaming fashion you just have to use the `body_stream` member of the response. You can `iter` on it or just use as a file-like object (read, readline, readlines, ...).

**Attention**: Since 2.0, response.body are just streamed and aren't persistent. In previous version, the implementation may cause problem with memory or storage usage.

Quick snippet with iteration::

  import os
  from restkit import request
  import tempfile

  r = request("http://e-engura.com/images/logo.gif")
  fd, fname = tempfile.mkstemp(suffix='.gif')

  with r.body_stream() as body:
    with os.fdopen(fd, "wb") as f:
      for block in body:
          f.write(block)

Or if you just want to read::

  with r.body_stream() as body:
    with os.fdopen(fd, "wb") as f:
      while True:
          data = body.read(1024)
          if not data:
              break
          f.write(data)

Tee input
---------

While with body_stream you can only consume the input until the end, you
may want to reuse this body later in your application. For that, restkit
since the 3.0 version offer the `tee` method. It copy response input to
standard output or a file if length > sock.MAX_BODY. When all the input
has been read, connection is released::

   from restkit import request
   import tempfile

   r = request("http://e-engura.com/images/logo.gif")
   fd, fname = tempfile.mkstemp(suffix='.gif')
   fd1, fname1 = tempfile.mkstemp(suffix='.gif')

   body = t.tee()
   # save first file
   with os.fdopen(fd, "wb") as f:
      for chunk in body: f.write(chunk)

   # reset
   body.seek(0)
   # save second file.
   with os.fdopen(fd1, "wb") as f:
      for chunk in body: f.write(chunk)


