code: def _handle_artifacts(self, model, nemo_file_folder):
      tarfile_artifacts = []
      app_state = AppState()
  
      # aggregate artifacts from self and all children recursively
      artifacts_containers = []
      for _, config_path, module in model.named_nemo_modules():
          if module.has_artifacts():  # NeMo model with artifacts
              artifacts_containers.append(
                  (config_path, module.artifacts)
              )
  
      if len(artifacts_containers) > 0 and (
          not hasattr(model, "artifacts") or model.artifacts is None
      ):
          # model has no artifacts, but submodules have some
          model.artifacts = dict()
      for config_path, artifacts in artifacts_containers:
          for subconf_path, artiitem in artifacts.items():
              conf_path = (
                  f"{config_path}.{subconf_path}"
                  if config_path
                  else f"{subconf_path}"
              )
              if (
                  artiitem.path_type
                  == model_utils.ArtifactPathType.LOCAL_PATH
              ):
                  if not os.path.exists(artiitem.path):
                      raise FileNotFoundError(
                          f"Artifact {conf_path} not found at location: {artiitem.path}"
                      )
  
                  # Generate new uniq artifact name and copy it to nemo_file_folder
                  # Note uuid.uuid4().hex is guaranteed to be 32 character long
                  artifact_base_name = os.path.basename(artiitem.path)
                  artifact_uniq_name = (
                      f"{uuid.uuid4().hex}_{artifact_base_name}"
                  )
                  shutil.copy2(
                      artiitem.path,
                      os.path.join(
                          nemo_file_folder, artifact_uniq_name
                      ),
                  )
  
                  # Update artifacts registry
                  artiitem.hashed_path = "nemo:" + artifact_uniq_name
                  model.artifacts[conf_path] = artiitem
  
              elif (
                  artiitem.path_type
                  == model_utils.ArtifactPathType.TAR_PATH
              ):
                  # process all tarfile artifacts in one go, so preserve key-value pair
                  tarfile_artifacts.append((conf_path, artiitem))
                  if subconf_path:  # artifact from submodule
                      model.artifacts[conf_path] = artiitem
  
              else:
                  raise ValueError(
                      f"Directly referencing artifacts from other nemo files isn't supported yet"
                  )
  
      # Process current tarfile artifacts by unpacking the previous tarfile and extract the artifacts
      # that are currently required.
      # artifacts can be native (from the model itself) and from submodules
      restoration_paths: Set[
          str
      ] = (
          set()
      )  # model + submodules restoration paths, handle only unique paths
      model_metadata = app_state.get_model_metadata_from_guid(
          model.model_guid
      )
      if model_metadata.restoration_path is not None:
          restoration_paths.add(model_metadata.restoration_path)
      # aggregate restoration paths for all submodules recursively
      for module in model.modules():
          if isinstance(module, nemo_classes.ModelPT):  # if NeMo model
              submodule_restoration_path = (
                  app_state.get_model_metadata_from_guid(
                      module.model_guid
                  ).restoration_path
              )
              if submodule_restoration_path is not None:
                  restoration_paths.add(submodule_restoration_path)
      if len(tarfile_artifacts) > 0 and len(restoration_paths) == 0:
          # TODO: see cases when this can occur, and if we can fix them
          logging.warning(
              "Model contains registered artifacts, but no restoration paths found"
          )
      if len(tarfile_artifacts) > 0 and len(restoration_paths) > 0:
          # Need to step into nemo archive to extract file
          # Get path where the command is executed - the artifacts will be "retrieved" there
          # (original .nemo behavior)
          cwd = os.getcwd()
          # Step into the nemo archive to try and find the file
          # TemporaryDirectory context must always be outer to try-catch chdir otherwise it crashes on Windows
          with tempfile.TemporaryDirectory() as archive_dir:
              try:
                  # unpack all restorations paths (nemo checkpoints)
                  # in nemo checkpoints all resources contain hash in name, so there should be no collisions
                  for path in restoration_paths:
                      if self.model_extracted_dir:
                          shutil.copytree(
                              src=path,
                              dst=archive_dir,
                              dirs_exist_ok=True,
                          )
                      else:
                          self._unpack_nemo_file(
                              path2file=path, out_folder=archive_dir
                          )
                  os.chdir(archive_dir)
                  for conf_path, artiitem in tarfile_artifacts:
                      # Get basename and copy it to nemo_file_folder
                      if "nemo:" in artiitem.path:
                          artifact_base_name = artiitem.path.split(
                              "nemo:"
                          )[1]
                      else:
                          artifact_base_name = os.path.basename(
                              artiitem.path
                          )
                      # no need to hash here as we are in tarfile_artifacts which are already hashed
                      artifact_uniq_name = artifact_base_name
                      shutil.copy2(
                          artifact_base_name,
                          os.path.join(
                              nemo_file_folder, artifact_uniq_name
                          ),
                      )
  
                      # Update artifacts registry
                      new_artiitem = model_utils.ArtifactItem()
                      new_artiitem.path = "nemo:" + artifact_uniq_name
                      new_artiitem.path_type = (
                          model_utils.ArtifactPathType.TAR_PATH
                      )
                      model.artifacts[conf_path] = new_artiitem
              finally:
                  # change back working directory
                  os.chdir(cwd)
  
imports: from __future__ import annotations
  import os
  import shutil
  import tarfile
  import tempfile
  import uuid
  from typing import Optional, Set, Union
  import torch
  from omegaconf import DictConfig, OmegaConf
  from omegaconf.omegaconf import open_dict
  from pytorch_lightning.trainer.trainer import Trainer
  from nemo.core import classes
  from nemo.utils import logging, model_utils
  from nemo.utils.app_state import AppState
  from nemo.utils.get_rank import is_global_rank_zero
  from nemo.utils.model_utils import inject_model_parallel_rank
label_desc: Use image node_id 9 for calling the SaveRestoreConnector obj's underlying member method code with example usage: obj._handle_artifacts(model, nemo_file_folder) without return types