code: def _dopost(url, params=None, payload=None, progress_cb=None):
      
      if params:
          encoded = urlencode(params)
      else:
          encoded = ''
  
      url = str(url + encoded)
  
      if payload is None:
          payload = ''
  
      # Try to make use of PyCURL if we have it
      try:
          c = pycurl.Curl()
      except NameError:
          c = None
  
      if c is not None:
          response = [ ]
          def append_to_response(buf):
              response.append(buf.decode())
  
          def progress(download_t, download_d, upload_t, upload_d):
              if progress_cb is not None:
                  progress_cb(upload_d, upload_t)
  
          c = pycurl.Curl()
          c.setopt(pycurl.URL, url)
          c.setopt(pycurl.POST, 1)
          c.setopt(pycurl.POSTFIELDS, payload)
          c.setopt(pycurl.INFILESIZE, len(payload))
          c.setopt(pycurl.WRITEFUNCTION, append_to_response)
          c.setopt(pycurl.NOPROGRESS, 0)
          c.setopt(pycurl.PROGRESSFUNCTION, progress)
          c.perform()
          c.close()
  
          return json.loads(''.join(response))
      else:
          if progress_cb is not None:
              progress_cb(0, len(payload))
          response = [x.decode() for x in urlopen(url, payload).readlines()]
          if progress_cb is not None:
              progress_cb(len(payload), len(payload))
          return json.loads(''.join(response))
docs: Do a HTTP post to upload some data. If progress_cb is not None, it
      should be a callable which takes two arguments: the total number of bytes
      to upload and the number of bytes which have been uploaded. The callable is
      called periodically to show the progress of the upload.