text: # date: 2021.07.14
  # author: Raul Saavedra raul.saavedra.felipe@iais.fraunhofer.de
  
  import grpc
  from concurrent import futures
  import time
  import numpy
  
  # import constant with the hardcoded openml data ID number
  import myconstants
  
  # import the generated grpc related classes for python
  import model_pb2
  import model_pb2_grpc
  
  # import utility file to get the data
  import openml_data_fetcher as odf
  
  port_address = 8061
  openml_obj = odf.FetchOpenMLData()
  current_row = 0
  
  class get_next_rowServicer(model_pb2_grpc.get_next_rowServicer):
      def get_next_row(self, request, context):
          response = model_pb2.Features()
          total_rows = openml_obj.get_num_rows()
          current_row = openml_obj.current_row
          #print("total number of rows of OpenML file: ", total_rows)
          if current_row == total_rows:
              context.set_code(grpc.StatusCode.NOT_FOUND)
              context.set_details('All available data has been processed')
              print("All data processed. Exception raised")
              return response
  
          #print(f"fetching row {current_row} from a total of {total_rows}")
          row = openml_obj.get_next_row(current_row)
          openml_obj.current_row = openml_obj.current_row + 1
  
          ###############################################################
          # Here goes the OpenML dataset specific Feature assignments
          ###############################################################
  
          response.Age                            = numpy.uint32(row[0])
          response.Sex                            = row[1]
          response.Chest_pain_type                = row[2]
          response.Trestbps                       = numpy.uint32(row[3])
          response.Cholesterol                    = row[4]
          response.Fasting_blood_sugar__lt__120   = row[5]
          response.Resting_ecg                    = row[6]
          response.Max_heart_rate                 = numpy.uint32(row[7])
          response.Exercise_induced_angina        = row[8]
          response.Oldpeak                        = row[9]
          response.Slope                          = row[10]
          response.Number_of_vessels_colored      = row[11]
          response.Thal                           = row[12]
          response.Class                          = row[13]
  
          ###############################################################
          return response
  
  
  # Following House_Price_Prediction/csv_databroker/csv_server.py
  server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
  model_pb2_grpc.add_get_next_rowServicer_to_server(get_next_rowServicer(), server)
  print("Starting OpenML data node server")
  server.add_insecure_port(f'[::]:{port_address}')
  server.start()
  
  try:
      while True:
          time.sleep(86400)
  except KeyboardInterrupt:
      server.stop(0)
  