Add validator for json structure
authorMagnus Hagander <magnus@hagander.net>
Tue, 26 Jun 2018 18:20:26 +0000 (20:20 +0200)
committerMagnus Hagander <magnus@hagander.net>
Wed, 27 Jun 2018 10:55:04 +0000 (12:55 +0200)
postgresqleu/util/validators.py

index f3150cdf77a446a205bd540c366af7f5088ae2d2..a8f2382cd378b321905949d1635158149ef8855d 100644 (file)
@@ -43,3 +43,32 @@ def TwitterValidator(value):
                raise ValidationError("Could not verify twitter name: {0}".format(r.status_code))
 
        # All is well! :)
+
+
+def validate_json_structure(config, structure):
+       def _validate_json_level(config, structure, path):
+               missing = set(structure.keys()).difference(set(config.keys()))
+               if missing:
+                       raise ValidationError("Keys {0} are missing".format(", ".join(["->".join(path+[m]) for m in missing])))
+               extra = set(config.keys()).difference(set(structure.keys()))
+               if extra:
+                       raise ValidationError("Keys {0} are not allowed".format(", ".join(["->".join(path+[m]) for m in extra])))
+
+               # Keys are correct, validate datatypes
+               for k,v in config.items():
+                       fullkey = "->".join(path+[k])
+                       # Dicts don't have __name__
+                       if type(structure[k]) == dict:
+                               structtype = dict
+                       else:
+                               structtype = structure[k]
+                       structname = structtype.__name__
+                       valname = type(v).__name__
+
+                       if type(v) != structtype:
+                               raise ValidationError("Value for {0} should be of type {1}, not {2}".format(fullkey, structname, valname))
+                       if isinstance(v, dict):
+                               # Recursively check substructure
+                               _validate_json_level(v, structure[k], path+[k])
+
+       _validate_json_level(config, structure, [])