code: def get_backdoor_paths(graph: nx.DiGraph, nodes1, nodes2):
      paths = []
      undirected_graph = graph.to_undirected()
      nodes12 = set(nodes1).union(nodes2)
      for node1 in nodes1:
          for node2 in nodes2:
              backdoor_paths = [
                  pth
                  for pth in nx.all_simple_paths(
                      undirected_graph, source=node1, target=node2
                  )
                  if graph.has_edge(pth[1], pth[0])
              ]
              # remove paths that have nodes1\node1 or nodes2\node2 as intermediate nodes
              filtered_backdoor_paths = [
                  pth
                  for pth in backdoor_paths
                  if len(nodes12.intersection(pth[1:-1])) == 0
              ]
              paths.extend(filtered_backdoor_paths)
      _logger.debug("Backdoor paths: " + str(paths))
      return paths
  
imports: import itertools
  import logging
  import re
  from abc import abstractmethod
  from typing import Any, List, Protocol
  import networkx
  from networkx.algorithms.dag import has_cycle
  from dowhy.utils.api import parse_state
  from dowhy.utils.graph_operations import daggity_to_dot
label_desc: Use image node_id 8 for calling a global function with example usage: get_backdoor_paths(graph, nodes1, nodes2) and returns: paths