我正在python中开发一个小型RESTful Web应用程序,并使用JSON作为接口.应用程序接受JSON数据,需要根据模式验证它们.根据请求,模式可能非常严格或灵活.此外,应用程序可能需要在稍后的改进中验证用户对象.
我在堆栈溢出以及其他网站上找到了一些建议.那些包括
但找不到合适的比较.
在简单性,灵活性和扩展能力方面,您认为我应该选择哪一个?
Cerberus似乎非常灵活,扩展能力从他们的文档和示例中看起来非常好.但我不知道其他图书馆.
编辑1:目前,应用程序的需求非常简单,基本的模式验证以及添加自定义类型和自定义验证规则的范围就足够了.因此,如果所有这些库都提供了基本要求,我会选择最简单的库.如果有的话,我也愿意接受其他建议.
希望能找到一些帮助.
从文档中,我不清楚自定义规则和自定义验证器的用例有何不同.在文档中给出的示例中,唯一的区别是一个额外的if语句,用于检查is_odd自定义规则中的值.我应该何时更喜欢自定义规则,何时应该更喜欢自定义验证器?
自定义规则
schema = {'amount': {'isodd': True, 'type': 'integer'}}
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")
Run Code Online (Sandbox Code Playgroud)
自定义验证器
from cerberus import Validator
schema = {'amount': {'validator': 'oddity'}}
class AValidator(Validator):
def _validator_oddity(self, field, value):
if value & 1:
self._error(field, "Must be …Run Code Online (Sandbox Code Playgroud) 我正在尝试为具有引用文档中较高位置的依赖项的文档创建模式.例如:
document = {
'packages': {
'some-package': {'version': 1}
},
'build-steps': {
'needs-some-package': {'foo': 'bar'},
'other-thing': {'funky': 'stuff'}
}
}
Run Code Online (Sandbox Code Playgroud)
我在这里苦苦挣扎的是强制build-steps.needs-some-package和packages.some-package之间的依赖关系.每当构建步骤包含"needs-some-package"时,包必须包含"some-package".
当"need-some-package"不存在时,不需要"some-package".所以这份文件也应该验证.
other_document = {
'packages': {
'other-package': {'version': 1}
},
'build-steps': {
'other-thing': {'funky': 'stuff'}
}
}
Run Code Online (Sandbox Code Playgroud)
具有依赖关系的模式似乎是合适的位置
schema = {
'packages': {
'type': 'dict',
'valueschema': {
'type': 'dict'
}
},
'build-steps': {
'type': 'dict',
'schema': {
'needs-some-package': {
'type': 'dict',
'dependencies': 'packages.some-package'
},
'other-thing': {
'type': 'dict'
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为似乎Cerberus正在"构建步骤"下的子文档中寻找"包".有没有办法上升文档树?或者引用一些关于文档根目录的内容?
我有一个很大的json文档,如果其他字段具有确切值,则应在其中输入某些字段。例如
document = {'is_realty_address': False, 'postcode': 111111}
Run Code Online (Sandbox Code Playgroud)
如果is_realty_address == False,则必须提供邮政编码。所有规则(“必需”除外)都应用于文档中存在的字段,因此当我拥有
document = {'is_realty_address': False}
Run Code Online (Sandbox Code Playgroud)
规则对我的情况无济于事,因为我有很多“有条件需要”的字段,这些字段取决于许多不同的字段。因此,规则将使我的架构非常复杂。依赖关系也不起作用。我试过了:
{'postcode': {'dependencies': {'is_realty_address': False}, 'required': True}}
Run Code Online (Sandbox Code Playgroud)
如果邮政编码没有出现在文档中,则返回错误,无论is_realty_address的值是多少
v = Validator()
print(v.validate({'is_realty_address': False}, schema))
print(v.errors)
print(v.validate({'is_realty_address': True}, schema))
print(v.errors)
Run Code Online (Sandbox Code Playgroud)
此代码返回:
False
{'postcode': ['required field']}
False
{'postcode': ['required field']}
Run Code Online (Sandbox Code Playgroud)
我还尝试实现验证方法:
def _validate_conditional_required(self, conditional_required, field, value):
"""
:param conditional_required:
:param field:
:param value:
:return:
The rule's arguments are validated against this schema:
{'type': 'dict'}
"""
for conditional_field, conditional_value in conditional_required.items():
if self.document[conditional_field] == conditional_value and field not in …Run Code Online (Sandbox Code Playgroud) 我有以下架构:
schema = {
'person': {
'name': {'type': 'string', 'required': True, 'minlength': 2},
'gender': {'type': 'integer', 'required': True},
'weight': {'type': 'integer', 'required': True},
'age': {'type': 'integer', 'required': True, 'min': 5}
},
'parameters': {
'ps': {'type': 'float', 'required': True},
'pp': {'type': 'float', 'required': True},
'ls': {'type': 'float', 'required': True},
'lp': {'type': 'float', 'required': True},
'ab': {'type': 'float', 'required': True}
},
'indicators': {
'atmospheric_pressure': {'type': 'integer', 'required': True},
'puls': {'type': 'integer', 'required': True},
'respiration_rate': {'type': 'integer', 'required': True}
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行验证时:
v …Run Code Online (Sandbox Code Playgroud) 我试图将字符串强制为日期,以便它可以验证日期数据类型,但它仍然返回False:
from cerberus import Validator
from datetime import datetime
v = Validator()
v.schema = {'start_date': {'type': 'date','coerce':datetime.date}}
v.validate({'start_date': '2017-10-01'})
>>> False
Run Code Online (Sandbox Code Playgroud)
我尝试使用整数并且它有效。我不确定为什么日期转换不起作用:
v = Validator()
v.schema = {'amount': {'type': 'integer','coerce': int}}
v.validate({'amount': '2'})
>>> True
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激。
我想本地化 Cerberus 返回的错误消息,例如我想实现以下目标:
>>> validator.schema = {'animal': {'forbidden': ['Einhorn']}}
>>> validator({'animal': 'Einhorn'})
False
>>> validator.errors
{'animal': ['VERBOTEN!']} # instead of 'unallowed value Einhorn'
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Cerberus 来验证一些数据,但我遇到了一个问题。
我定义了几个较小的架构,例如:
A = {"type": "dict", "required": False, "schema": {"name": {"type": "string"}}}
B = {"type": "dict", "required": False, "schema": {"age": {"type": "integer"}}}
C = {"type": "dict", "required": False, "schema": {"gender": {"type": "string"}}}
Run Code Online (Sandbox Code Playgroud)
更高级别的架构是这样的:
{"something": {"type": "list", "schema": "type": [A, B, C]}}
Run Code Online (Sandbox Code Playgroud)
这显然行不通。
我想验证一个列表,其中的元素只需要通过(A, B, C). 我不知道如何用 Cerberus 做到这一点,我正在寻求帮助。
谢谢。
正在验证.csv文件,我想以用户习惯的格式给出验证结果。为了使用Cerberus,我让用户在文件中定义验证规则.yaml。
架构.yaml
Rules:
Rule1:
maxlength: 10
Rule2:
allowed: ["MO", "TU", "WE", "TH", "FR", "SA", "SU"]
Rule3:
required: True
Run Code Online (Sandbox Code Playgroud)
然后,我将这些规则映射到 CSV 文件中适用的列。
csv_fields.yaml
Fields:
1:
rules:
- Rule1
- Rule2
2:
rules:
- Rule2
- Rule3
3:
rules:
- Rule1
- Rule3
Run Code Online (Sandbox Code Playgroud)
样本文件.csv
下面是一个包含三列的示例文件:first_name、day_of_week和is_employed。
Peter, XX, True
Run Code Online (Sandbox Code Playgroud)
为了使用 Cerberus 进行验证,我将文档密钥rules中定义的内容与文件中的进行交叉引用。这很容易做到,因为文件在 python 中以键值格式读取为字典。rulescsv_fields.yamlRulesschema.yaml.yaml
我的问题
在上面的示例数据中,cerberus 会抛出错误'day_of_week': ['unallowed value XX'],但用户不知道什么规则触发了此错误。
我期待告诉用户的是,该错误unallowed …
我正在使用Python-Eve开发API,我需要使用Cerberus创建一个MongoDB模式声明来表达如下文档:
{
name : 'John Smith',
type: 'home',
devices : [
ObjectID('1234'),
ObjectID('ABCD'),
ObjectID('D2AF'),
],
}
Run Code Online (Sandbox Code Playgroud)
我想知道如何声明Cerberus模式具有一个数组ObjectID,如devices上面的键。
我想要一个对其他文档的引用数组的架构,并且可能使它们可嵌入,就像下面的单元素架构示例(取自Python-Eve 文档):
{
'author': {
'type': 'objectid',
'data_relation': {
'resource': 'users',
'field': '_id',
'embeddable': True
},
},
}
Run Code Online (Sandbox Code Playgroud)
我怀疑这将需要自定义类型,但我仍然没有弄清楚该如何做。
有没有办法让Cerberus验证两个字段具有相同数量的元素?
例如,该文档将验证:
{'a': [1, 2, 3], b: [4, 5, 6]}
Run Code Online (Sandbox Code Playgroud)
这不会:
{'a': [1, 2, 3], 'b': [7, 8]}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经想出了这个模式:
{'a': {'required':False, 'type'= 'list', 'dependencies':'b'},
'b': {'required':False, 'type'= 'list', 'dependencies':'a'}}
Run Code Online (Sandbox Code Playgroud)
但没有规则可以测试两个字段的长度是否相等。
cerberus ×11
python ×10
validation ×6
datetime ×1
eve ×1
json ×1
jsonschema ×1
mongodb ×1
python-3.x ×1
voluptuous ×1