另一个python api模式通过输入注释进行处理;轻巧、简单、强大。
pyapischema的Python项目详细描述
APISchema
另一个python api模式通过输入注释进行处理;轻巧、简单、强大。
开始
使用pip install pyapischema
安装(我目前在pypi上声明apischema
名称)。
按照下面的示例使用它
示例
简单示例:
importjsonimportuuidfromdataclassesimportdataclassfromtypingimportIterator,Sequencefromapischema.dataimportfrom_data,to_datafromapischema.modelimportModelfromapischema.schemaimportbuild_schemafromapischema.validatorimportError,validateclassUUID(Model[str],uuid.UUID):pass@dataclassclassMyModel:id:UUIDelts:Sequence[int]check_sum:int@validate("elts","check_sum")defelts_sum(self)->Iterator[Error]:ifsum(self.elts)!=self.check_sum:yield"check_sum doesn't match elts"data=json.load(...)# type: ignore# data = {"id": str(uuid4()), "elts": [1, 2], "check_sum": 3} my_model=from_data(MyModel,data,camel_case=False)data2=to_data(MyModel,my_model,camel_case=False)openapi=build_schema(MyModel,camel_case=False)
稍微复杂一点
from__future__importannotationsfromdataclassesimportdataclass,fieldfromtypingimportList,TypeVar,Union,Iterator,Genericimportpytestfromapischema.dataimportfrom_datafromapischema.modelimportModelfromapischema.validationimportValidationErrorfromapischema.validatorimportError,validateT=TypeVar("T")classA(Model[Union[T,List[T]]],List[T]):@classmethoddeffrom_model(cls,obj:Union[T,List[T]])->A:ifisinstance(obj,list):returnA(obj)else:returnA([obj])defto_model(self)->Union[T,List[T]]:returnself[0]iflen(self)==1elselist(self)@validatedefno_consecutive_duplicates(self)->Iterator[Error]:iflen(self)==0:returncur=self[0]foriinrange(1,len(self)):ifcur==self[i]:yieldf"duplicate elt {cur} in position {i}"cur=self[i]@dataclassclassB(Generic[T]):a:A[T]=field(default_factory=A)deftest():print()print(from_data(B,{}))print(from_data(B[int],{}))print(from_data(B[int],{"a":0}))print(from_data(B[int],{"a":[1,2]}))withpytest.raises(ValidationError)aserr:print(from_data(B[int],{"a":[1,2,2]}))print(err.value)withpytest.raises(ValidationError)aserr:print(from_data(B[str],{"a":["",0,1]}))print(err.value)
使用spec:
fromdataclassesimportdataclassfromapischema.dataimportfrom_data,to_datafromapischema.fieldimportfieldfromapischema.modelimportModelfromapischema.schemaimportSchema,build_schemafromapischema.specimportNumSpec,SpecClassclassShortString(Model[str],SpecClass,str):max_length=10@dataclassclassA:positive:int=field(spec=NumSpec(min=0))short_string:ShortString=ShortString("")deftest():# data = json.load(...)data={"positive":1,"shortString":"ok"}a=from_data(A,data)data2=to_data(A,a)print(data2)openapi=build_schema(A)print(to_data(Schema,openapi))