Package: validict
Descriptionvalidictis a Python module for comparing an unknown value to a
desired template. It is intended for the top-level type to be adict, but should be flexible enough to deal withlists or
scalars (though if you’re dealing at scalars, might I suggest running
away from this and just using Python’sisinstance).Important: this
library specifically does not treat ``tuple``s as template
expectations but instead as a set of expectations for a given position
in a template.UsageInstall withpip.shell~$ pip install validictUsingvalidictis simple. First, declare your template:fromvalidictimportvalidatetemplate={'name':str,'age':int,'pets':[{'name':str,'kind':str}],'parents':([{'name':str}],int,None)}kid={'name':"Bart Simpson",'age':10,'pets':[{'name':"Santa's Little Helper",'kind':"Dog"},{'name':"Snowball II",'kind':"Cat"}],'parents':[{'name':"Homer Simpson"},{'name':"Marge Simpson"}]}validate(template,kid)# returns Truebad_kid={'name':"Nelson Muntz",'age':12}validate(template,bad_kid)# raises FailedValidationErrorvalidate(template,bad_kid,quiet=True)# returns Falseoptional_kid={'name':"Milhouse Van Houten",'age':10,'pets':[{'name':"Lhasa Apso",'kind':"Dog"}],'parents':None# Okay, not really, but for demonstration purposes...}validate(template,optional_kid)# returns TrueYou might be asking yourself – or me – “what the hell is this
garbage?” Allow me to briefly explain, and you’ll see that the template
language is pretty simple.We use plain, naked Pythontypes to indicate that the expected
value for the given key should be an object of that type. So, if the
passed-in dict has a value for'name'that isn’t astr,
validation fails.When we are expecting alistof elements, we only need to declare
in our template one instance of that item, if thelist’s children
are expected to be homogenous. Therefore,'pets'is expected to
be alistofdicts, all containingstrvalue for keys'name'and'kind'.We can use atupleto declare that there may be multiple types of
values, even including (but not demonstrated) further depth of
structure. In the above, the value of'parents'can be adictwith parents’ names, anint(perhaps representing the number of
parents), orNone(if you’re Batman).Callingvalidatewith the template and unvalidated value,
positionally, will result either in a return value ofTrueor a
raise ofFailedValidationError.Callingvalidateas above with the keyword parameterquiet=Truewill returnFalseinstead of raisingFailedValidationErroron validation failure.Allowing aNonetype as adictvalue or as a member of atuplesignifies that the value is optional. Using it in atupleallows you to declare that the value can either be matching
some type or otherwise can be nothing at all.(Undemonstrated) Your template can declare scalar values as well.
So if all inputs must have some specific K/V pair, you can declare
that.Why do I want to use this?If you’re using a web framework like, say,Falconand you wanted to set up abefore hookto validate the body of the incoming HTTP request, the function in this
method is for you. At least that’s why it’s for me.Bonus!There is an experimental (read:not heavily tested) function in this
module calleddeep_merge, which takes as its arguments two
dictionaries. The second will be merged into the first, in a fashion
such that keys are merged on every level instead of top-level key-values
clobbering over all nested data.