class_docstr: Handles a ListSessionGroups request.
class_docstr_tok: ["Handles","a","ListSessionGroups","request","."]
docstr: Returns a list of SessionGroups protobuffers from the summary
  data.
code: def _build_session_groups(
      self, hparams_run_to_tag_to_content, metric_infos
  ):
      """Returns a list of SessionGroups protobuffers from the summary
      data."""
  
      # Algorithm: We keep a dict 'groups_by_name' mapping a SessionGroup name
      # (str) to a SessionGroup protobuffer. We traverse the runs associated with
      # the plugin--each representing a single session. We form a Session
      # protobuffer from each run and add it to the relevant SessionGroup object
      # in the 'groups_by_name' dict. We create the SessionGroup object, if this
      # is the first session of that group we encounter.
      groups_by_name = {}
      # The TensorBoard runs with session start info are the
      # "sessions", which are not necessarily the runs that actually
      # contain metrics (may be in subdirectories).
      session_names = [
          run
          for (run, tags) in hparams_run_to_tag_to_content.items()
          if metadata.SESSION_START_INFO_TAG in tags
      ]
      metric_runs = set()
      metric_tags = set()
      for session_name in session_names:
          for metric in metric_infos:
              metric_name = metric.name
              (run, tag) = metrics.run_tag_from_session_and_metric(
                  session_name, metric_name
              )
              metric_runs.add(run)
              metric_tags.add(tag)
      all_metric_evals = (
          self._backend_context.read_last_scalars(
              self._request_context,
              self._experiment_id,
              run_tag_filter=provider.RunTagFilter(
                  runs=metric_runs, tags=metric_tags
              ),
          )
          if self._include_metrics
          else {}
      )
      for (
          session_name,
          tag_to_content,
      ) in hparams_run_to_tag_to_content.items():
          if metadata.SESSION_START_INFO_TAG not in tag_to_content:
              continue
          start_info = metadata.parse_session_start_info_plugin_data(
              tag_to_content[metadata.SESSION_START_INFO_TAG]
          )
          end_info = None
          if metadata.SESSION_END_INFO_TAG in tag_to_content:
              end_info = metadata.parse_session_end_info_plugin_data(
                  tag_to_content[metadata.SESSION_END_INFO_TAG]
              )
          session = self._build_session(
              metric_infos,
              session_name,
              start_info,
              end_info,
              all_metric_evals,
          )
          if session.status in self._request.allowed_statuses:
              self._add_session(session, start_info, groups_by_name)
  
      # Compute the session group's aggregated metrics for each group.
      groups = groups_by_name.values()
      for group in groups:
          # We sort the sessions in a group so that the order is deterministic.
          group.sessions.sort(key=operator.attrgetter("name"))
          self._aggregate_metrics(group)
      return groups
  
imports: import collections
  import dataclasses
  import operator
  import re
  from typing import Optional
  from google.protobuf import struct_pb2
  from tensorboard.data import provider
  from tensorboard.plugins.hparams import api_pb2
  from tensorboard.plugins.hparams import backend_context
  from tensorboard.plugins.hparams import error
  from tensorboard.plugins.hparams import json_format_compat
  from tensorboard.plugins.hparams import metadata
  from tensorboard.plugins.hparams import metrics
  from tensorboard.plugins.hparams import plugin_data_pb2
label_desc: Use image node_id 5 for calling the Handler obj's underlying member method code with example usage: obj._build_session_groups(hparams_run_to_tag_to_content, metric_infos) and returns: groups