Skip to content

Commit 5bd99ec

Browse files
committed
add progressbar for cacheless download
1 parent bf46940 commit 5bd99ec

File tree

1 file changed

+42
-11
lines changed
  • bioimageio/spec/_internal

1 file changed

+42
-11
lines changed

bioimageio/spec/_internal/io.py

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
model_validator,
4848
)
4949
from pydantic_core import core_schema
50+
from tqdm import tqdm
5051
from typing_extensions import (
5152
Annotated,
5253
LiteralString,
@@ -725,10 +726,16 @@ def resolve(
725726
if settings.user_agent is not None:
726727
headers["User-Agent"] = settings.user_agent
727728

728-
if settings.cache_path and not get_validation_context().disable_cache:
729+
chunk_size = 1024
730+
if (
731+
settings.cache_path
732+
and not get_validation_context().disable_cache
733+
and any(v is not None for v in kwargs.values())
734+
):
729735
downloader = pooch.HTTPDownloader(
730736
headers=headers,
731737
progressbar=progressbar, # pyright: ignore[reportArgumentType]
738+
chunk_size=chunk_size,
732739
)
733740
fname = _get_unique_file_name(source)
734741
_ls: Any = pooch.retrieve(
@@ -746,23 +753,47 @@ def resolve(
746753
)
747754
else:
748755
# cacheless download to memory using an in memory zip file
749-
r = requests.get(str(source))
756+
r = requests.get(str(source), stream=True)
750757
r.raise_for_status()
751-
if not isinstance(r.content, bytes):
752-
raise TypeError(
753-
f"Request content of {source} has unexpected type {type(r.content)}."
754-
)
755758

756759
zf = zipfile.ZipFile(io.BytesIO(), "w")
757760
fn = extract_file_name(source)
758-
# alternative implementation; TODO: remove commented code
759-
# zf.writestr(fn, r.content)
760-
# zp = ZipPath(zf) / fn
761-
# assert zp.exists(), f"failed to write {fn} to in-memory zip file"
761+
total = int(r.headers.get("content-length", 0))
762+
763+
if isinstance(progressbar, bool):
764+
if progressbar:
765+
use_ascii = bool(sys.platform == "win32")
766+
pbar = tqdm(
767+
total=total,
768+
ncols=79,
769+
ascii=use_ascii,
770+
unit="B",
771+
unit_scale=True,
772+
leave=True,
773+
)
774+
pbar = tqdm(desc=f"Downloading {fn}")
775+
else:
776+
pbar = None
777+
else:
778+
pbar = progressbar
779+
762780
zp = ZipPath(zf, fn)
763781
with zp.open("wb") as z:
764782
assert not isinstance(z, io.TextIOWrapper)
765-
_ = z.write(r.content)
783+
for chunk in r.iter_content(chunk_size=chunk_size):
784+
n = z.write(chunk)
785+
if pbar is not None:
786+
_ = pbar.update(n)
787+
788+
# Make sure the progress bar gets filled even if the actual number
789+
# is chunks is smaller than expected. This happens when streaming
790+
# text files that are compressed by the server when sending (gzip).
791+
# Binary files don't experience this.
792+
# (adapted from pooch.HttpDownloader)
793+
if pbar is not None:
794+
pbar.reset()
795+
_ = pbar.update(total)
796+
pbar.close()
766797

767798
return FileInZip(
768799
path=zp,

0 commit comments

Comments
 (0)