Package: serialize-mcr
Latest Versionserialize-mcr='0.0.1'MaintainersJunpu Fan (Original Author,serial-j=https://github.com/JunpuFan/serial-j/blob/master)Andrew Ray,rayam@iu.edu(Primary Maintainer)Featuresserialize-mcr JSON / Python Dictionary data into Python object based on a compact dataschema.Dataschemais a python list[]of many{}.Each{}in theschemadefines a property in yourJSONdata.The easiest form of a property definition is{'name':'my_property'}which means:YourJSONdataMUSTcontain a property calledmy_property.Its valueMUSTbe anon-emptyvalue.Non-empty means that the value ofmy_propertycan not beNone,"",(),[], or{}.Additional options are available to give you more control over your data definition. Those options are:nullable,optional,is_compound,compound_serialize-mcrr,compound_schema,type, anddefault.Optionnullable: Truemeans the value ofmy_propertycan beNone, or a nullable equivalent.Optionoptional: Truemeansmy_propertymay or may not exist in yourJSONdata.In casemy_propertyexist, verify all applicable options.In casemy_propertydoesn't exist, we ignoremy_property.Optionis_compound: Truemeansmy_propertyis a nestedJSONobject or an Array ofJSONobjects.Whenis_compound: True, you must provide eithercompound_serialize-mcrrorcompound_schemaso we can property serialize-mcr this nested data structure.compound_serialize-mcrris aserialize-mcrserialize-mcrr class.compound_schemahas the same structure as the dataschema.Optiontypegives you the power to validate the value of each property in yourJSONdata. Currently supported type definitions are:'type': (bool,)a boolean value.'type': (float,)a floating point number.'type': (int,)an integer.'type': (int, (1, 64, 343))an enumeration of integers, this means that the value of aJSONproperty should be in(1, 64, 343).'type': (int, range(1, 10, 3), a range of integers, this means that the value of aJSONproperty should be inrange(1, 10, 3).'type': (int, lambda x: x % 2 == 0)a user definedlambdaexpression used to filter desired integer values, the above examplelambdaspecifies the value of theJSONproperty should be aevennumber.'type': (str,)a string value.'type': (str, ('SUCCESS', 'FAILURE'))an enumeration of strings, this means that the value of aJSONproperty should be in('SUCCESS', 'FAILURE'). Note that('SUCCESS', 'FAILURE')is just an example here, you can define anything you like.'type': (str, 'email')an email address.'type': (str, 'url')a web url.'type': (str, 'ipv4')an IPv4 address.'type': (str, 'ipv6')an IPv6 address.'type': (str, 'uuid')an UUID string.'type': (str, '[^@]+@[^@]+\.[^@]+')a user definedregex.Optiondefaultgives you the power to set a defaulted value for a property in the case where it was not passed in AND the property was optionaldefaultdoes not work if the property is optional, or in other wordsrequireddefaultdoes a type check against the definedtypeif passed inif the type of thedefaultvalue does not conform with thetypedefined, then an error will be throwndefaultdefaulted value isNone, therefore bothTrueandFalseare also supported in thedefaultrealm of options.Automatically validate every JSON properties defined in theschemabased on varies additional options specified inschema.You are given convenient built-in methods that you can use to convert your data back to JSON encoded string or JSON / Python Dictionary.You have the flexibility of defining additional methods in your serialize-mcrr class that utilize your data in anyway you want.Example CodesNameCodeBasic Examplebasic_ex.pyserialize-mcr Nested Json Data withcompound_schemanested_ex2.pyserialize-mcr Nested Json Data withcompound_serialize-mcrrnested_ex1.pyData Type Validation: all in one exampletyped_ex.pyData Type Validation:boolbool_data.pyData Type Validation:floatfloat_data.pyData Type Validation:intint_data.pyData Type Validation:int enumint_enum_data.pyData Type Validation:int rangeint_ranged_data.pyData Type Validation:int lambdaint_lambda_data.pyData Type Validation:strstr_data.pyData Type Validation:str enumstr_enum_data.pyData Type Validation:str emailstr_email_data.pyData Type Validation:str urlstr_url_data.pyData Type Validation:str uuidstr_uuid_data.pyData Type Validation:str ipv4str_ipv4_data.pyData Type Validation:str ipv6str_ipv6_data.pyData Type Validation:str regexstr_regex_data.pyDefault Data:defaultextra_params_ex.pyBasic ExampleLet's first see a basic example.fromserialize_mcrimportSerializeMCRclassFruitBucket(SerializeMCR):# define how our data should look like using `schema`.schema=[{'name':'apple'},{'name':'orange'},{'name':'pineapple'},]# test data for FruitBuckettest1=dict(apple="good apple",orange="very good orange",pineapple="nice pineapple",)serialize-mcrfruits=FruitBucket(test1)# `fruits` is a proper python object , which means that you can use# `fruits.apple` syntax to retrieve the value of `apple`.print(fruits.apple)>>>goodapple# ...and other fruits too.print(fruits.orange)>>>verygoodorangeprint(fruits.pineapple)>>>nicepineapple# you can get the JSON formatted string back too.print(fruits)>>>{"apple":"good apple","orange":"very good orange","pineapple":"nice pineapple"}# interested to get the python dictionary back?fruits_data=fruits.as_dict()print(fruits_data)>>>{'apple':'good apple','orange':'very good orange','pineapple':'nice pineapple'}Nested JSON DataLet's see how we can serialize-mcr more complex data structure into python object.Serializing Nested JSON Data withcompound_schema.Define a nested dataschemacalledcompound_schemato serialize-mcr nestedJSONdata.fromserialize_mcrimportSerializeMCRclassSnackBucket(SerializeMCR):schema=[{'name':'apple'},{'name':'orange'},{'name':'pineapple'},{'name':'snack','is_compound':True,'compound_schema':[{'name':'cheese','optional':True},{'name':'chocolate'},{'name':'chips','nullable':True},],},]test3=dict(apple="good apple",orange="very good orange",pineapple="nice pineapple",snack=[dict(cheese="Feta",chocolate="Ferrero Rocher",chips=[]),dict(chocolate="Swiss milk chocolate",chips=["Cheetos","Lays Classic Potato Chips","Cool Ranch Doritos"]),])mysnacks=SnackBucket(test3)print(mysnacks)>>>{"apple":"good apple","orange":"very good orange","pineapple":"nice pineapple",>>>"snack":[{"cheese":"Feta","chocolate":"Ferrero Rocher","chips":[]},>>>{"chocolate":"Swiss milk chocolate","chips":>>>["Cheetos","Lays Classic Potato Chips","Cool Ranch Doritos"]}]}Serializing Nested JSON Data withcompound_serialize-mcrr.Define a separete dataserialize-mcrserialize-mcrr calledcompound_serialize-mcrrto serialize-mcr nestedJSONdata.fromserialize_mcrimportSerializeMCRclassSnack(SerializeMCR):schema=[# cheese is nice but is optional.{'name':'cheese','optional':True},# chocolate is a MUST have.{'name':'chocolate'},# chips is a must but we have to decide which kind later,# so its value can be None, False, "", {}, [].{'name':'chips','nullable':True},]classNestedBucket(SerializeMCR):schema=[{'name':'apple'},{'name':'orange'},{'name':'pineapple'},{'name':'snack','is_compound':True,'compound_serialize-mcrr':Snack}]# test data for NestedBuckettest2=dict(apple="good apple",orange="very good orange",pineapple="nice pineapple",snack=dict(chocolate="Ferrero Rocher",chips=[]# yeah its a list of chips!),)my_snacks=NestedBucket(test2)print(my_snacks)>>>{"apple":"good apple","orange":"very good orange","pineapple":"nice pineapple",>>>"snack":{"chocolate":"Ferrero Rocher","chips":[]}}Data Type Validationa compact example that shows all data types currently supported by this package.fromserialize_mcrimportSerializeMCRclassTypedData(SerializeMCR):schema=[{'name':'prop1','type':(int,)},{'name':'prop2','type':(int,(1,64,343))},{'name':'prop3','type':(int,range(1,10,3))},{'name':'prop4','type':(int,lambdax:x%2==0)},{'name':'prop5','type':(str,)},{'name':'prop6','type':(str,('SUCCESS','FAILURE'))},{'name':'prop7','type':(str,'email')},{'name':'prop8','type':(str,'url')},{'name':'prop9','type':(str,'ipv4')},{'name':'prop10','type':(str,'ipv6')},{'name':'prop11','type':(str,'uuid')},{'name':'prop12','type':(str,'[^@]+@[^@]+\.[^@]+')},{'name':'prop13','type':(float,)},{'name':'prop14','type':(bool,)},]test1={'prop1':1,'prop2':64,'prop3':4,'prop4':2,'prop5':"str",'prop6':'SUCCESS','prop7':'anyone@emailservice.com','prop8':'https://www.something.com/something-something/something/12345','prop9':'172.16.255.1','prop10':'2001:0db8:0a0b:12f0:0000:0000:0000:0001','prop11':'c026dd66-86f2-498e-8c2c-858179c0c93d','prop12':'junpufan@me.com','prop13':0.1,'prop14':True}data1=TypedData(test1)print(data1)# >>> {"prop1": 1, "prop2": 64, "prop3": 4, "prop4": 2, "prop5": "str",# >>> "prop6": "SUCCESS", "prop7": "anyone@emailservice.com",# >>> "prop8": "https://www.something.com/something-something/something/12345",# >>> "prop9": "172.16.255.1", "prop10": "2001:0db8:0a0b:12f0:0000:0000:0000:0001",# >>> "prop11": "c026dd66-86f2-498e-8c2c-858179c0c93d", "prop12": "junpufan@me.com",# >>> "prop13": 0.1, "prop14": true}Defaulting Data on Optional Properties Absencea simple way to ensure a value is set at all times for optional properties in a JSON schemafromserialize_mcrimportSerializeMCRclassDefaultingValues(SerializeMCR):schema=[{'name':'var1','type':(int,),'optional':True,'default':0},{'name':'var2','type':(str,),'optional':True,'default':'str'},{'name':'var3','type':(float,),'optional':True,'default':1.25},{'name':'var4','type':(bool,),'optional':True,'default':True},{'name':'var5','type':(int,(1,3,5)),'optional':True,'default':3}]### acceptable bodies to pass in# since all properties are optional, no values are required to be passed in# all values will be set to their defined default valuetest1={}data1=DefaultingValues(data=test1)# choosing some but not all properties will also work, as var2, var3, var5 will be set to their default valuestest2={'var1':24,'var4':False}data2=DefaultingValues(data=test2)classInvalidDefaultValues(SerializeMCR):schema=[{'name':'var1','type':(int,),'default':0},{'name':'var2','type':(str,),'optional':True,'default':1},{'name':'var3','type':(float,),'optional':True,'default':True},{'name':'var4','type':(bool,),'optional':True,'default':False},{'name':'var5','type':(int,(1,3,5)),'default':3}]# var1 is not optional, therefore a default value cannot be set# var2 has a defined type of `str`, but a defaulted value of `int`# var3 has a defined type of `float`, but a defaulted value of `bool`# var4 is acceptable# var5 is not optional, therefore a default value cannot be setNote: The schema's of a serialize-mcr are not validated until a dataset is passed into the Class, therefore improper schema definitions are acceptable, but will fail to build.