code: def file_md5sum(filename):
      '''Calculate and returns an MD5 checksum for the specified file.  Any file
      errors (non-existent file, read error, etc.) are not handled here but should
      be caught where this method is called.
  
      :param filename: full path to the file for which a checksum should be calculated
      :returns: hex-digest formatted MD5 checksum as a string
      '''
      # duplicated from keep.common.utils
      # possibly at some point this should be moved to a common codebase/library
      md5 = hashlib.md5()
      with open(filename, 'rb') as filedata:
          for chunk in iter(lambda: filedata.read(128 * md5.block_size), b''):
              md5.update(chunk)
      return md5.hexdigest(f file_md5sum(filename):
      '''Calculate and returns an MD5 checksum for the specified file.  Any file
      errors (non-existent file, read error, etc.) are not handled here but should
      be caught where this method is called.
  
      :param filename: full path to the file for which a checksum should be calculated
      :returns: hex-digest formatted MD5 checksum as a string
      '''
      # duplicated from keep.common.utils
      # possibly at some point this should be moved to a common codebase/library
      md5 = hashlib.md5()
      with open(filename, 'rb') as filedata:
          for chunk in iter(lambda: filedata.read(128 * md5.block_size), b''):
              md5.update(chunk)
      return md5.hexdigest()
docs: Calculate and returns an MD5 checksum for the specified file.  Any file
      errors (non-existent file, read error, etc.) are not handled here but should
      be caught where this method is called.
  
      :param filename: full path to the file for which a checksum should be calculated
      :returns: hex-digest formatted MD5 checksum as a string