[ ]
ZhouSa.com-周飒博客 1. 结构数据验证
我们的程序往往需要从外部获取数据,比如服务请求都是外部输入数据,比如程序启动可以导入外部设定的配置.通常我们使用json(或者yaml)或者是python中的字典作为外部数据的标准格式.结构数据验证无非是验证字段是否存在,字段值是否符合要求.一个比较通用的数据描述协议是jsonschema其python实现是包jsonschema.
一个比较好的语法描述是Json Schema 快速入门,更加详细的可以看understanding-json-schema
1.1. 例子:
我们来验证如下的json格式描述的用户
{ "name": "Emily", "age": 123, "email":"[email protected]" "gender": "female", "like_film":["a","b"] }
定义结构
schema = { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://yourdomain.com/schemas/user-schema.json", "title": "User", "description": "用户", "type" : "object", "properties" : { "name" : { "description": "user name", "type" : "string" },"age" : { "description": "user age", "type" : "integer", "minimum": 0, "maximum":140, "exclusiveMaximum": True },"gender":{ "description": "user gender", "type": "string", "enum": ["male", "female"] },"email":{ "description": "user email", "type" : "string", "pattern":r"^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$" },"like_film":{ "description": "user like file's name", "type": "array", "items": { "type": "string" }, } }, "required": [ "name", "age", "gender" ] }
验证字典是否满足结构
from jsonschema import validate
validate(instance={ "name": "Emily", "age": 123, "gender": "female", "like_film":["a","b"] }, schema=schema)
validate(instance={ "name": "Emily", "age": 123, "gender": "female", "email":"[email protected]" }, schema=schema)
validate(instance={ "name": "Emily", "age": 123, "gender": "female", "email":"[email protected]" }, schema=schema)
validate( instance={"name" : "Eggs", "price" : "Invalid"}, schema=schema, )
--------------------------------------------------------------------------- ValidationError Traceback (most recent call last) <ipython-input-6-075aa0c4612f> in <module> 1 validate( ----> 2 instance={"name" : "Eggs", "price" : "Invalid"}, schema=schema, 3 ) ~/Lib/conda/anaconda3/lib/python3.7/site-packages/jsonschema/validators.py in validate(instance, schema, cls, *args, **kwargs) 539 cls = validator_for(schema) 540 cls.check_schema(schema) --> 541 cls(schema, *args, **kwargs).validate(instance) ~/Lib/conda/anaconda3/lib/python3.7/site-packages/jsonschema/validators.py in validate(self, *args, **kwargs) 128 def validate(self, *args, **kwargs): 129 for error in self.iter_errors(*args, **kwargs): --> 130 raise error 131 132 def is_type(self, instance, type): ValidationError: 'age' is a required property Failed validating 'required' in schema: {'description': '用户', 'properties': {'age': {'description': 'user age', 'exclusiveMaximum': True, 'maximum': 140, 'minimum': 0, 'type': 'integer'}, 'email': {'description': 'user email', 'pattern': '^(\\w)+(\\.\\w+)*@(\\w)+((\\.\\w+)+)$', 'type': 'string'}, 'gender': {'description': 'user gender', 'enum': ['male', 'female'], 'type': 'string'}, 'like_film': {'description': "user like file's name", 'items': {'type': 'string'}, 'type': 'array'}, 'name': {'description': 'user name', 'type': 'string'}}, 'required': ['name', 'age', 'gender'], 'title': 'User', 'type': 'object'} On instance: {'name': 'Eggs', 'price': 'Invalid'}
jsonschema最大的优点是跨语言,使用同一套描述规范可以在c,cpp,go,js,python之间进行传递,这个类似protobuf,可以做到代码即文件,同时它支持继承,可以维护一个统一的服务用语描述schema,同时支持使用$id
描述自身的维护地址,使用$ref
来引用外部或者别处定义的对象.
还没有评论,来说两句吧...