tqdm/examples/tqdm_wget.py

111 lines
3.4 KiB
Python
Raw Normal View History

2020-05-02 22:55:04 +00:00
"""An example of wrapping manual tqdm updates for `urllib` reporthook.
See also: tqdm_requests.py.
2020-05-02 22:55:04 +00:00
# `urllib.urlretrieve` documentation
> If present, the hook function will be called once
> on establishment of the network connection and once after each block read
> thereafter. The hook will be passed three arguments; a count of blocks
> transferred so far, a block size in bytes, and the total size of the file.
Usage:
tqdm_wget.py [options]
Options:
-h, --help
Print this help message and exit
-u URL, --url URL : string, optional
The url to fetch.
2017-05-28 22:43:13 +00:00
[default: https://caspersci.uk.to/matryoshka.zip]
-o FILE, --output FILE : string, optional
The local file path in which to save the url [default: /dev/null].
"""
2017-05-28 22:43:13 +00:00
from os import devnull
2023-03-03 15:43:42 +00:00
from urllib import request as urllib
2020-05-02 22:55:04 +00:00
from docopt import docopt
2021-01-09 17:00:18 +00:00
2020-05-02 22:55:04 +00:00
from tqdm.auto import tqdm
def my_hook(t):
"""Wraps tqdm instance.
Don't forget to close() or __exit__()
the tqdm instance once you're done with it (easiest using `with` syntax).
Example
-------
>>> with tqdm(...) as t:
... reporthook = my_hook(t)
... urllib.urlretrieve(..., reporthook=reporthook)
"""
last_b = [0]
def update_to(b=1, bsize=1, tsize=None):
"""
b : int, optional
Number of blocks transferred so far [default: 1].
bsize : int, optional
Size of each block (in tqdm units) [default: 1].
tsize : int, optional
Total size (in tqdm units). If [default: None] or -1,
remains unchanged.
"""
if tsize not in (None, -1):
t.total = tsize
displayed = t.update((b - last_b[0]) * bsize)
last_b[0] = b
return displayed
2017-08-28 11:42:38 +00:00
return update_to
class TqdmUpTo(tqdm):
"""Alternative Class-based version of the above.
Provides `update_to(n)` which uses `tqdm.update(delta_n)`.
Inspired by [twine#242](https://github.com/pypa/twine/pull/242),
[here](https://github.com/pypa/twine/commit/42e55e06).
"""
2017-08-28 11:42:38 +00:00
def update_to(self, b=1, bsize=1, tsize=None):
"""
b : int, optional
Number of blocks transferred so far [default: 1].
bsize : int, optional
Size of each block (in tqdm units) [default: 1].
tsize : int, optional
Total size (in tqdm units). If [default: None] remains unchanged.
"""
if tsize is not None:
self.total = tsize
return self.update(b * bsize - self.n) # also sets self.n = b * bsize
opts = docopt(__doc__)
eg_link = opts['--url']
eg_file = eg_link.replace('/', ' ').split()[-1]
2017-05-28 22:43:13 +00:00
eg_out = opts['--output'].replace("/dev/null", devnull)
# with tqdm(unit='B', unit_scale=True, unit_divisor=1024, miniters=1,
# desc=eg_file) as t: # all optional kwargs
# urllib.urlretrieve(eg_link, filename=eg_out,
# reporthook=my_hook(t), data=None)
with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, miniters=1,
desc=eg_file) as t: # all optional kwargs
2021-02-17 16:03:15 +00:00
urllib.urlretrieve( # nosec
eg_link, filename=eg_out, reporthook=t.update_to, data=None)
2020-05-02 22:55:04 +00:00
t.total = t.n
2019-11-30 23:53:53 +00:00
# Even simpler progress by wrapping the output file's `write()`
2021-02-17 16:03:15 +00:00
response = urllib.urlopen(eg_link) # nosec
2019-11-30 23:53:53 +00:00
with tqdm.wrapattr(open(eg_out, "wb"), "write",
2021-02-10 20:23:35 +00:00
miniters=1, desc=eg_file,
total=getattr(response, 'length', None)) as fout:
for chunk in response:
2019-11-30 23:53:53 +00:00
fout.write(chunk)