docs: def create_graph(response_jsons, name='unnamed', retain_all=False, bidirectional=False):
      """
      Create a networkx graph from OSM data.
  
      Parameters
      ----------
      response_jsons : list
          list of dicts of JSON responses from from the Overpass API
      name : string
          the name of the graph
      retain_all : bool
          if True, return the entire graph even if it is not connected
      bidirectional : bool
          if True, create bidirectional edges for one-way streets
     
  
      Returns
      -------
      networkx multidigraph
      """
  
      log('Creating networkx graph from downloaded OSM data...')
      start_time = time.time()
  
      # make sure we got data back from the server requests
      elements = []
      for response_json in response_jsons:
          elements.extend(response_json['elements'])
      if len(elements) < 1:
          raise EmptyOverpassResponse('There are no data elements in the response JSON objects')
  
      # create the graph as a MultiDiGraph and set the original CRS to default_crs
      G = nx.MultiDiGraph(name=name, crs=settings.default_crs)
  
      # extract nodes and paths from the downloaded osm data
      nodes = {}
      paths = {}
      for osm_data in response_jsons:
          nodes_temp, paths_temp = parse_osm_nodes_paths(osm_data)
          for key, value in nodes_temp.items():
              nodes[key] = value
          for key, value in paths_temp.items():
              paths[key] = value
  
      # add each osm node to the graph
      for node, data in nodes.items():
          G.add_node(node, **data)
  
      # add each osm way (aka, path) to the graph
      G = add_paths(G, paths, bidirectional=bidirectional)
  
      # retain only the largest connected component, if caller did not
      # set retain_all=True
      if not retain_all:
          G = get_largest_component(G)
  
      log('Created graph with {:,} nodes and {:,} edges in {:,.2f} seconds'.format(len(list(G.nodes())), len(list(G.edges())), time.time()-start_time))
  
      # add length (great circle distance between nodes) attribute to each edge to
      # use as weight
      if len(G.edges) > 0:
          G = add_edge_lengths(G)
  
      return G