2626
2727
2828class Key :
29- def __init__ (self , label : str , type_ ):
30- self .label = label
31- self .type = type_
32-
33- # def unpack(self):
34- # return self.label, self.type
29+ def __init__ (self , name : str , type_ ):
30+ self .name = name
31+ self .type_ = type_
3532
3633 @classmethod
3734 def model (cls ):
@@ -46,29 +43,29 @@ def filter(cls):
4643 return cls ('filter' , dict )
4744
4845 def is_valid_type (self , entity ):
49- return isinstance (entity , self .type )
46+ return isinstance (entity , self .type_ )
5047
5148 def __str__ (self ):
52- return self .label
49+ return self .name
5350
5451 def __eq__ (self , o : object ) -> bool :
5552 if isinstance (o , self .__class__ ):
56- return self .label == o .label and self .type == o .type
53+ return self .name == o .name and self .type_ == o .type_
5754
5855 if isinstance (o , str ):
59- return self .label == o
56+ return self .name == o
6057
6158 return False
6259
6360 def __hash__ (self ):
64- return hash (self .label )
61+ return hash (self .name )
6562
6663
6764def check_model_key (entity : dict , entity_is_parent : bool ):
6865 model = Key .model ()
6966 if model not in entity and entity_is_parent :
7067 raise errors .MissingRequiredKeyError ("'model' key is missing." )
71- # check type
68+ # check type_
7269 if model in entity and not model .is_valid_type (entity [model ]):
7370 raise errors .InvalidDataTypeError ("'model' data should be 'string'." )
7471
@@ -93,42 +90,51 @@ def check_source_key(entity: dict, source_keys: list) -> Key:
9390
9491def check_source_data (source_data , source_key : Key ):
9592 if not isinstance (source_data , dict ) and not isinstance (source_data , list ):
96- raise errors .InvalidDataTypeError (f"Invalid type , { str (source_key )} should be either 'dict' or 'list'." )
93+ raise errors .InvalidDataTypeError (f"Invalid type_ , { str (source_key )} should be either 'dict' or 'list'." )
9794
9895 if isinstance (source_data , list ) and len (source_data ) == 0 :
9996 raise errors .EmptyDataError ("Empty list, 'data' or 'filter' list should not be empty." )
10097
10198
102- # def iter_reference_relationships(kwargs: dict, ref_prefix):
103- # for attr_name, value in kwargs.items():
104- # if attr_name.startswith(ref_prefix):
105- # # removed prefix
106- # yield attr_name[len(ref_prefix):], value
99+ def check_data_type (item , source_key : Key ):
100+ if not source_key .is_valid_type (item ):
101+ raise errors .InvalidDataTypeError (
102+ f"Invalid type_, '{ source_key .name } ' should be '{ source_key .type_ } '" )
103+
104+
105+ def iter_reference_relationship_values (kwargs : dict , ref_prefix ):
106+ for attr_name , value in kwargs .items ():
107+ if attr_name .startswith (ref_prefix ):
108+ # removed prefix
109+ yield value
107110
108111
109112class SchemaValidator :
110113 _source_keys = None
114+ _ref_prefix = None
111115
112116 @classmethod
113117 def validate (cls , entities , ref_prefix = '!' , source_keys = None ):
114118 if source_keys is None :
115119 cls ._source_keys = [Key .data (), Key .filter ()]
116- cls ._pre_validate (entities , is_parent = True , ref_prefix = ref_prefix )
120+ cls ._ref_prefix = ref_prefix
121+
122+ cls ._pre_validate (entities , entity_is_parent = True )
117123
118124 @classmethod
119- def _pre_validate (cls , entities : dict , is_parent = True , ref_prefix = '!' ):
125+ def _pre_validate (cls , entities : dict , entity_is_parent = True ):
120126 if not isinstance (entities , dict ) and not isinstance (entities , list ):
121127 raise errors .InvalidDataTypeError ("Invalid type, should be list or dict" )
122128 if len (entities ) == 0 :
123129 return
124130 if isinstance (entities , dict ):
125- return cls ._validate (entities , is_parent , ref_prefix )
131+ return cls ._validate (entities , entity_is_parent )
126132 # iterate list
127133 for entity in entities :
128- cls ._pre_validate (entity , is_parent , ref_prefix )
134+ cls ._pre_validate (entity , entity_is_parent )
129135
130136 @classmethod
131- def _validate (cls , entity : dict , entity_is_parent = True , ref_prefix = '!' ):
137+ def _validate (cls , entity : dict , entity_is_parent = True ):
132138 check_max_length (entity )
133139 check_model_key (entity , entity_is_parent )
134140
@@ -140,18 +146,15 @@ def _validate(cls, entity: dict, entity_is_parent=True, ref_prefix='!'):
140146
141147 if isinstance (source_data , list ):
142148 for item in source_data :
143- if not source_key .is_valid_type (item ):
144- raise errors .InvalidDataTypeError (
145- f"Invalid type, '{ source_key .label } ' should be '{ source_key .type } '" )
146-
149+ check_data_type (item , source_key )
147150 # check if item is a relationship attribute
148- cls ._scan_attributes (item , ref_prefix )
149- elif source_key .is_valid_type (source_data ):
151+ cls .check_attributes (item )
152+ else :
153+ # source_data is dict
150154 # check if item is a relationship attribute
151- cls ._scan_attributes (source_data , ref_prefix )
155+ cls .check_attributes (source_data )
152156
153157 @classmethod
154- def _scan_attributes (cls , source_data : dict , ref_prefix ):
155- for key , value in source_data .items ():
156- if str (key ).startswith (ref_prefix ):
157- cls ._pre_validate (value , is_parent = False , ref_prefix = ref_prefix )
158+ def check_attributes (cls , source_data : dict ):
159+ for value in iter_reference_relationship_values (source_data , cls ._ref_prefix ):
160+ cls ._pre_validate (value , entity_is_parent = False )
0 commit comments