Package: simple-schema-validator
Simple schema validatorSimple schema validatorBasic usageType checkingOptional typesA dead-simple utility that validates if object has a certain structure. Used in some of our projects.Basic usagepip install simple_schema_validatorAn example:Lets say we have an API that returns the following data:{"user":1,"profile":{"email":"some@user.com","name":"Some User","age":20},"tokens":{"jwt":"...","refresh":"...","firebase":"...",}}And we are writing a simple integration test, that wants to assure the response has a certain structure.Then we can use the schema validator like so:fromsimple_schema_validatorimportschema_validatordata=get_data_from_api()schema={'user':Any,'profile':{'email':Any,'name':Any,'age':Any},'tokens':{'jwt':Any,'refresh':Any,'firebase':Any}}validation=schema_validator(schema,data)ifnotvalidation:print(f'Keys in data, but not in schema:{validation.additional_keys}')print(f'Keys in schema, but not in data:{validation.missing_keys}')print(f'Keys with different type from schema{validation.type_errors}')missing_keysare those keys that are required in theschema, but not found indata.additional_keysare those keys present indata, but not required by theschema.validation_errorsare those keys, that are having a different type indata, from the defined inschema.Nested keys are represented with "dot" notation -profile.email,tokens.jwt, etc.Type checkingThe util supports simple schema type checking.Currently, the supported types in the schema are:intfloatstrbooltyping.Any(from Pythontypinglibrary)simple_schema_validator.types.Optional(custom type, define in the package)If the type isAny, no type checking is done.If there's a type mismatch, the errors are placed in thetype_errorsattribute of the result, which is a list of type errors.The general format of a single type error is:{'path':'the.path.to.the.value.in.data','expected':the_expected_type_as_defined_in_the_schema,'actual':the_actual_type_of_the_value}Here's an example:fromsimple_schema_validatorimportschema_validator,typesschema={'user':str,'profile':{'email':str,'name':str,'age':int},'tokens':{'jwt':str,'refresh':str,'firebase':str}}data={'user':'Some User','profile':{'email':'someuser@hacksoft.io','name':'Some User','age':"29"},'tokens':{'jwt':'some token value','refresh':'some token value','firebase':'some token value'}}result=schema_validator(schema,data)assertbool(result)isFalseassertresult.type_errors==[{'path':'profile.age','expected':int,'actual':str}]Optional typesThe schema validator support optional types.You can do the following:fromsimple_schema_validatorimportschema_validator,typesschema={'a':types.Optional[int]}data_1={'a':None}data_2={'a':1}data_3={'a':'some_string'}assertbool(schema_validator(schema,data_1))isTrueassertbool(schema_validator(schema,data_2))isTrueassertbool(schema_validator(schema,data_3))isFalseAdditionally, you can define optional branches in the schema:fromsimple_schema_validatorimportschema_validator,typesschema={'a':types.Optional[{'b':int}]}data_1={'a':None}data_2={'a':1}data_3={'a':{'b':1}}data_4={'a':{'b':'some_string'}}assertbool(schema_validator(schema,data_1))isTrueassertbool(schema_validator(schema,data_2))isFalseassertbool(schema_validator(schema,data_3))isTrueassertbool(schema_validator(schema,data_4))isFalseYou can use it with optional lists aswell:fromsimple_schema_validatorimportschema_validator,typesschema={'a':types.Optional[[int]]}data_1={'a':None}data_2={'a':1}data_3={'a':[1,2,3]}data_4={'a':['some_string']}assertbool(schema_validator(schema,data_1))isTrueassertbool(schema_validator(schema,data_2))isFalseassertbool(schema_validator(schema,data_3))isTrueassertbool(schema_validator(schema,data_4))isFalseList typesThe schema validator support list types.You can do the following:fromsimple_schema_validatorimportschema_validator,typesschema={'a':types.List[int]}data_1={'a':[1,2,3]}data_3={'a':['some_string']}assertbool(schema_validator(schema,data_1))isTrueassertbool(schema_validator(schema,data_2))isFalseRecursive schemasThe schema validator support type checking for schemas in list.You can do the following:fromsimple_schema_validatorimportschema_validator,typesschema={'a':[{'b':int}]}data_1={'a':[{'b':1}]}data_2={'a':[{'b':'some_string'}]}assertbool(schema_validator(schema,data_1))isTrueassertbool(schema_validator(schema,data_2))isFalsefromsimple_schema_validatorimportschema_validator,typesschema={'a':[{'b':[int]}]}data_1={'a':[{'b':[1]}]}data_2={'a':[{'b':[1,2,3]}]}data_3={'a':[{'b':['some_string']}]}data_4={'a':[{'b':[1,'some_string']}]}data_5={'a':[{'b':['some_string','other_string']}]}data_6={'a':[{'b':['some_string',1]}]}assertbool(schema_validator(schema,data_1))isTrueassertbool(schema_validator(schema,data_2))isTrueassertbool(schema_validator(schema,data_3))isFalseassertbool(schema_validator(schema,data_4))isFalseassertbool(schema_validator(schema,data_5))isFalseassertbool(schema_validator(schema,data_6))isFalseYou can do the same with optional branches aswell:fromsimple_schema_validatorimportschema_validator,typesschema={'a':[{'b':types.Optional[int]}]}data_1={'a':[{'b':{'c':1,'d':2}}]}data_2={'a':[{'b':'some_string'}]}assertbool(schema_validator(schema,data_1))isTrueassertbool(schema_validator(schema,data_2))isFalseExamplesFor examples, check theexamplesfolder or thetestsfor the project.