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,
)
17 changes: 15 additions & 2 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 @@ -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 on lines +284 to 287
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update download_url Raises docs to HashMismatchError for hash mismatch.

The implementation now raises HashMismatchError, but the docstring still declares RuntimeError for this path.

Proposed patch
@@
-        RuntimeError: When the hash validation of the ``url`` downloaded file fails.
+        HashMismatchError: When the hash validation of the ``url`` downloaded file fails.

As per coding guidelines, "Docstrings should be present for all definition which describe each variable, return value, and raised exception in the appropriate section of the Google-style of docstrings."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@monai/apps/utils.py` around lines 283 - 286, The docstring for download_url
incorrectly lists RuntimeError for checksum failures; update the "Raises"
section to state HashMismatchError (the actual exception raised in the
implementation) and include a short description (e.g., when the downloaded
file's checksum does not match expected hash) so the docstring matches the
behavior of download_url and references HashMismatchError.

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 @@ -79,7 +79,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 @@ -171,6 +170,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 @@ -206,7 +207,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