code: def fetch_files(
      data_dir, files, resume=True, verbose=1, session=None
  ):
      """Load requested dataset, downloading it if needed or requested.
  
      This function retrieves files from the hard drive or download them from
      the given urls. Note to developers: All the files will be first
      downloaded in a sandbox and, if everything goes well, they will be moved
      into the folder of the dataset. This prevents corrupting previously
      downloaded data. In case of a big dataset, do not hesitate to make several
      calls if needed.
  
      Parameters
      ----------
      %(data_dir)s
      files : list of (string, string, dict)
          List of files and their corresponding url with dictionary that contains
          options regarding the files. Eg. (file_path, url, opt). If a file_path
          is not found in data_dir, as in data_dir/file_path the download will
          be immediately cancelled and any downloaded files will be deleted.
          Options supported are:
              * 'move' if renaming the file or moving it to a subfolder is needed
              * 'uncompress' to indicate that the file is an archive
              * 'md5sum' to check the md5 sum of the file
              * 'overwrite' if the file should be re-downloaded even if it exists
      %(resume)s
      %(verbose)s
      session : `requests.Session`, optional
          Session to use to send requests.
  
      Returns
      -------
      files : list of string
          Absolute paths of downloaded files on disk.
  
      """
      if session is None:
          with requests.Session() as session:
              session.mount("ftp:", _NaiveFTPAdapter())
              return fetch_files(
                  data_dir,
                  files,
                  resume=resume,
                  verbose=verbose,
                  session=session,
              )
      # There are two working directories here:
      # - data_dir is the destination directory of the dataset
      # - temp_dir is a temporary directory dedicated to this fetching call. All
      #   files that must be downloaded will be in this directory. If a corrupted
      #   file is found, or a file is missing, this working directory will be
      #   deleted.
      files = list(files)
      files_pickle = pickle.dumps(
          [(file_, url) for file_, url, _ in files]
      )
      files_md5 = hashlib.md5(files_pickle).hexdigest()
      temp_dir = os.path.join(data_dir, files_md5)
  
      # Create destination dir
      if not os.path.exists(data_dir):
          os.makedirs(data_dir)
  
      # Abortion flag, in case of error
      abort = None
  
      files_ = []
      for file_, url, opts in files:
          # 3 possibilities:
          # - the file exists in data_dir, nothing to do.
          # - the file does not exists: we download it in temp_dir
          # - the file exists in temp_dir: this can happen if an archive has been
          #   downloaded. There is nothing to do
  
          # Target file in the data_dir
          target_file = os.path.join(data_dir, file_)
          # Target file in temp dir
          temp_target_file = os.path.join(temp_dir, file_)
          # Whether to keep existing files
          overwrite = opts.get("overwrite", False)
          if abort is None and (
              overwrite
              or (
                  not os.path.exists(target_file)
                  and not os.path.exists(temp_target_file)
              )
          ):
              # We may be in a global read-only repository. If so, we cannot
              # download files.
              if not os.access(data_dir, os.W_OK):
                  raise ValueError(
                      "Dataset files are missing but dataset"
                      " repository is read-only. Contact your data"
                      " administrator to solve the problem"
                  )
  
              if not os.path.exists(temp_dir):
                  os.mkdir(temp_dir)
              md5sum = opts.get("md5sum", None)
  
              dl_file = fetch_single_file(
                  url,
                  temp_dir,
                  resume=resume,
                  verbose=verbose,
                  md5sum=md5sum,
                  username=opts.get("username", None),
                  password=opts.get("password", None),
                  session=session,
                  overwrite=overwrite,
              )
              if "move" in opts:
                  # XXX: here, move is supposed to be a dir, it can be a name
                  move = os.path.join(temp_dir, opts["move"])
                  move_dir = os.path.dirname(move)
                  if not os.path.exists(move_dir):
                      os.makedirs(move_dir)
                  shutil.move(dl_file, move)
                  dl_file = move
              if "uncompress" in opts:
                  try:
                      uncompress_file(dl_file, verbose=verbose)
                  except Exception as e:
                      abort = str(e)
  
          if (
              abort is None
              and not os.path.exists(target_file)
              and not os.path.exists(temp_target_file)
          ):
              warnings.warn(f"An error occurred while fetching {file_}")
              abort = (
                  "Dataset has been downloaded but requested file was "
                  f"not provided:\nURL: {url}\n"
                  f"Target file: {target_file}\nDownloaded: {dl_file}"
              )
          if abort is not None:
              if os.path.exists(temp_dir):
                  shutil.rmtree(temp_dir)
              raise OSError(f"Fetching aborted: {abort}")
          files_.append(target_file)
      # If needed, move files from temps directory to final directory.
      if os.path.exists(temp_dir):
          # XXX We could only moved the files requested
          # XXX Movetree can go wrong
          movetree(temp_dir, data_dir)
          shutil.rmtree(temp_dir)
      return files_
  
imports: import collections.abc
  import contextlib
  import fnmatch
  import hashlib
  import os
  import pickle
  import shutil
  import sys
  import tarfile
  import time
  import urllib
  import warnings
  import zipfile
  from pathlib import Path
  import numpy
  import requests
  from .._utils import fill_doc
  from .utils import get_data_dirs
label_desc: Use image node_id 18 for calling a global function with example usage: fetch_files(data_dir, files, resume, verbose, session) and returns: files_, fetch_files