code: def build_graph_from_outputs(
      outputs: Iterable[DataPlaceholder],
  ) -> DiGraph:
      """Builds a graph by backtracking from a sets of outputs.
  
      It does so by backtracking recursively in depth-first fashion, jumping
      from outputs to steps in tandem until hitting a step with no inputs (an
      InputStep).
  
      It builds the graph including the targets, i.e. the graph at fit time.
  
      Parameters
      ----------
      outputs
          Outputs (data placeholders) from where the backtrack to build the
          graph starts.
  
      Returns
      -------
      graph
          The built graph.
      """
      graph = DiGraph()
  
      # Add nodes (a node represents a step at a given port)
      def collect_nodes_from(output):
          parent_node = output.node
  
          if parent_node in graph:
              return
  
          graph.add_node(parent_node)
          for input in parent_node.inputs:
              collect_nodes_from(input)
          for target in parent_node.targets:
              collect_nodes_from(target)
  
      for output in outputs:
          collect_nodes_from(output)
  
      # Add edges (data)
      for node in graph:
          for input in node.inputs:
              graph.add_edge(input.node, node, input)
          for target in node.targets:
              graph.add_edge(target.node, node, target)
  
      # Check that there are no steps with the same name
      steps_seen = {}  # type: Dict[str, Step]
      duplicated_names = []
      for node in graph:
          step_name = node.step.name
          if step_name not in steps_seen:
              steps_seen[step_name] = node.step
          elif node.step is not steps_seen[step_name]:
              duplicated_names.append(step_name)
  
      if duplicated_names:
          raise RuntimeError(
              "A graph cannot contain steps with duplicated names. "
              "Found the following duplicates:\n"
              "{}".format(duplicated_names)
          )
  
      return graph
  
imports: from collections import defaultdict
  from typing import Union, List, Dict, Set, Iterable, Optional
  from baikal._core.data_placeholder import is_data_placeholder_list, DataPlaceholder
  from baikal._core.digraph import DiGraph
  from baikal._core.step import Step, InputStep, Node
  from baikal._core.typing import ArrayLike
  from baikal._core.utils import listify, safezip2, SimpleCache, unlistify
label_desc: Use image node_id 2 for calling a global function with example usage: build_graph_from_outputs(outputs) and returns: graph