Repository: Project-MONAI/MONAI
File: monai/apps/utils.py (Python)

Code before:
DEFAULT_FMT = "%(asctime)s - %(levelname)s - %(message)s"
SUPPORTED_HASH_TYPES = {"md5": hashlib.md5, "sha1": hashlib.sha1, "sha256": hashlib.sha256, "sha512": hashlib.sha512}


def get_logger(
    module_name: str = "monai.apps",
    fmt: str = DEFAULT_FMT,
    datefmt: str | None = None,
    logger_handler: logging.Handler | None = None,
) -> logging.Logger:
    """
    Get a `module_name` logger with the specified format and date format.
    By default, the logger will print to `stdout` at the INFO level.
    - If `module_name` is None, the root logger is returned.
    - `fmt` and `datefmt` are passed to `logging.Formatter` for formatting.
    (https://docs.python.org/3/library/logging.html#formatter-objects).
    - If `logger_handler` is provided, it will be added to the logger.
    """
    # Retrieve or create a logger for the module
    logger = logging.getLogger(module_name)
    logger.setLevel(logging.INFO)

    # Check if stdout handler should be added (avoid adding multiple times)
    if module_name and module_name not in logging.root.manager.loggerDict:
        if fmt is not None or datefmt is not None:
            stdout_handler = next((h for h in logging.root.handlers if isinstance(h, logging.StreamHandler)), None)
            if stdout_handler:
                # Set the formatter if StreamHandler exists
                formatter = logging.Formatter(fmt=fmt, datefmt=datefmt)
                stdout_handler.setFormatter(formatter)

    # Add custom handler if provided
    if logger_handler is not None:
        logger.addHandler(logger_handler)
    return logger


# apps module-level default logger
logger = get_logger("monai.apps")
__all__.append("logger")


def _basename(p: PathLike) -> str:
    """get the last part of the path (removing the trailing slash if it exists)"""
    sep = os.path.sep + (os.path.altsep or "") + "/ "
    return Path(f"{p}".rstrip(sep)).name


def _download_with_progress(url: str, filepath: Path, progress: bool = True) -> None:
    """
    Retrieve file from `url` to `filepath`, optionally showing a progress bar.

Review comment (suggestion):
```suggestion
            stdout_handler = first(h for h in logging.root.handlers if isinstance(h, logging.StreamHandler))
```
`first` would also need to be imported: `from monai.utils import first`.

Code after:
DEFAULT_FMT = "%(asctime)s - %(levelname)s - %(message)s"
SUPPORTED_HASH_TYPES = {"md5": hashlib.md5, "sha1": hashlib.sha1, "sha256": hashlib.sha256, "sha512": hashlib.sha512}


def get_logger(
    module_name: str = "monai.apps",
    fmt: str = DEFAULT_FMT,
    datefmt: str | None = None,
    logger_handler: logging.Handler | None = None,
) -> logging.Logger:
    """
    Get a `module_name` logger with the specified format and date format.
    By default, the logger will print to `stdout` at the INFO level.
    If `module_name` is `None`, return the root logger.
    `fmt` and `datafmt` are passed to a `logging.Formatter` object
    (https://docs.python.org/3/library/logging.html#formatter-objects).
    `logger_handler` can be used to add an additional handler.
    """
    adds_stdout_handler = module_name is not None and module_name not in logging.root.manager.loggerDict
    logger = logging.getLogger(module_name)
    logger.propagate = False
    logger.setLevel(logging.INFO)
    if adds_stdout_handler:  # don't add multiple stdout or add to the root
        handler = logging.StreamHandler(sys.stdout)
        formatter = logging.Formatter(fmt=fmt, datefmt=datefmt)
        handler.setFormatter(formatter)
        logger.addHandler(handler)
    if logger_handler is not None:
        logger.addHandler(logger_handler)
    return logger


# apps module-level default logger
logger = get_logger("monai.apps")
__all__.append("logger")


def _basename(p: PathLike) -> str:
    """get the last part of the path (removing the trailing slash if it exists)"""
    sep = os.path.sep + (os.path.altsep or "") + "/ "
    return Path(f"{p}".rstrip(sep)).name


def _download_with_progress(url: str, filepath: Path, progress: bool = True) -> None:
    """
    Retrieve file from `url` to `filepath`, optionally showing a progress bar.
    """
    try:
        if has_tqdm and progress:

            class TqdmUpTo(tqdm):