Package: valdec
valdecDecorator for validating arguments and/or result of functions and methods of a class against annotations.Can be used in synchronous or asynchronous version.Validation is supported usingpydantic.BaseModelandvalidated_dc.ValidatedDC.You can easily add support for any other validator. To do this, you need to write your own validator-function and specify it in the settings for decorator (how to do this - see the examples below).Note: if the result of the function has no annotation, the result is expected to beNone.InstallationpipinstallvaldecQuick exampleDefaultBased on the validatorpydantic.BaseModel:pipinstallpydanticfromtypingimportList,OptionalfrompydanticimportBaseModel,StrictInt,StrictStrfromvaldec.decoratorsimportvalidate# from valdec.decorators import async_validate  # Use for async functions@validate# all arguments with annotations and returndeffunc(i:StrictInt,s:StrictStr)->StrictInt:returniassertfunc(1,"s")==1@validate("i",exclude=True)# exclude "i" (only "s" and return)deffunc(i:StrictInt,s:StrictStr)->StrictInt:returnint(i)assertfunc("1","s")==1# For example, an Api got a json-string and decoded it:data_for_group=[{"name":"Peter","profile":{"age":22,"city":"Samara"}},{"name":"Elena","profile":{"age":20,"city":"Kazan"}},]classProfile(BaseModel):age:StrictIntcity:StrictStrclassStudent(BaseModel):name:StrictStrprofile:Profile@validate("s","group")# only "s" and "group"deffunc(i:StrictInt,s:StrictStr,group:Optional[List[Student]]=None):asserti=="i not int"# because "i" is not validatedassertisinstance(s,str)forstudentingroup:# `student` is now an instance of `Student`# (This conversion can be disabled!)assertisinstance(student,Student)assertisinstance(student.name,str)assertisinstance(student.profile.age,int)returngroupresult=func("i not int","string",data_for_group)# The result can be any, because it is not validated.., now this is a list:assertisinstance(result,list)validated_dc_validatorIt is possible to enable validation withvalidated_dc.ValidatedDC. To do this, change the reference to the validator-function in the decorator settings:pipinstallvalidated-dcfromdataclassesimportdataclassfromtypingimportList,Optionalfromvaldec.data_classesimportSettingsfromvaldec.decoratorsimportvalidateas_validatefromvaldec.validator_validated_dcimportvalidatorfromvalidated_dcimportValidatedDCcustom_settings=Settings(validator=validator,# function for validationis_replace_args=True,# defaultis_replace_result=True,# defaultextra={}# default)defvalidate(*args,**kwargs):# define new decoratorkwargs["settings"]=custom_settingsreturn_validate(*args,**kwargs)# The new decorator can now be used:@validate# all arguments with annotations and returndeffunc(i:int,s:str)->int:returniassertfunc(1,"s")==1@validate("s")# only "s"deffunc(i:int,s:str)->int:returniassertfunc("not int","s")=="not int"@validate("s","return")# only "s" and returndeffunc(i:int,s:str)->int:returnint(i)assertfunc("1","s")==1@validate("i",exclude=True)# exclude "i" (only "s" and return)deffunc(i:int,s:str)->int:returnint(i)assertfunc("1","s")==1data_for_group=[{"name":"Peter","profile":{"age":22,"city":"Samara"}},{"name":"Elena","profile":{"age":20,"city":"Kazan"}},]@dataclassclassProfile(ValidatedDC):age:intcity:str@dataclassclassStudent(ValidatedDC):name:strprofile:Profile@validate("s","group")# only "s" and "group"deffunc(i:int,s:str,group:Optional[List[Student]]=None):asserti=="i not int"# because "i" is not validatedassertisinstance(s,str)forstudentingroup:# `student` is now an instance of `Student`# (This behavior can be changed by is_replace_args=False in the# Settings instance)assertisinstance(student,Student)assertisinstance(student.name,str)assertisinstance(student.profile.age,int)returngroupresult=func("i not int","string",data_for_group)# The result can be any, because it is not validated.., now this is a list:assertisinstance(result,list)ErrorsValidationArgumentsErroris raised on an arguments validation error, and aValidationReturnErroron a result validation error:fromtypingimportOptionalfrompydanticimportStrictInt,StrictStrfromvaldec.decoratorsimportvalidatefromvaldec.errorsimportValidationArgumentsError,ValidationReturnErrorclassFoo:@validate# all arguments with annotations and returndefbar_1(self,i:StrictInt,s:Optional[StrictStr]=None):pass@validate("return")# only "return"defbar_2(self,i:StrictInt,s:Optional[StrictStr]=None):returnifoo=Foo()foo.bar_1(1,"2")# oktry:foo.bar_1(1,2)exceptValidationArgumentsErroraserror:print(type(error),error,"\n")foo.bar_2(None,1)# oktry:foo.bar_2(1,2)exceptValidationReturnErroraserror:print(type(error),error)