Welcome, guest | Sign In | My Account | Store | Cart
import cStringIO as StringIO
import os

class ReadCallbackStream(object):
   
"""Wraps a file-like object in another, but also calls a user
    callback with the number of bytes read whenever its `read()` method
    is called. Used for tracking upload progress, for example for a
    progress bar in a UI application. Idea taken from ActiveState Code Recipe:
    http://code.activestate.com/recipes/578669-wrap-a-string-in-a-file-like-object-that-calls-a-u/
    """

   
def __init__(self, file_like, callback):
       
self.file_like = file_like
       
self._callback = callback

   
def __len__(self):
       
raise NotImplementedError()

   
def read(self, *args):
        chunk
= self.file_like.read(*args)
       
if len(chunk) > 0:
           
self._callback(len(chunk))
       
return chunk

class ReadCallbackString(ReadCallbackStream):
   
def __init__(self, data, callback):
       
super(ReadCallbackString, self).__init__(StringIO.StringIO(data), callback)
       
self._len = len(data)

   
def __len__(self):
       
return self._len

class ReadCallbackFile(ReadCallbackStream):
   
def __init__(self, filename, callback):
       
super(ReadCallbackFile, self).__init__(open(filename), callback)

   
def __len__(self):
        curpos
= self.file_like.tell()
       
self.file_like.seek(0, os.SEEK_END)
        file_length
= self.file_like.tell() - curpos
       
self.file_like.seek(curpos, os.SEEK_SET)
       
return file_length


if __name__ == '__main__':
   
import json
   
import urllib2

   
def callback(num_bytes_read):
       
print 'callback:', num_bytes_read, 'bytes read'

    data
= 'x' * 20000
    stream
= ReadCallbackString(data, callback)
    request
= urllib2.Request('http://httpbin.org/post', stream)
    f
= urllib2.urlopen(request)
    response
= json.loads(f.read())
   
print 'httpbin.org said we POSTed', len(response['data']), 'bytes'

   
# create a real file and repeat process
   
print
    filename
= 'testfile'
   
with open(filename, 'w') as testfile:
        testfile
.write(data)

    stream
= ReadCallbackFile(filename, callback)
    request
= urllib2.Request('http://httpbin.org/post', stream)
    f
= urllib2.urlopen(request)
    response
= json.loads(f.read())
   
print 'httpbin.org said we POSTed', len(response['data']), 'bytes'

History