Using tqdm or progress bars while downloading datasets using `urlretreve`

### Describe the workflow you want to enable

https://github.com/scikit-learn/scikit-learn/blob/4ca01961969a0c9e1c7c48410e0976bb04a92703/sklearn/datasets/_base.py#L1368-L1399

When we fetch remote data using the function `_fetch_remote`, we cannot verify that we are downloading it normally because there is no interaction action.

Depending on the download environment, it may take a long time, and users may think that there is an error in the program if they do not see it.

### Describe your proposed solution

I suggest that make an option to display the progress bar that we download using tqdm or other methods.

We can simply implement using [urlretreve reporthook parameter](https://docs.python.org/3/library/urllib.request.html#urllib.request.urlretrieve), Here are some example.

https://gist.github.com/leimao/37ff6e990b3226c2c9670a2cd1e4a6f5

### Describe alternatives you've considered, if relevant

_No response_

### Additional context

I've also suggest that adding more options: timeout, retrying.

COMMENT:
Your proposed solution of adding a progress bar using tqdm or other methods is a good idea. We can use the urlretrieve function's reporthook parameter to display the progress bar.

```
from urllib.request import urlretrieve
from tqdm import tqdm

def _fetch_remote(remote, dirname=None, show_progress=True):
    file_path = remote.filename if dirname is None else join(dirname, remote.filename)
    if show_progress:
        def _progress(count, block_size, total_size):
            progress_bar.update(block_size)
        progress_bar = tqdm(total=remote.size, unit='B', unit_scale=True)
        urlretrieve(remote.url, file_path, reporthook=_progress)
        progress_bar.close()
    else:
        urlretrieve(remote.url, file_path)
    checksum = _sha256(file_path)
    if remote.checksum != checksum:
        raise OSError(
            "{} has an SHA256 checksum ({}) "
            "differing from expected ({}), "
            "file may be corrupted.".format(file_path, checksum, remote.checksum)
        )
    return file_path
```
This implementation adds a show_progress parameter to the function, which defaults to True. If show_progress is True, it creates a tqdm progress bar with the total size of the remote file and updates it using the reporthook parameter of urlretrieve. If show_progress is False, it simply calls urlretrieve without a progress bar.

Regarding your suggestion of adding more options like timeout and retrying, those are good ideas as well. We can add those as additional parameters to the function and use them in the urlretrieve call.

```
from urllib.request import urlretrieve
from tqdm import tqdm

def _fetch_remote(remote, dirname=None, show_progress=True, timeout=None, num_retries=0):
    file_path = remote.filename if dirname is None else join(dirname, remote.filename)
    if show_progress:
        def _progress(count, block_size, total_size):
            progress_bar.update(block_size)
        progress_bar = tqdm(total=remote.size, unit='B', unit_scale=True)
        urlretrieve(remote.url, file_path, reporthook=_progress, timeout=timeout)
        progress_bar.close()
    else:
        urlretrieve(remote.url, file_path, timeout=timeout)
    checksum = _sha256(file_path)
    if remote.checksum != checksum:
        if num_retries > 0:
            return _fetch_remote(remote, dirname=dirname, show_progress=show_progress, timeout=timeout, num_retries=num_retries-1)
        else:
            raise OSError(
                "{} has an SHA256 checksum ({}) "
                "differing from expected ({}), "
                "file may be corrupted.".format(file_path, checksum, remote.checksum)
            )
    return file_path
```

This implementation adds timeout and num_retries parameters to the function. The timeout parameter is passed to urlretrieve to set a timeout for the download. The num_retries parameter specifies the number of times to retry the download if the checksum verification fails. If num_retries is greater than 0, it recursively calls _fetch_remote with num_retries decremented by 1.

Try this.

Labels: New Feature