code: def get_jobs(run, session, repo):
      with shelve.open("test_report_jobs") as cache:
          url = run["jobs_url"]
          try:
              jobs = cache[url]
          except KeyError:
              params = {"per_page": 100}
              r = get_from_github(
                  run["jobs_url"], params, session=session
              )
              jobs = r.json()["jobs"]
              while next_page := maybe_get_next_page_path(r):
                  r = get_from_github(
                      next_page, params=params, session=session
                  )
                  jobs.extend(r.json()["jobs"])
              cache[url] = jobs
  
      df_jobs = pandas.DataFrame.from_records(jobs)
      # Interpolate the `$TEST_ID` variable from the job name.
      # Somehow the job ID is not part of the workflow schema and we have no other way to later join
      # this to the JXML results.
  
      if repo.endswith("/dask"):
          # example name: "test (windows-latest, 3.9)" or "test (ubuntu-latest, 3.12, dask-expr)"
          df_jobs = df_jobs[~df_jobs.name.str.contains("Event File")]
  
          def format(row):
              return ",".join(
                  (
                      row[1].strip(),
                      row[2].strip(),
                      (row[3] or "").strip(),
                  )
              )
  
          name_components = (
              df_jobs[df_jobs.name.str.startswith("test")]
              .name.str.replace("(", ",")
              .str.replace(")", ",")
              .str.split(",", expand=True)
              .apply(format, axis=1)
              .str.split(",", expand=True)
          )
  
          # See `Set $TEST_ID` step in `tests.yaml`
          name_components.columns = [
              "OS version",
              "environment",
              "option",
          ]
          df_jobs["suite_name"] = name_components.iloc[:, 0].str.cat(
              name_components.iloc[:, 1:], sep="-"
          )
          df_jobs["suite_name"] = df_jobs.suite_name.str.replace(
              "--", "-"
          )
      else:
          name_components = df_jobs.name.str.split(
              "-", expand=True
          ).dropna()
          if len(name_components.columns) != 5:
              raise ValueError(
                  f"Job names must have 5 components:\n{name_components!r}"
              )
          name_components.columns = [
              "OS",
              "OS version",
              "environment",
              "label",
              "partition",
          ]
  
          # See `Set $TEST_ID` step in `tests.yaml`
          name_components[
              "partition"
          ] = name_components.partition.str.replace(" ", "")
  
          df_jobs["suite_name"] = name_components.iloc[:, 0].str.cat(
              name_components.iloc[:, 1:], sep="-"
          )
      return df_jobs
  
imports: from __future__ import annotations
  import argparse
  import contextlib
  import html
  import io
  import os
  import re
  import shelve
  import sys
  import zipfile
  from collections.abc import Iterable, Iterator
  from concurrent.futures import ProcessPoolExecutor
  from typing import Any, cast
  import altair
  import altair_saver
  import junitparser
  import pandas
  import requests
  from requests.adapters import HTTPAdapter
  from urllib3.util.retry import Retry
label_desc: Use image node_id 5 for calling a global function with example usage: get_jobs(run, session, repo) and returns: df_jobs, str