code: def get_hash_and_size(
      obj,
      retries=5,
      algorithm="sha1",
      cache=None,
      save_path=None,
      verify_ssl=True,
  ):
      """Fetch sha1 hash of all urls in the input obj"""
  
      def _get_hash_and_size(
          obj, retries, algorithm, cache=None, save_path=None
      ):
          if isinstance(obj, str):
              if obj.startswith("http://") or obj.startswith(
                  "https://"
              ):
                  url = obj
                  hex_hash = None
                  file_size = None
                  if cache is not None and obj in cache:
                      return obj, cache[obj]
                  while retries + 1 > 0:
                      # Disable pyling too broad Exception
                      # pylint: disable=W0703
                      try:
                          if algorithm == "sha1":
                              m = hashlib.sha1()
                          elif algorithm == "sha256":
                              m = hashlib.sha256()
                          elif algorithm == "md5":
                              m = hashlib.md5()
                          else:
                              raise NotImplementedError
                          print(
                              "Calculating hash of the file downloaded from {}...".format(
                                  url
                              )
                          )
                          start = time.time()
                          r = requests.get(
                              url, stream=True, verify=verify_ssl
                          )
                          if r.status_code != 200:
                              raise RuntimeError(
                                  "Failed downloading url {}".format(
                                      url
                                  )
                              )
                          f_size = 0
                          for chunk in r.iter_content(chunk_size=10240):
                              if (
                                  chunk
                              ):  # filter out keep-alive new chunks
                                  m.update(chunk)
                                  f_size += len(chunk)
                          hex_hash = m.hexdigest()
                          file_size = f_size
                          end = time.time()
                          print(
                              "{}={}, size={}, Time spent={}".format(
                                  algorithm,
                                  hex_hash,
                                  file_size,
                                  end - start,
                              )
                          )
                          if cache is None:
                              cache = OrderedDict()
                          cache[url] = (hex_hash, file_size)
                          if save_path is not None:
                              with open(
                                  save_path, "a", encoding="utf-8"
                              ) as of:
                                  of.write(
                                      "{} {} {}\n".format(
                                          url, hex_hash, file_size
                                      )
                                  )
                          break
                      except Exception as e:
                          retries -= 1
                          if retries <= 0:
                              raise e
                          print(
                              "download failed due to {}, retrying, {} attempt{} left".format(
                                  repr(e),
                                  retries,
                                  "s" if retries > 1 else "",
                              )
                          )
                  return obj, (hex_hash, file_size)
              else:
                  return obj
          elif isinstance(obj, tuple):
              return tuple(
                  (
                      _get_hash_and_size(
                          ele, retries, algorithm, cache, save_path
                      )
                      for ele in obj
                  )
              )
          elif isinstance(obj, list):
              return [
                  _get_hash_and_size(
                      ele, retries, algorithm, cache, save_path
                  )
                  for ele in obj
              ]
          elif isinstance(obj, dict):
              return {
                  k: _get_hash_and_size(
                      v, retries, algorithm, cache, save_path
                  )
                  for k, v in obj.items()
              }
          else:
              return obj
  
      if cache is None:
          cache = OrderedDict()
      else:
          cache = copy.deepcopy(cache)
      if save_path is not None and os.path.exists(save_path):
          with open(save_path, "r", encoding="utf-8") as f:
              for line in f:
                  line = line.strip()
                  url, hex_hash, file_size = line.split()
                  cache[url] = (hex_hash, file_size)
      _get_hash_and_size(obj, retries, algorithm, cache, save_path)
      return obj, cache
  
file_path: gluon-nlp/src/gluonnlp/cli/data/update_download_stats.py
imports: import hashlib
  import requests
  import time
  import os
  import copy
  from collections import OrderedDict
  from gluonnlp.cli.data.machine_translation.prepare_wmt import _PARA_URLS, _MONOLINGUAL_URLS
  from gluonnlp.cli.data.question_answering.prepare_squad import _URLS
  from gluonnlp.cli.data.question_answering.prepare_triviaqa import _URLS
  from gluonnlp.cli.data.question_answering.prepare_hotpotqa import _URLS
  from gluonnlp.cli.data.question_answering.prepare_searchqa import _URLS
  from gluonnlp.cli.data.language_modeling.prepare_lm import _URLS
  from gluonnlp.cli.data.music_generation.prepare_music_midi import _URLS
  from gluonnlp.cli.data.pretrain_corpus.prepare_gutenberg import _URLS
  from gluonnlp.cli.data.general_nlp_benchmark.prepare_glue import SUPERGLUE_TASK2PATH
  from gluonnlp.cli.data.general_nlp_benchmark.prepare_glue import GLUE_TASK2PATH
  from gluonnlp.cli.data.general_nlp_benchmark.prepare_text_classification import TASK2PATH
label_desc: Use image node_id 1 for calling a global function with example usage: get_hash_and_size(obj, retries, algorithm, cache, save_path, verify_ssl) and returns: obj,  cache, obj,  hex_hash,  file_size, obj, tuple, obj,  cache, unknown, unknown, obj