from typing import BinaryIO
from typing import Callable
import hashlib


def hash_file_hex(f: BinaryIO, algorithm: Callable = hashlib.blake2b, block_size: int = 65536) -> str:
    """Get the hex digest of the hash of a file.

    Args:
        f (os.pathlike, str): Readable binary file-like object to hash.
        algorithm (:obj:`object`, optional): The hash algorithm object
            to use. This should have an `update` method. Defaults to
            `hashlib.blake2b`.
        block_size (:obj:`int`, optional): The amount of bytes to read
            into memory at once. This should be a multiple of the hash
            algorithm's block size. Defaults to 65536.

    Returns:
        str: The hex digest of the hash.
    """
    hash_ = algorithm()
    while True:
        buf = f.read(block_size)
        if not buf:
            break
        hash_.update(buf)
    return hash_.hexdigest()