Laszlo
Laszlo

Reputation: 801

Python 2.7: How to validate a list against a specified schema?

In this class:

class message:
    def __init__(self, node_info = None):
       if node_info is None: node_info = []
       self.node_info = node_info

    @property
    def node_info(self):
        return self._node_info

    @node_info.setter
    def node_info(self, value):
        self._node_info = value

node_info should have a layout similar to this:

sample_node_info = [
  'Node Name',
  'Node URL',
  status,
  ['Service1','ServiceURL1',status],
  ['Service2','ServiceURL2',status]
]

The first two elements are strings, and are required. Subsequent elements are lists, and are optional. The optional elements, if included, should contain three required elements:

 service_info = ['ServiceName','ServiceURL',status]

Question: How do I validate node_info against this format in the class above? Do I have to parse the list or is there some better way, like defining a schema/format of some sorts?

Upvotes: 0

Views: 534

Answers (1)

Laszlo
Laszlo

Reputation: 801

This is a possible solution, using a custom validator:

import sys
from private import private

class message:
    #status_t = ['offline', 'online']

    def __init__(self, node_info = None):
      if node_info is None:
         self.node_info = []
      else:
         self.__validate_node_info(node_info)
         self.node_info = node_info

    @property
    def node_info(self):
        return self.node_info

    @node_info.setter
    def node_info(self, value):
      self.__validate_node_info(value)
      self.node_info = value

    def toString(self):
      s = ''
      return s


    @private
    def __validate_node_info(self, lst, level=0):

      '''
      Validates the node_info list, against this schema:

      node_info = [
         required(str),
         required(str),
         required(int),
         optional(service_info),
         optional(service_info),...]

      service_info = [required(str),required(str),required(int)]

      Sample input:

      sample_node_info = [
         'Node Name',
         'Node URL',
         status,
         ['Service1','ServiceURL1',status],
         ['Service2','ServiceURL2',status]
       ]

      '''

      i = 0
      lstlen = len(lst)

      if lstlen < 2:
        raise TypeError("The list %s is too short" % (lst))
      if level > 0:
        if len(lst) != 3:
           raise TypeError("The list %s should contain exactly %d elements" % (lst,3))
      for e in lst:
        argval = lst[i]
        if i < 2:
           if not type(argval) is str:
              raise TypeError("type is %s, must be %s" % (type(argval), str))
        elif i == 2:
           if not type(argval) is int:
              raise TypeError("type is %s, must be %s" % (type(argval), int))
        else:
           self.__validate_node_info(lst[i],level+1)
        i=i+1


#message.node_info = ['node1', 'nodeurl1', 1, ['service1', 'serviceurl1', 0], ['service2', 'serviceurl2', 1] ]
#print(message.node_info)

private.py is listed here

Upvotes: 1

Related Questions