Package: py-schema
py_schemaA simple and extensible schema validator.Installpip install py-schemaUsagefrompy_schemaimportSchemaValidator,SchemaValidationErrorfrompy_schemaimportDictField,ListField,StrField,IntFieldschema=DictField(schema={'name':StrField(min_length=2,max_length=50),'age':IntField(min=0,max=130),'pets':ListField(min_items=1,item_schema=StrField())})value={'name':'Bruce','age':40,'pets':['Billy',False]}try:validator=SchemaValidator(schema=schema,value=value)validator.validate()exceptSchemaValidationErroraserr:print(err.code)# STR_TYPEprint(err.path)# $root.pets.$1You can check the complete list of errors in each field spec.FieldsBaseFieldThis is the abstract field that all the fields inherit from.It has some shared props that you can use in all fields.requiredIf marked asTrue(default) and the value isNone, it will raise aREQUIRED_VALUEerror.frompy_schemaimportSchemaValidator,SchemaValidationError,StrFieldtry:schema=StrField(required=True)value=Nonevalidator=SchemaValidator(schema,value)validator.validate()exceptSchemaValidationErroraserr:print(err.code)# "REQUIRED_VALUE"IntFieldValidate if the value is an integer.frompy_schemaimportSchemaValidator,IntFieldschema=IntField(min=1,max=100)value=80validator=SchemaValidator(schema,value)validator.validate()min (int, optional, default None)If provided, it will validate if the value is >= of themin.If not, it will raise aINT_MINerror.max (int, optional, default None)If provided, it will validate if the value is <= of themax.If not, it will raise aINT_MAXerror.StrFieldValidate if the value is a string.frompy_schemaimportSchemaValidator,StrFieldschema=StrField(min_length=2,max_length=50)value='Luca Turilli'validator=SchemaValidator(schema,value)validator.validate()min_length (int, optional, default None)If provided, it will validate if the string len is >= of themin_length.If not, it will raise aSTR_MIN_LENGTHerror.max_length (int, optional, default None)If provided, it will validate if the string len is <= of themax_length.If not, it will raise aSTR_MAX_LENGTHerror.FloatFieldValidate if the value is a float.frompy_schemaimportSchemaValidator,FloatFieldschema=FloatField(min=0.0,max=99.0)value=50.0validator=SchemaValidator(schema,value)validator.validate()min (int, optional, default None)If provided, it will validate if the value is >= of themin.If not, it will raise aFLOAT_MINerror.max (int, optional, default None)If provided, it will validate if the value is <= of themax.If not, it will raise aFLOAT_MAXerror.BoolFieldValidate if the value is a bool.frompy_schemaimportSchemaValidator,BoolFieldschema=BoolField()value=Falsevalidator=SchemaValidator(schema,value)validator.validate()DictFieldValidate if the value is a dict and each field inside it.frompy_schemaimportSchemaValidator,DictField,StrField,BoolFieldschema=DictField(schema={'name':StrField(),'admin':BoolField(),'contacts':DictField(schema={'phone':StrField(),'email':StrField()},optional_props=['phone'])},strict=True,optional_props=['contacts'])value={'name':'Dargor The Lord','admin':True,'contacts':{'email':'dargor@blackmountain.com'}}validator=SchemaValidator(schema,value)validator.validate()schema (dict, required)The definition of the dictionary.strict (bool, optional, default False)If the schema should reject dictionary keys that is not present in the schema.For example:frompy_schemaimportSchemaValidator,SchemaValidationError,DictField,StrField,BoolFieldtry:schema=DictField(schema={'name':StrField(),'admin':BoolField()},strict=True)value={'name':'Dargor The Lord','admin':True,'contacts':{'email':'dargor@blackmountain.com'}}validator=SchemaValidator(schema,value)validator.validate()exceptSchemaValidationErroraserr:print(err.code)# DICT_PROP_NOT_ALLOWEDprint(err.extra)# {'prop': 'contacts'}In this case, thecontactsproperty in the value is not present in the schema.It will raise aDICT_PROP_NOT_ALLOWED.optional_props ([str], optional, default [])This prop indicates which properties are optional in schema.If a prop is in this list and it's not in the value, it will be ignored.Otherwise, it will raise aDICT_PROP_MISSINGerror.Example:frompy_schemaimportSchemaValidator,DictField,StrField,BoolFieldschema=DictField(schema={'name':StrField(),'admin':BoolField(),'gender':StrField()},optional_props=['gender'])value={'name':'Dargor The Lord','admin':True}validator=SchemaValidator(schema,value)validator.validate()# validfrompy_schemaimportSchemaValidator,SchemaValidationError,DictField,StrField,BoolFieldtry:schema=DictField(schema={'name':StrField(),'admin':BoolField()})value={'name':'Dargor The Lord'}validator=SchemaValidator(schema,value)validator.validate()exceptSchemaValidationErroraserr:print(err.code)# DICT_PROP_MISSINGprint(err.extra)# {'prop': 'admin'}ListFieldValidate if the value is a list and the items inside it.frompy_schemaimportSchemaValidator,ListField,StrFieldschema=ListField(min_items=1,max_items=3,item_schema=StrField())value=['Emerald','Sword']validator=SchemaValidator(schema,value)validator.validate()item_schema (BaseField, required)The schema for the item inside the list.min_items (int, optional, default None)Validate if the list contain at minimunmin_itemslength.If not, it will raiseLIST_MIN_ITEMSerror.max_items (int, optional, default None)Validate if the list contain at maximummax_itemslength.If not, it will raiseLIST_MAX_ITEMSerror.EnumFieldValidate if the value is one of the allowed values.frompy_schemaimportSchemaValidator,EnumFieldschema=EnumField(accept=[1,True,'Immortal'])value=1validator=SchemaValidator(schema,value)validator.validate()accept (list, required)The list of the values that can be accepted.If the value is not in theaccepted, it will raise aENUM_VALUE_NOT_ACCEPTerror.Regex FieldValidate if the value matches the regex.frompy_schemaimportSchemaValidator,RegexFieldschema=RegexField(regex='\\d{5}\\Z')value='12345'validator=SchemaValidator(schema,value)validator.validate()regex (str, required)The regex pattern.OR FieldValidate if the value matches with at least one of given schemas.frompy_schemaimportOrField,StrField,BoolField,IntField,SchemaValidator,SchemaValidationErrorschema=OrField(schemas=[StrField(),IntField()])value=Truevalidator=SchemaValidator(schema,value)try:validator.validate()exceptSchemaValidationErrorase:print(e.extra['errors'])schemas ([BaseField], required)The list of the schemas to validate.
If all the schemas failed, it will raise aOR_NO_MATCHING_SCHEMAerror.If the validation fail, you can check the error propextra['errors']to see all the validation results.MiscSchemaValidationErrorIf a validation fails, it will raise aSchemaValidationError.Inside the error will will have:frompy_schemaimportSchemaValidationErrortry:# ....passexceptSchemaValidationErroraserr:print(err.code)# The code of the errorprint(err.path)# The path in the schema that the error occurred.print(err.node)# The BaseField node where the validation was raised.print(err.extra)# Any extra argument of the error.Creating custom validatorsFor better context, let's use this sample:frompy_schemaimportDictFieldfrom.my_fieldimportMyFieldschema=DictField(schema={'my_field':MyField()})value={'my_field':'Avalon'}frompy_schemaimportBaseFieldclassMyField(BaseField):defvalidator(self):ctx=self.ctx# the current SchemaValidator instancevalue=self.value# here is the current value of the schema (in this sample: "Avalon")ifvalue!='Avalon':# create you custom validationself.raise_error(# if your validation fails, raise an errorcode='MY_CUSTOM_CODE',extra="Any other extra info for your error (optional)")And that's it =).