code: def build_graph(stages, outs_trie=None):
      """Generate a graph by using the given stages on the given directory
  
      The nodes of the graph are the stage's path relative to the root.
  
      Edges are created when the output of one stage is used as a
      dependency in other stage.
  
      The direction of the edges goes from the stage to its dependency:
  
      For example, running the following:
  
          $ dvc run -o A "echo A > A"
          $ dvc run -d A -o B "echo B > B"
          $ dvc run -d B -o C "echo C > C"
  
      Will create the following graph:
  
             ancestors <--
                         |
              C.dvc -> B.dvc -> A.dvc
              |          |
              |          --> descendants
              |
              ------- pipeline ------>
                         |
                         v
            (weakly connected components)
  
      Args:
          stages (list): used to build a graph from
  
      Raises:
          OutputDuplicationError: two outputs with the same path
          StagePathAsOutputError: stage inside an output directory
          OverlappingOutputPathsError: output inside output directory
          CyclicGraphError: resulting graph has cycles
      """
      import networkx as nx
  
      from dvc.exceptions import StagePathAsOutputError
  
      from .trie import build_outs_trie
  
      graph = nx.DiGraph()
  
      # Use trie to efficiently find overlapping outs and deps
      outs_trie = outs_trie or build_outs_trie(stages)
  
      for stage in stages:
          out = outs_trie.shortest_prefix(
              localfs.parts(stage.path)
          ).value
          if out:
              raise StagePathAsOutputError(stage, str(out))
  
      # Building graph
      graph.add_nodes_from(stages)
      for stage in stages:
          if stage.is_repo_import:
              continue
          if stage.is_db_import:
              continue
  
          for dep in stage.deps:
              dep_key = dep.fs.parts(dep.fs_path)
              overlapping = [
                  n.value for n in outs_trie.prefixes(dep_key)
              ]
              if outs_trie.has_subtrie(dep_key):
                  overlapping.extend(outs_trie.values(prefix=dep_key))
  
              graph.add_edges_from(
                  (stage, out.stage) for out in overlapping
              )
      check_acyclic(graph)
  
      return graph
  
file_path: dvc/dvc/repo/graph.py
imports: from typing import TYPE_CHECKING, Any, Iterator, List, Optional, Set, TypeVar
  from dvc.fs import localfs
  from dvc.utils.fs import path_isin
label_desc: Use image node_id 7 for calling a global function with example usage: build_graph(stages, outs_trie) and returns: graph