class_docstr: Keras-compatible data generator to use with Keras methods :meth:`keras.Model.fit`,
  :meth:`keras.Model.evaluate`, and :meth:`keras.Model.predict`
  
  This class generates data samples for link inference models
  and should be created using the :meth:`flow` method of
  :class:`.GraphSAGELinkGenerator` or :class:`.Attri2VecLinkGenerator`.
  
  Args:
      sample_function (Callable): A function that returns features for supplied head nodes.
      sampler (UnsupersizedSampler):  An object that encapsulates the neighbourhood sampling of a graph.
          The generator method of this class returns a batch of positive and negative samples on demand.
class_docstr_tok: ["Keras-compatible","data","generator","to","use","with","Keras","methods",":","meth",":","`","keras.Model.fit","`",",",":","meth",":","`","keras.Model.evaluate","`",",","and",":","meth",":","`","keras.Model.predict","`","This","class","generates","data","samples","for","link","inference","models","and","should","be","created","using","the",":","meth",":","`","flow","`","method","of",":","class",":","`",".GraphSAGELinkGenerator","`","or",":","class",":","`",".Attri2VecLinkGenerator","`",".","Args",":","sample_function","(","Callable",")",":","A","function","that","returns","features","for","supplied","head","nodes",".","sampler","(","UnsupersizedSampler",")",":","An","object","that","encapsulates","the","neighbourhood","sampling","of","a","graph",".","The","generator","method","of","this","class","returns","a","batch","of","positive","and","negative","samples","on","demand","."]
code: def __init__(self, sample_function, batch_size, walker, shuffle=True):
      # Store the generator to draw samples from graph
      if isinstance(sample_function, collections.abc.Callable):
          self._sample_features = sample_function
      else:
          raise TypeError(
              "({}) The sampling function expects a callable function.".format(
                  type(self).__name__
              )
          )
  
      if not isinstance(walker, UnsupervisedSampler):
          raise TypeError(
              "({}) UnsupervisedSampler is required.".format(
                  type(self).__name__
              )
          )
  
      self.batch_size = batch_size
      self.walker = walker
      self.shuffle = shuffle
      # FIXME(#681): all batches are created at once, so this is no longer "on demand"
      self._batches = self._create_batches()
      self.length = len(self._batches)
      self.data_size = sum(len(batch[0]) for batch in self._batches)
  
imports: import warnings
  import operator
  import random
  import collections
  import numpy
  import itertools
  import networkx
  import scipy.sparse
  from tensorflow.keras import backend
  from functools import reduce
  from tensorflow.keras.utils import Sequence
  from ..data.unsupervised_sampler import UnsupervisedSampler
  from ..core.utils import is_real_iterable
  from ..random import random_state
  from scipy import sparse
  from ..core.experimental import experimental
label_desc: Use image node_id 1 to create a new OnDemandLinkSequence object from inherited base classes: Sequence with example: obj = OnDemandLinkSequence(sample_function, batch_size, walker, shuffle)