Safely (resume a) download to a file from http(s).

def _get_http(url, temp_file_name, initial_size, file_size, verbose_bool,
              progressbar, ncols=80):
    """Safely (resume a) download to a file from http(s)."""
    # Actually do the reading
    req = urllib.request.Request(url)
    if initial_size > 0:
        req.headers['Range'] = 'bytes=%s-' % (initial_size,)
    try:
        response = urllib.request.urlopen(req)
    except Exception:
        # There is a problem that may be due to resuming, some
        # servers may not support the "Range" header. Switch
        # back to complete download method
        tqdm.write('Resuming download failed (server '
                   'rejected the request). Attempting to '
                   'restart downloading the entire file.')
        del req.headers['Range']
        response = urllib.request.urlopen(req)
    total_size = int(response.headers.get('Content-Length', '1').strip())
    if initial_size > 0 and file_size == total_size:
        tqdm.write('Resuming download failed (resume file size '
                   'mismatch). Attempting to restart downloading the '
                   'entire file.')
        initial_size = 0
    total_size += initial_size
    if total_size != file_size:
        raise RuntimeError('URL could not be parsed properly')
    mode = 'ab' if initial_size > 0 else 'wb'
    if progressbar is True:
        progress = tqdm(total=total_size, initial=initial_size, desc='file_sizes',
                        ncols=ncols, unit='B', unit_scale=True)

    chunk_size = 8192  # 2 ** 13
    with open(temp_file_name, mode) as local_file:
        while True:
            t0 = time.time()
            chunk = response.read(chunk_size)
            dt = time.time() - t0
            if dt < 0.005:
                chunk_size *= 2
            elif dt > 0.1 and chunk_size > 8192:
                chunk_size = chunk_size // 2
            if not chunk:
                break
            local_file.write(chunk)
            if progressbar is True:
                progress.update(len(chunk))