Skip to content

Instantly share code, notes, and snippets.

@ly0
Created February 5, 2014 08:55
Show Gist options
  • Save ly0/8819606 to your computer and use it in GitHub Desktop.
Save ly0/8819606 to your computer and use it in GitHub Desktop.
Making requests support stream file upload with a processbar
import requests
from io import BytesIO
import progressbar
class CancelledError(Exception):
def __init__(self, msg):
self.msg = msg
Exception.__init__(self, msg)
def __str__(self):
return self.msg
__repr__ = __str__
class BufferReader(BytesIO):
def __init__(self, buf=b'',
callback=None,
cb_args=(),
cb_kwargs={}):
self._callback = callback
self._cb_args = cb_args
self._cb_kwargs = cb_kwargs
self._progress = 0
self._len = len(buf)
BytesIO.__init__(self, buf)
def __len__(self):
return self._len
def read(self, n=-1):
chunk = BytesIO.read(self, n)
self._progress += int(len(chunk))
self._cb_kwargs.update({
'size' : self._len,
'progress': self._progress
})
if self._callback:
try:
self._callback(*self._cb_args, **self._cb_kwargs)
except: # catches exception from the callback
raise CancelledError('The upload was cancelled.')
return chunk
############################################################
def upload(files, callback):
url = 'ARBITRARY URL'
(gendata, ctype) = requests.packages.urllib3.filepost.encode_multipart_formdata(files)
headers = {
"Content-Type": ctype
}
body = BufferReader(gendata, callback)
response = requests.post(url, data=body, verify=False,headers=headers)
return response
############################################################
class ProgressBar():
def __init__(self):
self.first_call = True
self.finish = False
def __call__(self, *args, **kwargs):
if self.first_call:
self.widgets = [progressbar.Percentage(), ' ', progressbar.Bar(marker=progressbar.RotatingMarker('>')),
' ', progressbar.ETA()]
self.pbar = progressbar.ProgressBar(widgets=self.widgets, maxval=kwargs['size']).start()
self.first_call = False
self.pbar.update(kwargs['progress'])
if kwargs['size'] == kwargs['progress'] and self.finish:
self.pbar.finish()
self.finish = True
##############################################################
# MAIN
upload({'file':('filename','filecontent')},ProgressBar())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment