Package: jschemalite
Author: Kris HauserJSON Schema Lite uses a JSON Schema-like syntax to match JSON objects.MotivationWhy use this instead of JSON Schema?First reason: It’smuchless verbose than JSON Schema.Second reason: It’sway easierto write rules! Since rules largely
match the JSON representation of an object, it’s really simple to modify
items to specify what you’d like. Say that you want to match a user
login object, except for the ‘session’ and ‘ip’ key:item={"name":"John Doe","password":"john123","session":28387432,"ip":"128.0.0.1"}To ignore these keys, just set:schema=copy.copy(item)schema['session']=Noneschema['ip']=NoneThen, thematchfunction will match any item matching John Doe’s
record, except for the ‘session’ and ‘ip’ keys.As another example, suppose that you’d like to recognize “large
circles”. The circle object is represented by an object like this:circle={"type":"Circle","center":[0.583,3.2919],"radius":0.25}Then, we can simply modify some conditions the center and radius to
match circles with radius greater than 2:importjschemalitebig_circle_schema=circle.copy()big_circle_schema['center']=[None,None]#match 2-element listsbig_circle_schema['radius']={'!minimum':2}#match any radius >= 2print(jschemalite.match(circle,big_circle_schema))#prints FalseBasic schema rulesAn object will always match itself.None: An object will always match with None.list: The object must be a list of the same length as the rule.
Each item must match the corresponding item in the rule.dict: A dict rule states which keys must exist in the object,
EXCEPT for special rules (i.e., keys prefixed with “!”). Each
subkey’s value must match the rule under the corresponding subkey in
the dict.Special rulesSpecial rules are always dicts, with keys prefixed with “!”. Special
keys are patterned after JSON Schema specifiers, and include the
following:!type[str or list]: accept any object of this type. Accepts JSON
Schema “string”, “number”, “integer”, “array”, “object”, “boolean”,
“null” as well as Python class names ‘str’, ‘float’, ‘int’, ‘list’,
‘dict’. or ‘bool’.If a list is given, multiple types are accepted.!enumlist: accept any object that matches one of the items in the list.!minimumvalue: accept numeric values that are >= value!maximumvalue: accept numeric values that are <= value!exclusiveMinimumvalue: accept numeric values that are > value!exclusiveMaximumvalue: accept numeric values that are < value!propertiesdict: designates a dict of possible properties (keys).
The property name will map to its specification. Note that like JSON
Schema, properties are optional.!additionalPropertiesbool: if False, will not allow any other
properties in a dictionary than are specified in the rule.!requiredlist: a list of property names that are required.!minPropertiesvalue: must have at least this number of properties!minPropertiesvalue: must have at least this number of properties!itemsrule: for lists/arrays, all items must match this rule. (Note: can’t specify multiple item rules as in JSON Schema)!minItemsvalue: lists/arrays must have at least this number of items.!maxItemsvalue: lists/arrays must have at most this number of items.!anyOflist: any of the rules given in the list may match.!lengthvalue: length specifier, works for either dicts or lists.!orlist: alias for!anyOf.!valueval: takes on value val.  Usually you’d want to just replace the dict
with val, but for quick insertion of fixed values into an existing schema, this
will do in a pinch.!empty: matches with nothing (not even None). Used to specify that a key should
not be present in a dict.ExamplesBasic examples:fromjschemaliteimportmatchobj={'a':3,'b':{'foo':'bar','baz':[0.4,0.2]}}schema1={'a':None,'b':None}#dict must have keys 'a' and 'b'schema2={'!properties':{'a':None,'b':None,'c':None}}#dict may have keys 'a', 'b', and 'c'schema3={'a':None,'b':{'foo':None,'baz':None}}#dict must have the top-level key structureschema4={'b':{'foo':None}}#dict must have at least as many keys as are specifiedarray_schema={'!type':'array'}#object must be an arraysize2_array_schema={'!type':'array','!length':2}#object must be a length-2 arrayprint(match(obj,obj),"= True")#an object matches itselfprint(match(obj,schema1),"= True")#it matches the schemaprint(match(obj,schema2),"= True")#it matches the schemaprint(match(obj,schema3),"= True")#it matches the schemaprint(match(obj,schema4),"= True")#it matches the schemaprint(match(obj,array_schema),"= False")#it's not an arrayprint(match(obj['b']['baz'],size2_array_schema),"= True")#it's a length 2 arrayenum_schema={'!enum':["One","Two","Three"]}#this is how you specify an enumprint(match("One",enum_schema))print(match([1],enum_schema))SamplingWe can also sample objects that match a schema using thesample_matchfunction. This works best when numeric items have a
minimum and maximum.ConversionsCan convert to JSON Schema usingto_json_schema.No conversions from JSON Schema back to JSON Schema Lite yet.JSON Schema Lite objects can be converted to MongoDB queries.fromjschemalite.mongodbimportjschemalite_to_mongodbmongodb_query=jschemalite_to_mongodb(jsl_query)