code: def _build_resolver_graph(
      lineage_graph: metadata_store_pb2.LineageGraph,
      optional_event_filter: Optional[
          Callable[[metadata_store_pb2.Event], bool]
      ] = None,
  ) -> ResolverGraph:
      """Builds a resolver graph from a lineage graph.
  
      For example, if lineage_graph is:
      {
          artifacts: {
              id: 1
              # other fields
          }
          artifacts: {
              id: 2
              # other fields
          }
          executions: {
              id: 10
              # other fields
          }
          events: {
              artifact_id: 1
              execution_id: 10
              type: INPUT
          }
          events: {
              artifact_id: 2
              execution_id: 10
              type: OUTPUT
          }
      }
      The resolver graph returned will be:
      ResolverGraph(
          artifacts_by_id={
              1: Artifact(id=1, #other_fields),
              2: Artifact(id=2, #other_fields)
          },
          executions_by_id={
              10: Execution(id=10, #other_fields)
          },
          artifact_to_execution={
              EventType.INPUT: {1: [10]},
              EventType.OUTPUT: {2: [10]}},
          execution_to_artifact={
              EventType.INPUT: {10: [1]},
              EventType.OUTPUT: {10: [2]}
          }
      )
  
      Args:
        lineage_graph: lineage graph to build the resolver graph from.
        optional_event_filter: an optional callable object for filtering events in
          the paths. Only an event with `optional_event_filter(event)` evaluated to
          True will be considered as valid and kept in the path.
  
      Returns:
        A resolver graph dedicated for in-memory graph traversal.
      """
      resolver_graph = ResolverGraph()
  
      for event in lineage_graph.events:
          if (
              optional_event_filter is not None
              and not optional_event_filter(event)
          ):
              continue
          event_type = _get_resolver_event_type(event)
  
          resolver_graph.artifact_to_execution[event_type][
              event.artifact_id
          ].append(event.execution_id)
          resolver_graph.execution_to_artifact[event_type][
              event.execution_id
          ].append(event.artifact_id)
  
      for artifact in lineage_graph.artifacts:
          resolver_graph.artifacts_by_id[artifact.id] = artifact
      for execution in lineage_graph.executions:
          resolver_graph.executions_by_id[execution.id] = execution
      return resolver_graph
  
file_path: ml-metadata/ml_metadata/tools/mlmd_resolver/metadata_resolver_utils.py
imports: import collections
  import enum
  from typing import Callable, Dict, List, Optional, Set
  import attr
  from ml_metadata.proto import metadata_store_pb2
label_desc: Use image node_id 7 for calling a global function with example usage: _build_resolver_graph(lineage_graph, optional_event_filter) and returns: resolver_graph