class_docstr: Wraps the base_plugin.TBContext to stores additional data shared across
  API handlers for the HParams plugin backend.
  
  Before adding fields to this class, carefully consider whether the
  field truly needs to be accessible to all API handlers or if it
  can be passed separately to the handler constructor. We want to
  avoid this class becoming a magic container of variables that have
  no better place. See http://wiki.c2.com/?MagicContainer
class_docstr_tok: ["Wraps","the","base_plugin.TBContext","to","stores","additional","data","shared","across","API","handlers","for","the","HParams","plugin","backend",".","Before","adding","fields","to","this","class",",","carefully","consider","whether","the","field","truly","needs","to","be","accessible","to","all","API","handlers","or","if","it","can","be","passed","separately","to","the","handler","constructor",".","We","want","to","avoid","this","class","becoming","a","magic","container","of","variables","that","have","no","better","place",".","See","http",":","\/\/wiki.c2.com\/","?","MagicContainer"]
docstr: Computes the list of metric names from all the scalar (run, tag)
  pairs.
  
  The return value is a list of (tag, group) pairs representing the metric
  names. The list is sorted in Python tuple-order (lexicographical).
  
  For example, if the scalar (run, tag) pairs are:
  ("exp/session1", "loss")
  ("exp/session2", "loss")
  ("exp/session2/eval", "loss")
  ("exp/session2/validation", "accuracy")
  ("exp/no-session", "loss_2"),
  and the runs corresponding to sessions are "exp/session1", "exp/session2",
  this method will return [("loss", ""), ("loss", "/eval"), ("accuracy",
  "/validation")]
  
  More precisely, each scalar (run, tag) pair is converted to a (tag, group)
  metric name, where group is the suffix of run formed by removing the
  longest prefix which is a session run. If no session run is a prefix of
  'run', the pair is skipped.
  
  Returns:
    A python list containing pairs. Each pair is a (tag, group) pair
    representing a metric name used in some session.
docstr_tok: ["Computes","the","list","of","metric","names","from","all","the","scalar","(","run",",","tag",")","pairs",".","The","return","value","is","a","list","of","(","tag",",","group",")","pairs","representing","the","metric","names",".","The","list","is","sorted","in","Python","tuple-order","(","lexicographical",")",".","For","example",",","if","the","scalar","(","run",",","tag",")","pairs","are",":","(","``","exp\/session1","''",",","``","loss","''",")","(","``","exp\/session2","''",",","``","loss","''",")","(","``","exp\/session2\/eval","''",",","``","loss","''",")","(","``","exp\/session2\/validation","''",",","``","accuracy","''",")","(","``","exp\/no-session","''",",","``","loss_2","''",")",",","and","the","runs","corresponding","to","sessions","are","``","exp\/session1","''",",","``","exp\/session2","''",",","this","method","will","return","[","(","``","loss","''",",","``","''",")",",","(","``","loss","''",",","``","\/eval","''",")",",","(","``","accuracy","''",",","''","\/validation","''",")","]","More","precisely",",","each","scalar","(","run",",","tag",")","pair","is","converted","to","a","(","tag",",","group",")","metric","name",",","where","group","is","the","suffix","of","run","formed","by","removing","the","longest","prefix","which","is","a","session","run",".","If","no","session","run","is","a","prefix","of","'run","'",",","the","pair","is","skipped",".","Returns",":","A","python","list","containing","pairs",".","Each","pair","is","a","(","tag",",","group",")","pair","representing","a","metric","name","used","in","some","session","."]
code: def _compute_metric_names(self, ctx, experiment_id, session_runs):
      """Computes the list of metric names from all the scalar (run, tag)
      pairs.
  
      The return value is a list of (tag, group) pairs representing the metric
      names. The list is sorted in Python tuple-order (lexicographical).
  
      For example, if the scalar (run, tag) pairs are:
      ("exp/session1", "loss")
      ("exp/session2", "loss")
      ("exp/session2/eval", "loss")
      ("exp/session2/validation", "accuracy")
      ("exp/no-session", "loss_2"),
      and the runs corresponding to sessions are "exp/session1", "exp/session2",
      this method will return [("loss", ""), ("loss", "/eval"), ("accuracy",
      "/validation")]
  
      More precisely, each scalar (run, tag) pair is converted to a (tag, group)
      metric name, where group is the suffix of run formed by removing the
      longest prefix which is a session run. If no session run is a prefix of
      'run', the pair is skipped.
  
      Returns:
        A python list containing pairs. Each pair is a (tag, group) pair
        representing a metric name used in some session.
      """
      metric_names_set = set()
      scalars_run_to_tag_to_content = self.scalars_metadata(
          ctx, experiment_id
      )
      for run, tags in scalars_run_to_tag_to_content.items():
          session = _find_longest_parent_path(session_runs, run)
          if session is None:
              continue
          group = os.path.relpath(run, session)
          # relpath() returns "." for the 'session' directory, we use an empty
          # string.
          if group == ".":
              group = ""
          metric_names_set.update((tag, group) for tag in tags)
      metric_names_list = list(metric_names_set)
      # Sort metrics for determinism.
      metric_names_list.sort()
      return metric_names_list
  
imports: import collections
  import os
  from tensorboard.data import provider
  from tensorboard.plugins.hparams import api_pb2
  from tensorboard.plugins.hparams import json_format_compat
  from tensorboard.plugins.hparams import metadata
  from google.protobuf import json_format
  from tensorboard.plugins.scalar import metadata
label_desc: Use image node_id 18 for calling the Context obj's underlying member method code with example usage: obj._compute_metric_names(ctx, experiment_id, session_runs) and returns: metric_names_list