add bandwidth to a file download in python

Another short code snippet I came up when writing the module download script

The following class keeps a download under a certain ratio and prints live download stats (KB/s).

PYTHON:
  1. class BandwidthFile:
  2.     """
  3.     limits the file download to a certain amount of bytes per second and prints download stats
  4.     """
  5.     def __init__(self, filename, filesize, bytes_per_second = 20000, mode = "wb"):
  6.         self.fp = open(filename, "wb")
  7.         self.bytecounter = 0
  8.         self.started = datetime.datetime.now()
  9.         self.bytes_per_second = bytes_per_second
  10.         self.filesize = filesize
  11.         self.filename = filename
  12.  
  13.     def __del__(self):
  14.         self.fp.close()
  15.    
  16.     def write(self, bytestring):
  17.         self.bytecounter += len(bytestring)
  18.         seconds_since_started = (datetime.datetime.now() - self.started).seconds + 1
  19.         while (self.bytecounter / seconds_since_started)> self.bytes_per_second:
  20.             seconds_since_started = (datetime.datetime.now() - self.started).seconds + 1
  21.             time.sleep(0.1)
  22.         self.fp.write(bytestring)
  23.         sys.stdout.write("\rdownloading %s (%i/%i KB, %i KB/s)" % (self.filename, (self.bytecounter / 1024), (int(self.filesize) / 1024), (self.bytecounter /seconds_since_started / 1024)))
  24.         sys.stdout.flush()

To use the class with ftp:

PYTHON:
  1. from ftplib import FTP
  2. ftp = FTP("ftp.modland.com")
  3. filesize = ftp.size(remote_filename)
  4. f = BandwidthFile(local_filename, ftp_filesize)
  5. ftp.retrbinary('RETR '+remote_filename, f.write)

The status line looks like this:

downloading /home/phred/modules/Skaven/beyond the network.it (95/4411 KB, 19 KB/s)

If you have suggestions how to enhance the code snippet feel free to leave a comment!

Leave a Reply