How to monitor progress of a HTTP POST file upload using Python

To upload file with progress monitor using Python you can you this simple code:
import requests
import io

class CancelledError(Exception):
    def __init__(self, msg):
        self.msg = msg
        Exception.__init__(self, msg)

    def __str__(self):
        return self.msg

    __repr__ = __str__

class BufferReader(io.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)
        io.BytesIO.__init__(self, buf)

    def __len__(self):
        return self._len

    def read(self, n=-1):
        chunk = io.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 progress(size=None, progress=None):
    print("{0} / {1}".format(size, progress))


files = {"myFileUpl": ("Anti Speed Camera Map with Sound v2.0 ENGLISH.rar", open("c:/Users/ArtUrlWWW/Downloads/Anti Speed Camera Map with Sound v2.0 ENGLISH.rar", 'rb').read())}

(data, ctype) = requests.packages.urllib3.filepost.encode_multipart_formdata(files)

headers = {
    "Content-Type": ctype
}

url = 'http://upl.myjino.ru/upl.php'

body = BufferReader(data, progress)
r = requests.post(url, data=body, headers=headers)

print(r.text)

### Commented code - is code for simple file upload

# url = 'http://upl.myjino.ru/upl.php'
# files = {'myFileUpl': open('c:/Users/ArtUrlWWW/Downloads/28_PF-o.pdf', 'rb')}
# files = {'myFileUpl': open('c:/Users/ArtUrlWWW/Downloads/MPDF_6_0.pdf', 'rb')}
# files = {'myFileUpl': open('c:/Users/ArtUrlWWW/Downloads/MyBot-release-MBR_6.1.4.zip', 'rb')}
# files = {'myFileUpl': open('c:/Users/ArtUrlWWW/Downloads/Anti Speed Camera Map with Sound v2.0 ENGLISH.rar', 'rb')}
# files = {'myFileUpl': open('c:/Users/ArtUrlWWW/Downloads/ESP-01.pdf', 'rb')}
# r = requests.post(url, files=files)

# print(r.text)
This code uses requests, that you can install using pip:
pip install requests
For server side I use PHP code like 
<?php
   if(isset($_FILES['myFileUpl'])){
      $errors= array();
      $file_name = $_FILES['myFileUpl']['name'];
      $file_size =$_FILES['myFileUpl']['size'];
      $file_tmp =$_FILES['myFileUpl']['tmp_name'];
      $file_type=$_FILES['myFileUpl']['type'];
      $file_ext=strtolower(end(explode('.',$_FILES['myFileUpl']['name'])));
      
      // $expensions= array("jpeg","jpg","png");
      
      // if(in_array($file_ext,$expensions)=== false){
         // $errors[]="extension not allowed, please choose a JPEG or PNG file.";
      // }
      
      // if($file_size > 2097152){
         // $errors[]='File size must be excately 2 MB';
      // }
      
      if(empty($errors)==true){
         move_uploaded_file($file_tmp,"uploads/".$file_name);
         echo "Success";
      }else{
         print_r($errors);
      }
   }