Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion monai/apps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,13 @@

from .datasets import CrossValidation, DecathlonDataset, MedNISTDataset, TciaDataset
from .mmars import MODEL_DESC, RemoteMMARKeys, download_mmar, get_model_spec, load_from_mmar
from .utils import SUPPORTED_HASH_TYPES, check_hash, download_and_extract, download_url, extractall, get_logger, logger
from .utils import (
SUPPORTED_HASH_TYPES,
HashMismatchError,
check_hash,
download_and_extract,
download_url,
extractall,
get_logger,
logger,
)
19 changes: 16 additions & 3 deletions monai/apps/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,20 @@
else:
tqdm, has_tqdm = optional_import("tqdm", "4.47.0", min_version, "tqdm")

__all__ = ["check_hash", "download_url", "extractall", "download_and_extract", "get_logger", "SUPPORTED_HASH_TYPES"]
__all__ = [
"check_hash",
"download_url",
"extractall",
"download_and_extract",
"get_logger",
"HashMismatchError",
"SUPPORTED_HASH_TYPES",
]


class HashMismatchError(RuntimeError):
"""Raised when the hash of a downloaded file does not match the expected value."""


DEFAULT_FMT = "%(asctime)s - %(levelname)s - %(message)s"
SUPPORTED_HASH_TYPES = {"md5": hashlib.md5, "sha1": hashlib.sha1, "sha256": hashlib.sha256, "sha512": hashlib.sha512}
Expand Down Expand Up @@ -213,7 +226,7 @@ def download_url(
https://github.com/wkentaro/gdown/blob/main/gdown/download.py

Raises:
RuntimeError: When the hash validation of the ``filepath`` existing file fails.
HashMismatchError: When the hash validation of the ``filepath`` existing file fails.
RuntimeError: When a network issue or denied permission prevents the
file download from ``url`` to ``filepath``.
URLError: See urllib.request.urlretrieve.
Expand Down Expand Up @@ -268,7 +281,7 @@ def download_url(
pass
logger.info(f"Downloaded: {filepath}")
if not check_hash(filepath, hash_val, hash_type):
raise RuntimeError(
raise HashMismatchError(
f"{hash_type} check of downloaded file failed: URL={url}, "
f"filepath={filepath}, expected {hash_type}={hash_val}."
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Expand Down
7 changes: 4 additions & 3 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
import torch
import torch.distributed as dist

from monai.apps.utils import download_url
from monai.apps.utils import HashMismatchError, download_url
from monai.config import NdarrayTensor
from monai.config.deviceconfig import USE_COMPILED
from monai.config.type_definitions import NdarrayOrTensor
Expand Down Expand Up @@ -81,7 +81,6 @@
"unexpected EOF", # incomplete download
"network issue",
"gdown dependency", # gdown not installed
"md5 check",
"limit", # HTTP Error 503: Egress is over the account limit
"authenticate",
"timed out", # urlopen error [Errno 110] Connection timed out
Expand Down Expand Up @@ -173,6 +172,8 @@ def skip_if_downloading_fails():

try:
yield
except HashMismatchError:
raise
except DOWNLOAD_EXCEPTS as e:
raise unittest.SkipTest(f"Error while downloading: {e}") from e
except ssl.SSLError as ssl_e:
Expand Down Expand Up @@ -208,7 +209,7 @@ def test_download_url(self):
hash_val=SAMPLE_TIFF_HASH,
hash_type=SAMPLE_TIFF_HASH_TYPE,
)
with self.assertRaises(RuntimeError):
with self.assertRaises(HashMismatchError):
download_url(
url=SAMPLE_TIFF,
filepath=os.path.join(tempdir, "model_bad.tiff"),
Expand Down
Loading