cerberus地獄犬 (Cerberus是一個(gè)用于Python的輕量級(jí)且可擴(kuò)展的數(shù)據(jù)驗(yàn)證庫)
前言
文章內(nèi)容有點(diǎn)多,是自己學(xué)習(xí)cerberus的記錄,原文,由于篇幅有限定铜,源碼的解析就沒有了,源碼不是很難,具有很高的參考價(jià)值县恕。感謝rino nakasone
的翻譯支持.
CERBERUS, n. The watch-dog of Hades, whose duty it was to guard the entrance; everybody, sooner or later, had to go there, and nobody wanted to carry off the entrance.
- Ambrose Bierce, The Devil’s Dictionary
CERBERUS,地獄的守衛(wèi)犬剂桥,他們的職責(zé)是守衛(wèi)入口; 每個(gè)人遲早都不得不去那里忠烛,沒有人想要走出入口。
- Ambrose Bierce权逗,魔鬼的字典
這是對(duì)cerberus的描述美尸。不過很形象。Cerberus提供了功能強(qiáng)大但簡(jiǎn)單輕便的數(shù)據(jù)驗(yàn)證功能斟薇,其設(shè)計(jì)易于擴(kuò)展师坎,允許自定義驗(yàn)證。它沒有依賴性堪滨,并且已經(jīng)從Python 2.6到3.5胯陋,PyPy和PyPy3進(jìn)行了徹底測(cè)試。
概述
你可以定義一個(gè)驗(yàn)證的模式并將它傳遞給Validator
類的一個(gè)實(shí)例:
>>> schema = {'name': {'type': 'string'}}
>>> v = Validator(schema)
然后袱箱,您只需調(diào)用該模式validate()來驗(yàn)證字典遏乔。如果驗(yàn)證成功,True則返回:
>>> document = {'name': 'john doe'}
>>> v.validate(document)
True
安裝
這部分文檔涵蓋了Cerberus的安裝发笔。使用任何軟件包的第一步是正確安裝它盟萨。
穩(wěn)定版本
Cerberus在PyPI上,所以你需要做的是:
$pip install cerberus
開發(fā)版本
Cerberus是在GitHub上積極開發(fā)的了讨,代碼總是可用的捻激。如果你想使用開發(fā)版本制轰,有兩種方法:你可以讓pip拉入開發(fā)版本,或者你可以告訴它在git checkout上運(yùn)行胞谭。無論哪種方式垃杖,建議使用virtualenv。
在新的virtualenv中獲取git checkout并以開發(fā)模式運(yùn)行丈屹。
$ git clone http://github.com/pyeve/cerberus.git
Initialized empty Git repository in ~/dev/cerberus.git/
$ cd cerberus
$ virtualenv venv --distribute
New python executable in venv/bin/python
Installing distribute............done.
$ . venv/bin/activate
$ python setup.py install
...
Finished processing dependencies for Cerberus
這將拉入依賴關(guān)系并激活git頭缩滨,作為virtualenv中的當(dāng)前版本。然后泉瞻,您只需運(yùn)行即可更新到最新版本脉漏。git pull origin
要獲得沒有g(shù)it的開發(fā)版本,請(qǐng)改為:
$ mkdir cerberus
$ cd cerberus
$ virtualenv venv --distribute
$ . venv/bin/activate
New python executable in venv/bin/python
Installing distribute............done.
$ pip install git+git://github.com/pyeve/cerberus.git
...
Cleaning up...
完成上面你就完成了袖牙!
Cerberus用法
基本用法
您定義一個(gè)驗(yàn)證模式并將其傳遞給Validator該類的一個(gè)實(shí)例 :
>>> schema = {'name': {'type': 'string'}}
>>> v = Validator(schema)
然后侧巨,您只需調(diào)用該模式validate()來驗(yàn)證字典。如果驗(yàn)證成功鞭达,True則返回:
>>> document = {'name': 'john doe'}
>>> v.validate(document)
True
或者司忱,您可以將字典和模式傳遞給 validate()方法:
>>> v = Validator()
>>> v.validate(document, schema)
True
如果您的模式在實(shí)例的生命周期中發(fā)生變化,那么這可能非常方便畴蹭。
有關(guān)驗(yàn)證模式詳細(xì)信息在驗(yàn)證架構(gòu)坦仍。有關(guān)所有受支持規(guī)則的詳細(xì)文檔,請(qǐng)參閱驗(yàn)證規(guī)則和規(guī)范化規(guī)則叨襟。
與其他驗(yàn)證工具不同繁扎,Cerberus在第一個(gè)驗(yàn)證問題上不會(huì)停止并引發(fā)異常。整個(gè)文檔將始終處理糊闽,并且 False如果驗(yàn)證失敗將返回梳玫。然后您可以訪問該 errors屬性以獲取問題列表。查看 錯(cuò)誤和錯(cuò)誤處理以了解不同的輸出選項(xiàng)右犹。
>>> schema = {'name': {'type': 'string'}, 'age': {'type': 'integer', 'min': 10}}
>>> document = {'name': 'Little Joe', 'age': 5}
>>> v.validate(document, schema)
False
>>> v.errors
{'age': ['min value is 10']}
DocumentError當(dāng)文檔不是映射時(shí)引發(fā)A.
Validator類及其實(shí)例是可調(diào)用的提澎,允許使用以下簡(jiǎn)寫語法:
>>> document = {'name': 'john doe'}
>>> v(document)
True
允許未知(Allowing the Unknown)
默認(rèn)情況下,只允許模式中定義的鍵:
>>> schema = {'name': {'type': 'string', 'maxlength': 10}}
>>> v.validate({'name': 'john', 'sex': 'M'}, schema)
False
>>> v.errors
{'sex': ['unknown field']}
然而念链,您可以通過設(shè)allow_unknown
為允許未知的文檔密鑰對(duì) True
:
>>> v.schema = {}
>>> v.allow_unknown = True
>>> v.validate({'name': 'john', 'sex': 'M'})
True
或者你可以設(shè)置allow_unknown
一個(gè)驗(yàn)證模式盼忌,在這種情況下垢村,未知字段將被驗(yàn)證:
>>> v.schema = {}
>>> v.allow_unknown = {'type': 'string'}
>>> v.validate({'an_unknown_field': 'john'})
True
>>> v.validate({'an_unknown_field': 1})
False
>>> v.errors
{'an_unknown_field': ['must be of string type']}
allow_unknown
也可以在初始化時(shí)設(shè)置:
>>> v = Validator({}, allow_unknown=True)
>>> v.validate({'name': 'john', 'sex': 'M'})
True
>>> v.allow_unknown = False
>>> v.validate({'name': 'john', 'sex': 'M'})
False
allow_unknown
也可以設(shè)置為規(guī)則來配置針對(duì)模式規(guī)則檢查的嵌套映射的驗(yàn)證程序:
>>> v = Validator()
>>> v.allow_unknown
False
>>> schema = {
... 'name': {'type': 'string'},
... 'a_dict': {
... 'type': 'dict',
... 'allow_unknown': True, # this overrides the behaviour for
... 'schema': { # the validation of this definition
... 'address': {'type': 'string'}
... }
... }
... }
>>> v.validate({'name': 'john',
... 'a_dict': {'an_unknown_field': 'is allowed'}},
... schema)
True
>>> # this fails as allow_unknown is still False for the parent document.
>>> v.validate({'name': 'john',
... 'an_unknown_field': 'is not allowed',
... 'a_dict':{'an_unknown_field': 'is allowed'}},
... schema)
False
>>> v.errors
{'an_unknown_field': ['unknown field']}
在版本0.9中更改:allow_unknown
也可以為嵌套的字典字段設(shè)置目溉。
在版本0.8中更改:allow_unknown
也可以設(shè)置為驗(yàn)證模式。
獲取已處理的文檔(Fetching Processed Documents)
標(biāo)準(zhǔn)化和強(qiáng)制是在原始文檔的副本上執(zhí)行的按傅,結(jié)果文檔通過document-property
可用梆暮。
>>> v.schema = {'amount': {'type': 'integer', 'coerce': int}}
>>> v.validate({'amount': '1'})
True
>>> v.document
{'amount': 1}
除了document-property
之外服协,- Validator實(shí)例還具有處理文檔并獲取處理結(jié)果的速記方法。
驗(yàn)證方法(validated Method)
有一個(gè)包裝器方法validated()
返回經(jīng)過驗(yàn)證的文檔啦粹。如果文檔沒有驗(yàn)證None
返回偿荷,除非您調(diào)用關(guān)鍵字參數(shù)always_return_document
設(shè)置為的方法True。對(duì)于這樣的流程可能很有用:
v = Validator(schema)
valid_documents = [x for x in [v.validated(y) for y in documents]
if x is not None]
如果強(qiáng)制可調(diào)用或方法引發(fā)異常唠椭,那么異常將被捕獲并且驗(yàn)證失敗跳纳。
0.9版本中的新功能。
標(biāo)準(zhǔn)化的方法(normalized Method)
同樣贪嫂,該normalized()
方法返回文檔的規(guī)范化副本而不驗(yàn)證它:
>>> schema = {'amount': {'coerce': int}}
>>> document = {'model': 'consumerism', 'amount': '1'}
>>> normalized_document = v.normalized(document, schema)
>>> type(normalized_document['amount'])
<class 'int'>
1.0版中的新功能寺庄。
Warnings
通過Python標(biāo)準(zhǔn)庫的warnings
模塊發(fā)出警告,例如關(guān)于棄用或可能的故障原因力崇。日志模塊可以配置為捕獲這些logging.captureWarnings()
斗塘。
驗(yàn)證模式(Validation Schemas)
驗(yàn)證模式validation schema是一種映射,通常是一種映射dict亮靴。模式key是目標(biāo)字典中允許的key馍盟。模式值表示必須與相應(yīng)目標(biāo)值匹配的規(guī)則。
schema = {'name': {'type': 'string', 'maxlength': 10}}
在上面的例子中茧吊,我們定義了一個(gè)只有一個(gè)關(guān)鍵字的目標(biāo)字典贞岭,name
預(yù)期這個(gè)關(guān)鍵字不會(huì)超過10個(gè)字符。類似的東西 會(huì)驗(yàn)證搓侄,而類似或不會(huì)瞄桨。{'name': 'john doe'}{'name': 'a very long string'}或{'name': 99}
默認(rèn)情況下,文檔中的所有鍵都是可選的讶踪,除非將所需的規(guī)則設(shè)置為鍵芯侥。
注冊(cè) (Registries)
cerberus模塊名稱空間中有兩個(gè)默認(rèn)注冊(cè)表,您可以在其中存儲(chǔ)模式和規(guī)則集的定義乳讥,然后可以在驗(yàn)證模式中引用它們筹麸。您還可以更實(shí)例化Registry
對(duì)象,并將其綁定到 rules_set_registry
或 schema_registry
驗(yàn)證程序的雏婶。您也可以在初始化時(shí)將它們?cè)O(shè)置為關(guān)鍵字參數(shù)物赶。
如果使用注冊(cè)表特別有趣
- 模式應(yīng)包括對(duì)自己的引用,即vulgo:模式遞歸
- 模式包含很多重用部分留晚,并且支持序列化
>>> from cerberus import schema_registry
>>> schema_registry.add('non-system user',
... {'uid': {'min': 1000, 'max': 0xffff}})
>>> schema = {'sender': {'schema': 'non-system user',
... 'allow_unknown': True},
... 'receiver': {'schema': 'non-system user',
... 'allow_unknown': True}}
>>> from cerberus import rules_set_registry
>>> rules_set_registry.extend((('boolean', {'type': 'boolean'}),
... ('booleans', {'valueschema': 'boolean'})))
>>> schema = {'foo': 'booleans'}
驗(yàn)證(Validation)
驗(yàn)證模式本身在傳遞給驗(yàn)證程序時(shí)進(jìn)行驗(yàn)證酵紫,或者為文檔字段設(shè)置一組新的規(guī)則。SchemaError
當(dāng)遇到無效的驗(yàn)證模式時(shí)引發(fā). 請(qǐng)參閱 驗(yàn)證模式以供參考错维。
但是奖地,請(qǐng)注意,對(duì)于低于該級(jí)別的所有更改或注冊(cè)表中使用的定義更改時(shí)赋焕,都不會(huì)觸發(fā)驗(yàn)證参歹。因此您可以觸發(fā)驗(yàn)證并捕獲異常:
>>> v = Validator({'foo': {'allowed': []}})
>>> v.schema['foo'] = {'allowed': 'strings are no valid constraint for allowed'}
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "cerberus/schema.py", line 99, in __setitem__
self.validate({key: value})
File "cerberus/schema.py", line 126, in validate
self._validate(schema)
File "cerberus/schema.py", line 141, in _validate
raise SchemaError(self.schema_validator.errors)
SchemaError: {'foo': {'allowed': 'must be of list type'}}
>>> v.schema['foo']['allowed'] = 'strings are no valid constraint for allowed'
>>> v.schema.validate()
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "cerberus/schema.py", line 126, in validate
self._validate(schema)
File "cerberus/schema.py", line 141, in _validate
raise SchemaError(self.schema_validator.errors)
SchemaError: {'foo': {'allowed': 'must be of list type'}}
序列化(Serialization)
Cerberus的模式都有內(nèi)建的Python類型:dict
,list
隆判, string
等犬庇。即使用戶自定義的驗(yàn)證規(guī)則在模式中通過名稱調(diào)用作為一個(gè)字符串僧界。這種設(shè)計(jì)的一個(gè)有用的副作用是可以用多種方式定義模式,例如使用PyYAML臭挽。
>>> import yaml
>>> schema_text = '''
... name:
... type: string
... age:
... type: integer
... min: 10
... '''
>>> schema = yaml.load(schema_text)
>>> document = {'name': 'Little Joe', 'age': 5}
>>> v.validate(document, schema)
False
>>> v.errors
{'age': ['min value is 10']}
你當(dāng)然不必使用YAML捂襟,你可以使用你最喜歡的序列化器。 json
,只要有一個(gè)可以產(chǎn)生嵌套的解碼器欢峰,就 dict
可以用它來定義一個(gè)模式葬荷。
為了填充和回收其中一個(gè)注冊(cè)表,請(qǐng)使用 extend()
和all
驗(yàn)證規(guī)則(Validation Rules)
allow_unknown
在驗(yàn)證映射以設(shè)置子文檔驗(yàn)證程序的屬性時(shí)纽帖,可以將它與模式規(guī)則 結(jié)合使用 allow_unknown
.
allowed
如果目標(biāo)值是可迭代的宠漩,則其所有成員必須位于允許的值列表中。其他類型的目標(biāo)值將驗(yàn)證該值是否在該列表中懊直。
>>> v.schema = {'role': {'type': 'list', 'allowed': ['agent', 'client', 'supplier']}}
>>> v.validate({'role': ['agent', 'supplier']})
True
>>> v.validate({'role': ['intern']})
False
>>> v.errors
{'role': ["unallowed values ['intern']"]}
>>> v.schema = {'role': {'type': 'string', 'allowed': ['agent', 'client', 'supplier']}}
>>> v.validate({'role': 'supplier'})
True
>>> v.validate({'role': 'intern'})
False
>>> v.errors
{'role': ['unallowed value intern']}
>>> v.schema = {'a_restricted_integer': {'type': 'integer', 'allowed': [-1, 0, 1]}}
>>> v.validate({'a_restricted_integer': -1})
True
>>> v.validate({'a_restricted_integer': 2})
False
>>> v.errors
{'a_restricted_integer': ['unallowed value 2']}
在版本0.5.1中進(jìn)行了更改:添加了對(duì)int類型的支持扒吁。
allof
驗(yàn)證是否所有提供的約束都驗(yàn)證該字段。
0.9版本中的新功能吹截。
anyof
驗(yàn)證是否有任何提供的約束條件驗(yàn)證該字段瘦陈。
0.9版本中的新功能。
dependencies
如果文檔中存在定義的字段波俄,則此規(guī)則允許定義單個(gè)字段名稱晨逝,字段名稱序列或字段名稱映射以及文檔中所依賴的允許值序列。
>>> schema = {'field1': {'required': False}, 'field2': {'required': False, 'dependencies': 'field1'}}
>>> document = {'field1': 7}
>>> v.validate(document, schema)
True
>>> document = {'field2': 7}
>>> v.validate(document, schema)
False
>>> v.errors
{'field2': ["field 'field1' is required"]}
當(dāng)多個(gè)字段名稱被定義為依賴關(guān)系時(shí)懦铺,所有這些都必須存在才能驗(yàn)證目標(biāo)字段捉貌。
>>> schema = {'field1': {'required': False}, 'field2': {'required': False},
... 'field3': {'required': False, 'dependencies': ['field1', 'field2']}}
>>> document = {'field1': 7, 'field2': 11, 'field3': 13}
>>> v.validate(document, schema)
True
>>> document = {'field2': 11, 'field3': 13}
>>> v.validate(document, schema)
False
>>> v.errors
{'field3': ["field 'field1' is required"]}
當(dāng)提供一個(gè)映射關(guān)系時(shí),不僅僅所有依賴項(xiàng)都必須存在冬念,然而它們的所有允許值都必須匹配趁窃。
>>> schema = {'field1': {'required': False},
... 'field2': {'required': True, 'dependencies': {'field1': ['one', 'two']}}}
>>> document = {'field1': 'one', 'field2': 7}
>>> v.validate(document, schema)
True
>>> document = {'field1': 'three', 'field2': 7}
>>> v.validate(document, schema)
False
>>> v.errors
{'field2': ["depends on these values: {'field1': ['one', 'two']}"]}
>>> # same as using a dependencies list
>>> document = {'field2': 7}
>>> v.validate(document, schema)
False
>>> v.errors
{'field2': ["depends on these values: {'field1': ['one', 'two']}"]}
>>> # one can also pass a single dependency value
>>> schema = {'field1': {'required': False}, 'field2': {'dependencies': {'field1': 'one'}}}
>>> document = {'field1': 'one', 'field2': 7}
>>> v.validate(document, schema)
True
>>> document = {'field1': 'two', 'field2': 7}
>>> v.validate(document, schema)
False
>>> v.errors
{'field2': ["depends on these values: {'field1': 'one'}"]}
也支持使用.
符號(hào)聲明對(duì)子文檔字段的依賴關(guān)系:
>>> schema = {
... 'test_field': {'dependencies': ['a_dict.foo', 'a_dict.bar']},
... 'a_dict': {
... 'type': 'dict',
... 'schema': {
... 'foo': {'type': 'string'},
... 'bar': {'type': 'string'}
... }
... }
... }
>>> document = {'test_field': 'foobar', 'a_dict': {'foo': 'foo'}}
>>> v.validate(document, schema)
False
>>> v.errors
{'test_field': ["field 'a_dict.bar' is required"]}
在處理子文檔時(shí),查詢字段的問題始于該文檔的級(jí)別急前。為了將處理的文檔作為根級(jí)別進(jìn)行處理醒陆,聲明必須以^
開頭。兩個(gè)首^^
字符(^^)
的出現(xiàn)被解釋為一個(gè)文字裆针,單個(gè)^
沒有特殊含義刨摩。
>>> schema = {
... 'test_field': {},
... 'a_dict': {
... 'type': 'dict',
... 'schema': {
... 'foo': {'type': 'string'},
... 'bar': {'type': 'string', 'dependencies': '^test_field'}
... }
... }
... }
>>> document = {'a_dict': {'bar': 'bar'}}
>>> v.validate(document, schema)
False
>>> v.errors
{'a_dict': [{'bar': ["field '^test_field' is required"]}]}
注意
如果要擴(kuò)展點(diǎn)符號(hào)的語義,可以 覆蓋該_lookup_field()
方法世吨。
注意
該規(guī)則的評(píng)估不考慮用所需規(guī)則定義的任何約束條件澡刹。
在版本1.0.2中更改:支持絕對(duì)尋址^
。
在版本0.8.1中更改:支持將子文檔字段作為依賴項(xiàng)耘婚。
在版本0.8中進(jìn)行了更改:支持將依賴項(xiàng)作為字典罢浇。
0.7版中的新功能。
empty
如果False驗(yàn)證一個(gè)可迭代的值將失敗,如果它是空的嚷闭。將它設(shè)置為True
手動(dòng)是毫無意義的攒岛,因?yàn)樗男袨榫拖裢耆雎砸?guī)則一樣。
>>> schema = {'name': {'type': 'string', 'empty': False}}
>>> document = {'name': ''}
>>> v.validate(document, schema)
False
>>> v.errors
{'name': ['empty values not allowed']}
新版本0.0.3凌受。
excludes
您可以聲明字段以排除其他字段:
>>> v = Validator()
>>> schema = {'this_field': {'type': 'dict',
... 'excludes': 'that_field'},
... 'that_field': {'type': 'dict',
... 'excludes': 'this_field'}}
>>> v.validate({'this_field': {}, 'that_field': {}}, schema)
False
>>> v.validate({'this_field': {}}, schema)
True
>>> v.validate({'that_field': {}}, schema)
True
>>> v.validate({}, schema)
True
您可以要求這兩個(gè)字段構(gòu)建 排除
或 '':
>>> v = Validator()
>>> schema = {'this_field': {'type': 'dict',
... 'excludes': 'that_field',
... 'required': True},
... 'that_field': {'type': 'dict',
... 'excludes': 'this_field',
... 'required': True}}
>>> v.validate({'this_field': {}, 'that_field': {}}, schema)
False
>>> v.validate({'this_field': {}}, schema)
True
>>> v.validate({'that_field': {}}, schema)
True
>>> v.validate({}, schema)
False
您也可以傳遞多個(gè)字段以exclude
在列表中:
>>> schema = { 'this_field' : { 'type' : 'dict' 阵子,
... 'excludes' : [ 'that_field' 思杯, 'bazo_field' ]}胜蛉,
... 'that_field' : { 'type' : ' dict' ,
... 'excludes' : 'this_field' }色乾,
... 'bazo_field' : { 'type' : 'dict' }}
>>> v 誊册。驗(yàn)證({ 'this_field' : {}, 'bazo_field': {}}暖璧, schema )
False
forbidden
相反 允許
此驗(yàn)證案怯,如果值是定義值中的任何一個(gè),但:
>>> schema = {'user': {'forbidden': ['root', 'admin']}}
>>> document = {'user': 'root'}
>>> v.validate(document, schema)
False
1.0版中的新功能澎办。
items
根據(jù)必須驗(yàn)證每個(gè)索引對(duì)應(yīng)項(xiàng)目的規(guī)則序列驗(yàn)證任何迭代項(xiàng)目嘲碱。如果給定的迭代器的大小與定義匹配,這些項(xiàng)目才會(huì)被評(píng)估局蚀。
>>> schema = {'list_of_values': {'type': 'list', 'items': [{'type': 'string'}, {'type': 'integer'}]}}
>>> document = {'list_of_values': ['hello', 100]}
>>> v.validate(document, schema)
True
>>> document = {'list_of_values': [100, 'hello']}
>>> v.validate(document, schema)
False
請(qǐng)參閱用于處理任意長(zhǎng)度類型的shema(list)規(guī)則list麦锯。
keyschema
映射
mapping 的所有鍵的驗(yàn)證模式。
>>> v.schema = {'a_nullable_integer': {'nullable': True, 'type': 'integer'}, 'an_integer': {'type': 'integer'}}
>>> v.validate({'a_nullable_integer': 3})
True
>>> v.validate({'a_nullable_integer': None})
True
>>> v.validate({'an_integer': 3})
True
>>> v.validate({'an_integer': None})
False
>>> v.errors
{'an_integer': ['null value not allowed']}
0.9版本中的新功能琅绅。
版本1.0更改:重命名propertyschema
為keyschema
min扶欣,max
允許實(shí)現(xiàn)比較運(yùn)算符的任何類型的最小值和最大值。
版本1.0中更改:允許比較任何類型千扶。
在0.7版本改變:增加了對(duì)支持float
和number
類型料祠。
minlength,maxlength
MINLENGTH個(gè),最大長(zhǎng)度
迭代次數(shù)允許的最小和最大長(zhǎng)度澎羞。
noneof
驗(yàn)證是否沒有提供的約束條件驗(yàn)證該字段髓绽。有關(guān)詳細(xì)信息,請(qǐng)參閱*of-rules規(guī)則妆绞。
0.9版本中的新功能顺呕。
nullable
如果True
字段值可以設(shè)置為None
。它本質(zhì)上ignore_none_values
是一個(gè)Validator
實(shí)例的屬性的功能摆碉,但是允許更細(xì)粒度的控制直至字段級(jí)別塘匣。
>>> v.schema = {'a_nullable_integer': {'nullable': True, 'type': 'integer'}, 'an_integer': {'type': 'integer'}}
>>> v.validate({'a_nullable_integer': 3})
True
>>> v.validate({'a_nullable_integer': None})
True
>>> v.validate({'an_integer': 3})
True
>>> v.validate({'an_integer': None})
False
>>> v.errors
{'an_integer': ['null value not allowed']}
在版本0.7中更改:nullable
在缺少類型定義的字段上有效。
0.3.0版本的新功能巷帝。
of-rules
這些規(guī)則允許您列出多組要驗(yàn)證的規(guī)則忌卤。如果根據(jù)前綴邏輯列表驗(yàn)證對(duì)集中的領(lǐng)域?qū)⒈灰暈橛行?code>all,any
楞泼,one
或none
驰徊。
allof |
驗(yàn)證是否所有提供的約束都驗(yàn)證該字段笤闯。 |
---|---|
anyof |
驗(yàn)證是否有任何提供的約束條件驗(yàn)證該字段。 |
noneof |
驗(yàn)證是否沒有提供的約束條件驗(yàn)證該字段棍厂。 |
oneof |
驗(yàn)證所提供的約束是否有恰好適用颗味。 |
例如,要驗(yàn)證屬性是介于0到10還是100和110之間的數(shù)字牺弹,可以執(zhí)行以下操作:
>>> schema = {'prop1':
... {'type': 'number',
... 'anyof':
... [{'min': 0, 'max': 10}, {'min': 100, 'max': 110}]}}
>>> document = {'prop1': 5}
>>> v.validate(document, schema)
True
>>> document = {'prop1': 105}
>>> v.validate(document, schema)
True
>>> document = {'prop1': 55}
>>> v.validate(document, schema)
False
>>> v.errors
{'prop1': {'anyof': 'no definitions validated', 'definition 1': 'min value is 100', 'definition 0': 'max value is 10'}}
該anyof
規(guī)則通過為列表中的每個(gè)項(xiàng)目創(chuàng)建模式的新實(shí)例浦马。上述模式等同于創(chuàng)建兩個(gè)單獨(dú)的模式:
>>> schema1 = {'prop1': {'type': 'number', 'min': 0, 'max': 10}}
>>> schema2 = {'prop1': {'type': 'number', 'min': 100, 'max': 110}}
>>> document = {'prop1': 5}
>>> v.validate(document, schema1) or v.validate(document, schema2)
True
>>> document = {'prop1': 105}
>>> v.validate(document, schema1) or v.validate(document, schema2)
True
>>> document = {'prop1': 55}
>>> v.validate(document, schema1) or v.validate(document, schema2)
False
0.9版本中的新功能。
of-rules typesaver
您可以使用規(guī)則值列表將任何規(guī)則與下劃線和另一個(gè)規(guī)則連接起來以保存輸入:
{'foo': {'anyof_type': ['string', 'integer']}}
# is equivalent to
{'foo': {'anyof': [{'type': 'string'}, {'type': 'integer'}]}}
因此张漂,您可以使用它來根據(jù)多個(gè)模式驗(yàn)證文檔晶默,而無需執(zhí)行自己的邏輯:
>>> schemas = [{'department': {'required': True, 'regex': '^IT$'}, 'phone': {'nullable': True}},
... {'department': {'required': True}, 'phone': {'required': True}}]
>>> emloyee_vldtr = Validator({'employee': {'oneof_schema': schemas, 'type': 'dict'}}, allow_unknown=True)
>>> invalid_employees_phones = []
>>> for employee in employees:
... if not employee_vldtr.validate(employee):
... invalid_employees_phones.append(employee)
oneof
驗(yàn)證所提供的約束是否有一個(gè)恰好適用。有關(guān)詳細(xì)信息航攒,請(qǐng)參閱*規(guī)則磺陡。
0.9版本中的新功能。
readonly
如果True該值是只讀的漠畜。如果此字段出現(xiàn)在目標(biāo)字典中币他,則驗(yàn)證將失敗。例如憔狞,在接收要在發(fā)送到數(shù)據(jù)存儲(chǔ)之前要驗(yàn)證的有效載荷時(shí)蝴悉,這非常有用。該字段可能由數(shù)據(jù)存儲(chǔ)提供躯喇,但不應(yīng)寫入辫封。
在版本1.0.2中更改:可以與default
和一起使用default_setter
。
regex 正則
如果字段值與提供的正則表達(dá)式不匹配廉丽,則驗(yàn)證將失敗倦微。它只在字符串值上進(jìn)行測(cè)試。
>>> schema = {'email': {'type': 'string', 'regex': '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'}}
>>> document = {'email': 'john@example.com'}
>>> v.validate(document, schema)
True
>>> document = {'email': 'john_at_example_dot_com'}
>>> v.validate(document, schema)
False
>>> v.errors
{'email': ["value does not match regex '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$'"]}
有關(guān)正則表達(dá)式語法的詳細(xì)信息正压,請(qǐng)參閱標(biāo)準(zhǔn)庫的re-module 文檔欣福。請(qǐng)注意,您可以將標(biāo)志設(shè)置為表達(dá)式的一部分焦履,并(?aiLmsux)在該文檔中查找拓劝。
0.7版中的新功能。
required
如果True該字段是強(qiáng)制性的嘉裤。缺失時(shí)驗(yàn)證失敗郑临,除非validate()在以下情況下調(diào)用update=True:
>>> v.schema = {'name': {'required': True, 'type': 'string'}, 'age': {'type': 'integer'}}
>>> document = {'age': 10}
>>> v.validate(document)
False
>>> v.errors
{'name': ['required field']}
>>> v.validate(document, update=True)
True
注意
具有空值的字符串字段仍將被驗(yàn)證,即使 required設(shè)置為True屑宠。如果您不想接受空值厢洞,請(qǐng)參閱空白規(guī)則。
注意
此規(guī)則的評(píng)估不考慮依賴關(guān)系規(guī)則中定義的任何約束條件。
在版本0.8中更改:檢查字段依賴關(guān)系躺翻。
schema(dict)
如果為其schema定義了一個(gè)-rule 的字段具有作為值的映射丧叽,則該映射將根據(jù)作為約束提供的模式進(jìn)行驗(yàn)證。
>>> schema = {'a_dict': {'type': 'dict', 'schema': {'address': {'type': 'string'},
... 'city': {'type': 'string', 'required': True}}}}
>>> document = {'a_dict': {'address': 'my address', 'city': 'my town'}}
>>> v.validate(document, schema)
True
注意
要驗(yàn)證映射的任意鍵公你,請(qǐng)參閱keyschema
和resp
踊淳。 valueschema
用于驗(yàn)證映射的任意值。
schema (list)
如果schema-validation遇到一個(gè)arbritrary大小的序列作為值陕靠,序列中的所有項(xiàng)目將根據(jù)在schema
約束條件中提供的規(guī)則進(jìn)行驗(yàn)證 迂尝。
>>> schema = {'a_list': {'type': 'list', 'schema': {'type': 'integer'}}}
>>> document = {'a_list': [3, 4, 5]}
>>> v.validate(document, schema)
True
類型上的模式規(guī)則list也是定義和驗(yàn)證字典列表的首選方法。
注意
使用這個(gè)規(guī)則應(yīng)該伴隨著一個(gè)規(guī)則懦傍,像這個(gè)例子一樣type明確地限制字段為list-type雹舀。否則芦劣,當(dāng)映射根據(jù)此規(guī)則與序列約束進(jìn)行驗(yàn)證時(shí)粗俱,可能會(huì)出現(xiàn)錯(cuò)誤結(jié)果。
>>> schema = {'rows': {'type': 'list',
... 'schema': {'type': 'dict', 'schema': {'sku': {'type': 'string'},
... 'price': {'type': 'integer'}}}}}
>>> document = {'rows': [{'sku': 'KT123', 'price': 100}]}
>>> v.validate(document, schema)
True
在版本0.0.3中更改:list任意長(zhǎng)度類型的架構(gòu)規(guī)則
type
數(shù)據(jù)類型允許使用鍵值虚吟〈缛希可以是以下名稱之一:
類型名稱 | Python 2類型 | Python 3類型 |
---|---|---|
boolean |
bool |
bool |
binary |
bytes [1], bytearray
|
bytes , bytearray
|
date |
datetime.date |
datetime.date |
datetime |
datetime.datetime |
datetime.datetime |
dict |
collections.Mapping |
collections.abc.Mapping |
float |
float |
float |
integer |
int , long
|
int |
list |
collections.Sequence ,不含串慰。 string
|
collections.abc.Sequence 偏塞,不含。 string
|
number |
float 邦鲫,int 灸叼,long ,不包括庆捺。bool
|
float 古今,int ,不包括滔以。bool
|
set |
set |
set |
string |
basestring() |
str |
您可以擴(kuò)展此列表并支持自定義類型捉腥。 類型列表可以用來允許不同的值:
>>> v.schema = {'quotes': {'type': ['string', 'list']}}
>>> v.validate({'quotes': 'Hello world!'})
True
>>> v.validate({'quotes': ['Do not disturb my circles!', 'Heureka!']})
True
>>> v.schema = {'quotes': {'type': ['string', 'list'], 'schema': {'type': 'string'}}}
>>> v.validate({'quotes': 'Hello world!'})
True
>>> v.validate({'quotes': [1, 'Heureka!']})
False
>>> v.errors
{'quotes': [{0: ['must be of string type']}]}
注意
盡管該type
規(guī)則根本不需要設(shè)置,但不鼓勵(lì)將其解除設(shè)置你画,尤其是在使用更復(fù)雜的規(guī)則(如schema
抵碟。如果您決定仍然不想設(shè)置顯式類型,schema
則僅將規(guī)則應(yīng)用于實(shí)際可以使用規(guī)則的值(如dict
和list
)坏匪。此外拟逮, schema
Cerberus會(huì)嘗試確定一個(gè)list
或一個(gè)dict
類型規(guī)則是否更合適,并根據(jù)schema
規(guī)則的外觀來推斷它适滓。
注意
請(qǐng)注意敦迄,類型驗(yàn)證是在大多數(shù)其他字段存在于同一字段之前執(zhí)行的(預(yù)先僅考慮可空和只讀)。在發(fā)生類型故障時(shí),字段中的后續(xù)驗(yàn)證規(guī)則將被跳過颅崩,并且驗(yàn)證將在其他字段上繼續(xù)几于。這允許在調(diào)用其他(標(biāo)準(zhǔn)或自定義)規(guī)則時(shí)安全地假定字段類型正確。
版本1.0中更改:添加了binary
數(shù)據(jù)類型沿后。
在版本0.9中更改:如果給出類型列表沿彭,則鍵值必須匹配其中的任何一個(gè)。
在0.7.1版本中更改:dict
和list
類型檢查尖滚,現(xiàn)在有更一般的執(zhí)行 Mapping
和Sequence
類型從內(nèi)置collections
模塊喉刘。這意味著可以使用Cerberus驗(yàn)證與內(nèi)置dict
和list
類型設(shè)計(jì)為相同接口的自定義類型的實(shí)例。在檢查list
/ 時(shí)漆弄,我們排除了字符串睦裳,Sequence
因?yàn)樗隍?yàn)證情況下幾乎確定字符串不是序列的預(yù)期數(shù)據(jù)類型。
版本0.7中更改:添加了set
數(shù)據(jù)類型撼唾。
在版本0.6中更改:添加了number
數(shù)據(jù)類型廉邑。
在版本0.4.0中進(jìn)行了更改:類型驗(yàn)證總是首先執(zhí)行,并在失敗時(shí)阻止其他字段驗(yàn)證規(guī)則倒谷。
在版本0.3.0中更改:添加了float
數(shù)據(jù)類型蛛蒙。
validator
通過調(diào)用函數(shù)或方法來驗(yàn)證值。
一個(gè)函數(shù)必須像這樣實(shí)現(xiàn)以下原型:
def validationname(field, value, error):
if value is invalid:
error(field, 'error message')
該error
參數(shù)指向調(diào)用驗(yàn)證的_error
方法渤愁。有關(guān)如何提交錯(cuò)誤牵祟,請(qǐng)參閱 擴(kuò)展Cerberus。
下面是一個(gè)測(cè)試整數(shù)是否為奇數(shù)的例子:
def oddity(field, value, error):
if not value & 1:
error(field, "Must be an odd number")
然后抖格,你可以驗(yàn)證這樣一個(gè)值:
>>> schema = {'amount': {'validator': oddity}}
>>> v = Validator(schema)
>>> v.validate({'amount': 10})
False
>>> v.errors
{'amount': ['Must be an odd number']}
>>> v.validate({'amount': 9})
True
如果規(guī)則的約束是一個(gè)字符串诺苹,那么該Validator
實(shí)例必須有一個(gè)前綴為該名稱的方法_validator_
。請(qǐng)參閱 擴(kuò)展Cerberus以獲得與上述基于功能的示例等效的內(nèi)容雹拄。
約束條件也可以是連續(xù)調(diào)用的一系列條件收奔。
schema = {'field': {'validator': [oddity, 'prime number']}}
valueschema
對(duì)映射的所有值進(jìn)行驗(yàn)證模式。
>>> schema = {'numbers': {'type': 'dict', 'valueschema': {'type': 'integer', 'min': 10}}}
>>> document = {'numbers': {'an integer': 10, 'another integer': 100}}
>>> v.validate(document, schema)
True
>>> document = {'numbers': {'an integer': 9}}
>>> v.validate(document, schema)
False
>>> v.errors
{'numbers': [{'an integer': ['min value is 10']}]}
0.7版中的新功能办桨。
在版本0.9中更改:重命名keyschema
為valueschema
規(guī)范化規(guī)則
規(guī)范化規(guī)則適用于字段筹淫,也schema
適用于映射,以及通過schema
(對(duì)于序列)allow_unknown
呢撞,keyschema
和损姜, 定義為批量操作valueschema
。anyof
不會(huì)處理定義中用于測(cè)試變體(如with)的規(guī)范化規(guī)則殊霞。
重命名字段
您可以在進(jìn)一步處理之前定義要重命名的字段摧阅。
>>> v = Validator({'foo': {'rename': 'bar'}})
>>> v.normalized({'foo': 0})
{'bar': 0}
要讓一個(gè)可調(diào)用的字段或任意字段重命名,您可以定義一個(gè)用于重命名的處理程序绷蹲。如果約束是一個(gè)字符串棒卷,則它指向一個(gè) 自定義方法顾孽。如果約束是可迭代的,則通過該鏈處理該值比规。
>>> v = Validator({}, allow_unknown={'rename_handler': int})
>>> v.normalized({'0': 'foo'})
{0: 'foo'}
>>> even_digits = lambda x: '0' + x if len(x) % 2 else x
>>> v = Validator({}, allow_unknown={'rename_handler': [str, even_digits]})
>>> v.normalized({1: 'foo'})
{'01': 'foo'}
1.0版中的新功能若厚。
清除未知字段(Purging Unknown Fields)
重命名后,如果實(shí)例的purge_unknown
屬性為 未知字段蜒什,則會(huì)清除未知字段 ; 它默認(rèn)為测秸。您可以在初始化時(shí)設(shè)置每個(gè)關(guān)鍵字參數(shù)的屬性,也可以將其設(shè)置為子文檔的規(guī)則(請(qǐng)參閱允許未知)灾常。默認(rèn)是 霎冯。Validator
True``False``allow_unknown``False
>>> v = Validator({'foo': {'type': 'string'}}, purge_unknown=True)
>>> v.normalized({'bar': 'foo'})
{}
1.0版中的新功能。
默認(rèn)值(Default Values)
您可以使用default
規(guī)則為文檔中缺少的字段設(shè)置默認(rèn)值钞瀑。
>>> v.schema = {'amount': {'type': 'integer'}, 'kind': {'type': 'string', 'default': 'purchase'}}
>>> v.normalized({'amount': 1}) == {'amount': 1, 'kind': 'purchase'}
True
>>> v.normalized({'amount': 1, 'kind': None}) == {'amount': 1, 'kind': 'purchase'}
True
>>> v.normalized({'amount': 1, 'kind': 'other'}) == {'amount': 1, 'kind': 'other'}
True
您還可以定義一個(gè)可調(diào)用的默認(rèn)setter來動(dòng)態(tài)設(shè)置默認(rèn)值沈撞。使用當(dāng)前(子)文檔作為唯一參數(shù)調(diào)用可調(diào)用函數(shù)〉袷玻可調(diào)對(duì)象甚至可以相互依賴缠俺,但如果存在無法解析/循環(huán)依賴的情況,則標(biāo)準(zhǔn)化將失敗监徘。如果約束是一個(gè)字符串晋修,則它指向一個(gè)自定義方法。
>>> v.schema = {'a': {'type': 'integer'}, 'b': {'type': 'integer', 'default_setter': lambda doc: doc['a'] + 1}}
>>> v.normalized({'a': 1}) == {'a': 1, 'b': 2}
True
>>> v.schema = {'a': {'type': 'integer', 'default_setter': lambda doc: doc['not_there']}}
>>> v.normalized({})
>>> v.errors
{'a': ["default value for 'a' cannot be set: Circular dependencies of default setters."]}
你甚至可以在同一個(gè)字段上同時(shí)使用default
和只讀凰盔。這將創(chuàng)建一個(gè)無法手動(dòng)賦值的字段,但它將由Cerberus自動(dòng)提供默認(rèn)值倦春。當(dāng)然同樣適用default_setter
户敬。
在版本1.0.2中更改:可以與只讀一起使用。
1.0版中的新功能睁本。
值強(qiáng)制(Value Coercion)
強(qiáng)制允許您在驗(yàn)證文檔之前將可調(diào)用對(duì)象(作為對(duì)象或自定義標(biāo)準(zhǔn)化方法的名稱給定 )應(yīng)用于值尿庐。可調(diào)用的返回值將替換文檔中的新值呢堰。這可以用來轉(zhuǎn)換值或在驗(yàn)證數(shù)據(jù)之前對(duì)數(shù)據(jù)進(jìn)行清理抄瑟。如果約束是可迭代的,則通過該鏈處理該值枉疼。
>>> v.schema = {'amount': {'type': 'integer'}}
>>> v.validate({'amount': '1'})
False
>>> v.schema = {'amount': {'type': 'integer', 'coerce': int}}
>>> v.validate({'amount': '1'})
True
>>> v.document
{'amount': 1}
>>> to_bool = lambda v: v.lower() in ['true', '1']
>>> v.schema = {'flag': {'type': 'boolean', 'coerce': to_bool}}
>>> v.validate({'flag': 'true'})
True
>>> v.document
{'flag': True}
0.9版本中的新功能皮假。
錯(cuò)誤和錯(cuò)誤處理
錯(cuò)誤可以通過Python接口進(jìn)行評(píng)估,或者通過錯(cuò)誤處理程序處理為不同的輸出格式骂维。
錯(cuò)誤處理程序
處理errors
文檔后惹资,錯(cuò)誤處理程序?qū)⑼ㄟ^驗(yàn)證程序的屬性返回不同的輸出 。要使用的錯(cuò)誤處理程序可以作為關(guān)鍵字參數(shù)傳遞 error_handler
給驗(yàn)證程序的初始化航闺,或者在任何時(shí)候通過設(shè)置其屬性具有相同的名稱褪测。在初始化時(shí)猴誊,可以提供一個(gè)實(shí)例或一個(gè)類。要將帶有關(guān)鍵字參數(shù)的字典傳遞給類的初始化侮措,請(qǐng)?zhí)峁┮粋€(gè)包含錯(cuò)誤處理程序和字典的二值元組驾霜。
以下處理程序可用:
BasicErrorHandler
:這是返回字典的默認(rèn)值鞋屈。鍵是指文檔的鍵,值是包含錯(cuò)誤消息的列表。嵌套字段的錯(cuò)誤作為這些列表的最后一項(xiàng)保存在字典中家夺。
Python接口
錯(cuò)誤表示為ValidationError
具有以下屬性:
document_path
:文檔中的路徑。對(duì)于扁平字典萧朝,這只是元組中鍵的名稱腊尚,對(duì)于嵌套元素,它全部遍歷鍵名庵佣。序列中的項(xiàng)目由其索引表示歉胶。schema_path
:架構(gòu)內(nèi)的路徑。code
:錯(cuò)誤的唯一標(biāo)識(shí)符巴粪。查看錯(cuò)誤代碼列表通今。rule
:發(fā)生錯(cuò)誤時(shí)評(píng)估的規(guī)則。constraint
:該規(guī)則的約束肛根。value
:正在驗(yàn)證的值辫塌。info
:此元組包含與錯(cuò)誤一起提交的其他信息。對(duì)于大多數(shù)錯(cuò)誤派哲,這實(shí)際上是沒有的 對(duì)于批量驗(yàn)證(例如使用items
或keyschema
)此屬性保留所有單個(gè)錯(cuò)誤臼氨。查看源代碼中規(guī)則的執(zhí)行情況,以確定其額外的日志記錄芭届。
Validator
處理文檔后储矩,您可以訪問每個(gè)實(shí)例屬性的錯(cuò)誤:
_errors
:該列表包含所有提交的錯(cuò)誤。它不打算通過這個(gè)屬性直接操作錯(cuò)誤褂乍。您可以測(cè)試是否至少有一個(gè)具有特定錯(cuò)誤定義的錯(cuò)誤是in
該列表持隧。document_error_tree
:dict
類似于A 的對(duì)象,允許您查詢與您的文檔相對(duì)應(yīng)的節(jié)點(diǎn)逃片。該節(jié)點(diǎn)的錯(cuò)誤包含在它的errors
屬性中屡拨,您可以測(cè)試該屬性_errors
并在遍歷節(jié)點(diǎn)時(shí)放棄。如果節(jié)點(diǎn)或更低節(jié)點(diǎn)中沒有發(fā)生錯(cuò)誤褥实,None
則會(huì)返回呀狼。schema_error_tree
:與使用的模式類似。
在版本1.0中更改:錯(cuò)誤存儲(chǔ)ValidationError
在a中 ErrorList
性锭。
Examples
>>> schema = {'cats': {'type': 'integer'}}
>>> document = {'cats': 'two'}
>>> v.validate(document, schema)
False
>>> cerberus.errors.BAD_TYPE in v._errors
True
>>> v.document_error_tree['cats'].errors == v.schema_error_tree['cats']['type'].errors
True
>>> error = v.document_error_tree['cats'].errors[0]
>>> error.document_path
('cats',)
>>> error.schema_path
('cats', 'type')
>>> error.rule
'type'
>>> error.constraint
'integer'
>>> error.value
'two'
Cerberus擴(kuò)展
雖然你可以與一起使用的功能coerce
和 validator
規(guī)則赠潦,你可以很容易地?cái)U(kuò)展Validator
與自定義類的規(guī)則,類型草冈,驗(yàn)證她奥,coercers和 default_setters瓮增。雖然基于功能的風(fēng)格更適合特殊用途和一次性用途,但自定義類可以利用這些可能性:
- 自定義規(guī)則可以用模式中的約束來定義
- 擴(kuò)展可用類型小號(hào)
- 使用額外的上下文數(shù)據(jù)
- 模式是可序列化的
模式中對(duì)這些自定義方法的引用可以使用空格字符而不是下劃線哩俭,例如是一個(gè)別名绷跑。{'foo':{'validator': 'is odd'}}``{'foo': {'validator': 'is_odd'}}
自定義規(guī)則
假設(shè)在我們的用例中,一些值只能表示為奇數(shù)整數(shù)凡资,因此我們決定在isodd
驗(yàn)證模式中添加對(duì)新規(guī)則的支持:
schema = { 'amount' : { 'isodd' : True 砸捏, 'type' : 'integer' }}
這是我們將如何去實(shí)現(xiàn)的:
from cerberus import Validator
class MyValidator(Validator):
def _validate_isodd(self, isodd, field, value):
""" Test the oddity of a value.
The rule's arguments are validated against this schema:
{'type': 'boolean'}
"""
if isodd and not bool(value & 1):
self._error(field, "Must be an odd number")
通過繼承Cerberus Validator
類并添加自定義 _validate_<rulename>
方法,我們只是增強(qiáng)了Cerberus以滿足我們的需求隙赁。自定義規(guī)則isodd
現(xiàn)在在我們的模式中可用垦藏,而真正重要的是,我們可以使用它來驗(yàn)證所有奇數(shù)值:
>>> v = MyValidator(schema)
>>> v.validate({'amount': 10})
False
>>> v.errors
{'amount': ['Must be an odd number']}
>>> v.validate({'amount': 9})
True
由于模式本身已經(jīng)過驗(yàn)證伞访,因此可以在規(guī)則的實(shí)現(xiàn)方法的文檔字符串中將約束條件作為文字Python表達(dá)式來驗(yàn)證該規(guī)則的模式中給出的參數(shù)掂骏。文檔字符串只包含字面值,或者文字字符位于文檔字符串的底部厚掷,后面是 更多示例弟灼, 參見貢獻(xiàn)規(guī)則的來源。The rule's arguments are validated againstthis schema:
自定義數(shù)據(jù)類型
Cerberus支持并驗(yàn)證多種標(biāo)準(zhǔn)數(shù)據(jù)類型(請(qǐng)參見類型)冒黑。在構(gòu)建自定義驗(yàn)證器時(shí)田绑,您可以添加和驗(yàn)證自己的數(shù)據(jù)類型。
例如抡爹,Eve(快速構(gòu)建和部署RESTful Web服務(wù)的工具)支持自定義objectid
類型掩驱,用于驗(yàn)證字段值是否符合BSON / MongoDB ObjectId
格式。
通過向_validate_type_<typename>
自己的Validator
子類添加一個(gè)方法來擴(kuò)展支持的數(shù)據(jù)類型集豁延。這段代碼直接來自Eve來源昙篙,顯示了如何objectid
實(shí)現(xiàn):
def _validate_type_objectid(self, value):
""" Enables validation for `objectid` schema attribute.
:param value: field value.
"""
if re.match('[a-f0-9]{24}', value):
return True
新版本0.0.2。
版本1.0中更改:類型驗(yàn)證邏輯已更改诱咏,請(qǐng)參閱升級(jí)到Cerberus 1.0。
自定義驗(yàn)證器
如果驗(yàn)證測(cè)試不依賴于指定的約束缴挖,那么可以將這些驗(yàn)證器定義為規(guī)則而不是規(guī)則袋狞。當(dāng)validator
規(guī)則被賦予一個(gè)字符串作為約束時(shí),它們被調(diào)用 映屋。帶有前綴的匹配方法_validator_
將以field和value作為參數(shù)進(jìn)行調(diào)用:
def _validator_oddity(self, field, value):
if not value & 1:
self._error(field, "Must be an odd number")
自定義Coercers
您還可以定義返回coerce
d值或指向方法的自定義方法rename_handler
苟鸯。方法名稱必須以前綴_normalize_coerce_
。
class MyNormalizer(Validator):
def __init__(self, multiplier, *args, **kwargs):
super(MyNormalizer, self).__init__(*args, **kwargs)
self.multiplier = multiplier
def _normalize_coerce_multiply(self, value):
return value * self.multiplier
>>> schema = {'foo': {'coerce': 'multiply'}}
>>> document = {'foo': 2}
>>> MyNormalizer(2).normalized(document, schema)
{'foo': 4}
自定義默認(rèn)設(shè)置器
與自定義重命名處理程序類似棚点,也可以創(chuàng)建自定義默認(rèn)設(shè)置程序早处。
from datetime import datetime
class MyNormalizer(Validator):
def _normalize_default_setter_utcnow(self, document):
return datetime.utcnow()
>>> schema = {'creation_date': {'type': 'datetime', 'default_setter': 'utcnow'}}
>>> MyNormalizer().normalized({}, schema)
{'creation_date': datetime.datetime(...)}
Limitations
覆蓋特定的貢獻(xiàn)規(guī)則可能是一個(gè)糟糕的主意。
實(shí)例化自定義驗(yàn)證器
要在子類中使用其他上下文信息 Validator
瘫析,請(qǐng)使用如下模式:
class MyValidator(Validator):
def __init__(self, *args, **kwargs):
if 'additional_context' in kwargs:
self.additional_context = kwargs['additional_context']
super(MyValidator, self).__init__(*args, **kwargs)
# alternatively define a property
@property
def additional_context(self):
return self._config.get('additional_context', 'bar')
def _validate_type_foo(self, field, value):
make_use_of(self.additional_context)
這確保了額外的上下文將Validator
在驗(yàn)證期間可能使用的子實(shí)例中可用 砌梆。
0.9版本中的新功能默责。
有一個(gè)函數(shù)validator_factory()
可以獲得Validator
具有連接文檔字符串的 突變體。
1.0版中的新功能咸包。
相關(guān)的驗(yàn)證器 -屬性
Validator
在編寫自定義驗(yàn)證器時(shí)桃序,應(yīng)該注意一些屬性。
Validator.document
驗(yàn)證器document
在獲取驗(yàn)證字段時(shí)訪問屬性烂瘫。它還允許驗(yàn)證字段在文檔的其余部分發(fā)生媒熊。
0.7.1版本的新功能。
Validator.schema
同樣坟比,該schema
屬性保存使用的模式芦鳍。
注意
該屬性與schema
在某個(gè)時(shí)刻傳遞給驗(yàn)證器的對(duì)象不同。此外葛账,其內(nèi)容可能會(huì)有所不同柠衅,盡管它仍然代表著最初的限制。它提供了與a相同的界面 dict
注竿。
Validator._error
有三個(gè)簽名被接受用于向Validator
錯(cuò)誤隱藏提交錯(cuò)誤 茄茁。如有必要,給定的信息將被解析為一個(gè)新的實(shí)例ValidationError
巩割。
完全公開
為了能夠在以后獲得對(duì)錯(cuò)誤上下文的全面了解裙顽,您需要_error()
使用兩個(gè)強(qiáng)制參數(shù)進(jìn)行調(diào)用:
- 發(fā)生錯(cuò)誤的字段
- a的一個(gè)實(shí)例
ErrorDefinition
對(duì)于自定義規(guī)則,您需要定義一個(gè)錯(cuò)誤宣谈,如同ErrorDefinition
一個(gè)唯一的ID和違反的原因規(guī)則愈犹。請(qǐng)參閱errors
提供的錯(cuò)誤定義列表。請(qǐng)記住闻丑,第7位標(biāo)記為組錯(cuò)誤漩怎,第5位標(biāo)記由對(duì)不同規(guī)則集進(jìn)行驗(yàn)證而引發(fā)的錯(cuò)誤。
或者嗦嗡,您可以提交更多參數(shù)作為信息勋锤。用于人類目標(biāo)的錯(cuò)誤處理程序?qū)⑹褂眠@些作為格式化消息時(shí)的位置參數(shù)str.format()
。序列化處理程序?qū)堰@些值保存在一個(gè)列表中侥祭。
1.0版中的新功能叁执。
簡(jiǎn)單的自定義錯(cuò)誤
一個(gè)更簡(jiǎn)單的形式是_error()
用字段和字符串作為消息來調(diào)用。然而矮冬,由此產(chǎn)生的錯(cuò)誤將不包含違反約束的信息谈宛。這應(yīng)該保持向后兼容性,但也可以在不需要深入錯(cuò)誤處理時(shí)使用胎署。
多重錯(cuò)誤
使用兒童驗(yàn)證器時(shí)吆录,提交所有錯(cuò)誤是一種方便; 這是一個(gè)ValidationError
實(shí)例列表。
1.0版中的新功能琼牧。
Validator._get_child_validator
如果您需要Validator
-subclass的 _get_child_validator()
另一個(gè)實(shí)例恢筝,則-method會(huì)返回另一個(gè)以與之相同的參數(shù)啟動(dòng)的實(shí)例self
哀卫。您可以指定重寫關(guān)鍵字參數(shù)。由于屬性document_path
和schema_path
(見下文)由子驗(yàn)證器繼承滋恬,所以可以通過將關(guān)鍵字document_crumb
和 值傳遞給單個(gè)值或值元組來擴(kuò)展這些屬性schema_crumb
聊训。研究示例用法的源代碼。
0.9版本中的新功能恢氯。
在版本1.0中更改:添加document_crumb
和schema_crumb
作為可選的關(guān)鍵字參數(shù)带斑。
Validator.root_document,.root_schema&root_allow_unknown
子驗(yàn)證程序 - 用于驗(yàn)證schema
- 時(shí)可以訪問正在處理的第一代驗(yàn)證程序的文檔和模式以及通過它root_document
和root_schema
root_allow_unknown
屬性訪問未知字段的約束勋拟。
1.0版中的新功能勋磕。
Validator.document_path&Validator.schema_path
這些屬性分別維護(hù)文檔中的鍵路徑以及可能的父驗(yàn)證程序遍歷的模式。提交錯(cuò)誤時(shí)敢靡,兩者都將用作基本路徑挂滓。
1.0版中的新功能。
Validator.recent_error
通過recent_error
-attribute 可以訪問最后一次提交的單個(gè)錯(cuò)誤 啸胧。
1.0版中的新功能赶站。
Validator.mandatory_validations&Validator.priority_validations
如果要調(diào)整每個(gè)字段驗(yàn)證的驗(yàn)證邏輯,則可以覆蓋這些類屬性纺念。 mandatory_validations
是一個(gè)包含將針對(duì)每個(gè)字段進(jìn)行驗(yàn)證的規(guī)則的元組贝椿,無論規(guī)則是否定義為模式中的字段。priority_validations
是有序規(guī)則的元組陷谱,將在其他任何規(guī)則之前進(jìn)行驗(yàn)證烙博。如果驗(yàn)證方法或函數(shù)返回True
,則不會(huì)為該字段考慮進(jìn)一步的規(guī)則烟逊。
1.0版中的新功能渣窜。
API文檔
Validator Class
-
class
cerberus.``Validator
(*args, **kwargs)Validator class. Normalizes and/or validates any mapping against a validation-schema which is provided as an argument at class instantiation or upon calling the
validate()
,validated()
ornormalized()
method. An instance itself is callable and executes a validation.All instantiation parameters are optional.There are the introspective propertiestypes
,validators
,coercers
,default_setters
,rules
,normalization_rules
andvalidation_rules
.The attributes reflecting the available rules are assembled considering constraints that are defined in the docstrings of rules’ methods and is effectively used as validation schema forschema
.Parameters:schema (any mapping) – Seeschema
. Defaults toNone
.ignore_none_values (bool
) – Seeignore_none_values
. Defaults toFalse
.allow_unknown (bool
or any mapping) – Seeallow_unknown
. Defaults toFalse
.purge_unknown (bool
) – Seepurge_unknown
. Defaults to toFalse
.error_handler (class or instance based onBaseErrorHandler
ortuple
) – The error handler that formats the result oferrors
. When given as two-value tuple with an error-handler class and a dictionary, the latter is passed to the initialization of the error handler. Default:BasicErrorHandler
._error
(args)Creates and adds one or multiple errors.Parameters:args* –Accepts different argument’s signatures.1. Bulk addition of errors:iterable ofValidationError
-instancesThe errors will be added to_errors
.2. Custom error:the invalid field’s namethe error messageA custom error containing the message will be created and added to_errors
. There will however be fewer information contained in the error (no reference to the violated rule and its constraint).3. Defined error:the invalid field’s namethe error-reference, seecerberus.errors
arbitrary, supplemental information about the errorAValidationError
instance will be created and added to_errors
._get_child_validator
(document_crumb=None, schema_crumb=None, *kwargs)Creates a new instance of Validator-(sub-)class. All initialparameters of the parent are passed to the initialization, unless a parameter is given as an explicit keyword-parameter.Parameters:document_crumb* (tuple
or hashable) – Extends thedocument_path
of the child-validator.schema_crumb (tuple
or hashable) – Extends theschema_path
of the child-validator.kwargs (dict
) – Overriding keyword-arguments for initialization.Returns:an instance ofself.__class__``_lookup_field
(path)Searches for a field as defined by path. This method is used by thedependency
evaluation logic.Parameters:path (str
) – Path elements are separated by a.
. A leading^
indicates that the path relates to the document root, otherwise it relates to the currently evaluated document, which is possibly a subdocument. The sequence^^
at the start will be interpreted as a literal^
.Returns:Either the found field name and its value orNone
for both.Return type:A two-valuetuple
.allow_unknown
IfTrue
unknown fields that are not defined in the schema will be ignored. If a mapping with a validation schema is given, any undefined field will be validated against its rules. Also see Allowing the Unknown. Type:bool
or any mappingclear_caches
()Purge the cache of known valid schemas.errors
The errors of the last processing formatted by the handler that is bound toerror_handler
.ignore_none_values
Whether to not processNone
-values in a document or not. Type:bool
is_child``True
for child-validators obtained with_get_child_validator()
. Type:bool
normalized
(document, schema=None, always_return_document=False)Returns the document normalized according to the specified rules of a schema.Parameters:document (any mapping) – The document to normalize.schema (any mapping) – The validation schema. Defaults toNone
. If not provided here, the schema must have been provided at class instantiation.always_return_document (bool
) – Return the document, even if an error occurred. Defaults to:False
.Returns:A normalized copy of the provided mapping orNone
if an error occurred during normalization.purge_unknown
IfTrue
unknown fields will be deleted from the document unless a validation is called with disabled normalization. Also see Purging Unknown Fields. Type:bool
root_allow_unknown
Theallow_unknown
attribute of the first level ancestor of a child validator.root_document
Thedocument
attribute of the first level ancestor of a child validator.root_schema
Theschema
attribute of the first level ancestor of a child validator.rules_set_registry
The registry that holds referenced rules sets. Type:Registry
schema
The validation schema of a validator. When a schema is passed to a method, it replaces this attribute. Type: any mapping orNone
schema_registry
The registry that holds referenced schemas. Type:Registry
validate
(document, schema=None, update=False, normalize=True)Normalizes and validates a mapping against a validation-schema of defined rules.Parameters:document (any mapping) – The document to normalize.schema (any mapping) – The validation schema. Defaults toNone
. If not provided here, the schema must have been provided at class instantiation.update (bool
) – IfTrue
, required fields won’t be checked.normalize (bool
) – IfTrue
, normalize the document before validation.Returns:True
if validation succeeds, otherwiseFalse
. Check theerrors()
property for a list of processing errors.Return type:bool
validated
(*args, **kwargs)Wrapper aroundvalidate()
that returns the normalized and validated document orNone
if validation failed.
Rules Set & Schema Registry
-
class
cerberus.``Registry
(definitions={})A registry to store and retrieve schemas and parts of it by a name that can be used in validation schemas.Parameters:definitions (any mapping) – Optional, initial definitions.
add
(name, definition)Register a definition to the registry. Existing definitions are replaced silently.Parameters:name (str
) – The name which can be used as reference in a validation schema.definition (any mapping) – The definition.all
()Returns adict
with all registered definitions mapped to their name.clear
()Purge all definitions in the registry.extend
(definitions)Add several definitions at once. Existing definitions are replaced silently.Parameters:definitions (a mapping or an iterable with two-valuetuple
s) – The names and definitions.get
(name, default=None)Retrieve a definition from the registry.Parameters:name (str
) – The reference that points to the definition.default – Return value if the reference isn’t registered.remove
(names)Unregister definitions from the registry.Parameters:names* – The names of the definitions that are to be unregistered.
Error Handlers
-
class
cerberus.errors.``BaseErrorHandler
(*args, **kwargs)Base class for all error handlers. Subclasses are identified as error-handlers with an instance-test.
__call__
(errors)Returns errors in a handler-specific format.Parameters:errors (iterable ofValidationError
instances or aValidator
instance) – An object containing the errors.__init__
(args, *kwargs)Optionally initialize a new instance.__iter__
()Be a superhero and implement an iterator over errors.__weakref__
list of weak references to the object (if defined)add
(error)Add an error to the errors’ container object of a handler.Parameters:error (ValidationError
) – The error to add.emit
(error)Optionally emits an error in the handler’s format to a stream.Or light a LED, or even shut down a power plant.Parameters:error (ValidationError
) – The error to emit.end
(validator)Gets called when a validation ends.Parameters:validator (Validator
) – The calling validator.extend
(errors)Adds all errors to the handler’s container object.Parameters:errors (iterable ofValidationError
instances) – The errors to add.start
(validator)Gets called when a validation starts.Parameters:validator (Validator
) – The calling validator.
-
class
cerberus.errors.``BasicErrorHandler
(tree=None)Models cerberus’ legacy. Returns a
dict
.
Python Error Representations
-
class
cerberus.errors.``ValidationError
(document_path, schema_path, code, rule, constraint, value, info)A simple class to store and query basic error information.
child_errors
A list that contains the individual errors of a bulk validation error.definitions_errors
Dictionary with errors of an *of-rule mapped to the index of the definition it occurred in. ReturnsNone
if not applicable.field
Field of the contextual mapping, possiblyNone
.is_group_error``True
for errors of bulk validations.is_logic_error``True
for validation errors against different schemas with *of-rules.is_normalization_error``True
for normalization errors.
Error Codes
These errors are used as code
.
-
class
cerberus.errors.``ErrorList
A list for
ValidationError
instances that can be queried with thein
keyword for a particular error code.
-
class
cerberus.errors.``ErrorTree
(errors=[])Base class for
DocumentErrorTree
andSchemaErrorTree
.add
(error)Add an error to the tree.Parameters:error –ValidationError
fetch_errors_from
(path)Returns all errors for a particular path.Parameters:path –tuple
of hashable s.Return type:ErrorList
fetch_node_from
(path)Returns a node for a path.Parameters:path – Tuple of hashable s.Return type:ErrorTreeNode
orNone
-
class
cerberus.errors.``DocumentErrorTree
(errors=[])Implements a dict-like class to query errors by indexes following the structure of a validated document.
-
class
cerberus.errors.``SchemaErrorTree
(errors=[])Implements a dict-like class to query errors by indexes following the structure of the used schema.
Exceptions
-
exception
cerberus.``SchemaError
Raised when the validation schema is missing, has the wrong format or contains errors.
-
exception
cerberus.``DocumentError
Raised when the target document is missing or has the wrong format
Utilities
-
cerberus.utils.``mapping_to_frozenset
(mapping)Be aware that this treats any sequence type with the equal members as equal. As it is used to identify equality of schemas, this can be considered okay as definitions are semantically equal regardless the container type.
-
cerberus.utils.``validator_factory
(name, mixin=None, class_dict={})Dynamically create a
Validator
subclass.Docstrings of mixin-classes will be added to the resulting class’ one if__doc__
is not inclass_dict
.Parameters:name (str
) – The name of the new class.mixin (tuple
of or a single class) – Class(es) with mixin-methods.class_dict (dict
) – Attributes for the new class.Returns:The created class.
Schema Validation Schema
Against this schema validation schemas given to a vanilla Validator
will be validated: