code: def _fetch_training_jobs(
      session: boto3.Session,
      experiment: str,
      only_completed: bool,
      resolve_duplicates: bool,
  ) -> tuple[list[TrainingJob], list[TrainingJob]]:
      """
      Fetches all training jobs which are associated with this experiment.
      """
      client = session.client("sagemaker")
      search_params = {
          "MaxResults": 100,
          "Resource": "TrainingJob",
          "SearchExpression": {
              "Filters": [
                  {
                      "Name": "Tags.Experiment",
                      "Operator": "Equals",
                      "Value": experiment,
                  }
              ],
          },
      }
  
      while True:
          try:
              response = client.search(**search_params)
              break
          except ClientError:
              time.sleep(1)
  
      results = response["Results"]
      while "NextToken" in response:
          while True:
              try:
                  response = client.search(
                      NextToken=response["NextToken"], **search_params
                  )
                  results.extend(response["Results"])
                  break
              except ClientError:
                  time.sleep(1)
  
      jobs = [TrainingJob(r["TrainingJob"]) for r in results]
  
      if only_completed:
          completed_jobs = [j for j in jobs if j.status == "Completed"]
          if len(completed_jobs) < len(jobs):
              c = Counter([j.status for j in jobs])
              d = dict(c)
              del d["Completed"]
              logging.warning(
                  " Analysis is ignoring %d jobs %s",
                  len(jobs) - len(completed_jobs),
                  d,
              )
          jobs = completed_jobs
  
      duplicates = []
      if resolve_duplicates:
          unique = {}
          for job in jobs:
              hyperparameters = frozenset(job.hyperparameters.items())
              if hyperparameters in unique:
                  # Replace existing job if this one is newer. Don't do anything otherwise.
                  if (
                      unique[hyperparameters].date_created
                      < job.date_created
                  ):
                      duplicates.append(unique[hyperparameters])
                      unique[hyperparameters] = job
                  else:
                      duplicates.append(job)
              else:
                  unique[hyperparameters] = job
  
          if len(unique) < len(jobs):
              logging.warning(
                  " Analysis is ignoring %d superseded jobs",
                  len(jobs) - len(unique),
              )
          jobs = list(unique.values())
  
      return jobs, duplicates
  
imports: from __future__ import annotations
  import datetime
  import json
  import logging
  import re
  import shutil
  import tempfile
  import time
  from collections import Counter
  from functools import cached_property, lru_cache
  from pathlib import Path
  from typing import Any, Callable, cast, Dict, Iterator, List, Tuple, Union
  import boto3
  import numpy
  from botocore.exceptions import ClientError
  from .session import default_session
label_desc: Use image node_id 1 for calling a global function with example usage: _fetch_training_jobs(session, experiment, only_completed, resolve_duplicates) and returns: jobs,  duplicates