#voluptuous是一个python数据验证库
voluptuous的Python项目详细描述
voluptuous是一个python数据验证库
voluptuous,尽管名称是,但它是一个python数据验证库。它 主要用于验证作为json传入python的数据, 山药等
它有三个目标:
- 简单。
- 支持复杂的数据结构。
- 提供有用的错误信息。 < > >
联系人
快活现在有一个邮件列表!发送邮件到 订阅。指令 将继续。
您也可以通过电子邮件直接与我联系 推特
要提交错误,请在github上创建一个新问题,并提供一个如何复制该问题的简短示例。
文档
更改日志
给我举个例子
twitter的用户搜索api接受 查询URL,例如:
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
为了验证这一点,我们可以使用如下模式:
>>> fromvoluptuousimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })
这个模式非常简洁和粗略地描述了
API,会很好的工作。但也有一些问题。首先,它
不能完全表达api的约束。根据API,
每页
最多应限制为20,默认为5,对于
例子。为了更准确地描述api的语义,我们
架构需要更彻底地定义:
>>> fromvoluptuousimportRequired,All,Length,Range>>> schema=Schema({... Required('q'):All(str,Length(min=1)),... Required('per_page',default=5):All(int,Range(min=1,max=20)),... 'page':All(int,Range(min=0)),... })
这个模式完全强制执行twitter中定义的接口 文档,并进一步完善。
"Q"是必需的:
>>> fromvoluptuousimportMultipleInvalid,Invalid>>> try:... schema({})... raiseAssertionError('MultipleInvalid not raised')... exceptMultipleInvalidase:... exc=e>>> str(exc)=="required key not provided @ data['q']"True
…必须是字符串:
>>> try:... schema({'q':123})... raiseAssertionError('MultipleInvalid not raised')... exceptMultipleInvalidase:... exc=e>>> str(exc)=="expected str for dictionary value @ data['q']"True
…并且长度必须至少为一个字符:
>>> try:... schema({'q':''})... raiseAssertionError('MultipleInvalid not raised')... exceptMultipleInvalidase:... exc=e>>> str(exc)=="length of value must be at least 1 for dictionary value @ data['q']"True>>> schema({'q':'#topic'})=={'q':'#topic','per_page':5}True
"每页"是不大于20的正整数:
>>> try:... schema({'q':'#topic','per_page':900})... raiseAssertionError('MultipleInvalid not raised')... exceptMultipleInvalidase:... exc=e>>> str(exc)=="value must be at most 20 for dictionary value @ data['per_page']"True>>> try:... schema({'q':'#topic','per_page':-10})... raiseAssertionError('MultipleInvalid not raised')... exceptMultipleInvalidase:... exc=e>>> str(exc)=="value must be at least 1 for dictionary value @ data['per_page']"True
"page"是一个整数>;=0:
>>> try:... schema({'q':'#topic','per_page':'one'})... raiseAssertionError('MultipleInvalid not raised')... exceptMultipleInvalidase:... exc=e>>> str(exc)"expected int for dictionary value @ data['per_page']">>> schema({'q':'#topic','page':1})=={'q':'#topic','page':1,'per_page':5}True
定义模式
模式是由字典、列表和 标量和验证器。输入模式中的每个节点都是模式 与输入数据中的相应节点匹配。
文字
架构中的文本使用正常的相等检查进行匹配:
>>> schema=Schema(1)>>> schema(1)1>>> schema=Schema('a string')>>> schema('a string')'a string'
类型
通过检查对应的值是否匹配架构中的类型 是以下类型的实例:
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
0
网址
架构中的URL通过使用urlparse
库进行匹配。
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
1
列表
架构中的列表被视为一组有效值。每个元素 在模式列表中与输入数据中的每个值进行比较:
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
2
但是,空列表([]
)被视为原样。如果要指定可以
包含任何内容,将其指定为列表
:
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
3
集合与冻结集合
集合和冻结集被视为一组有效值。每个元素 在模式中,将集合与输入数据中的每个值进行比较:
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
4
但是,空集(set()
)被视为原样。如果要指定集合
可以包含任何内容,请将其指定为集合
:
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
5
验证功能
验证器是简单的可调用函数,当
它们遇到无效数据。确定有效性的标准是
完全取决于实现;它可以检查值是否有效
用户名使用pwd.getpwnam()
,它可以检查值是否为
特定类型,依此类推。
最简单的验证程序是一个python函数,它引发 参数无效时出现valueerror。方便,许多内置 python函数具有此属性。下面是一个约会的例子 验证器:
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
6
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
7
除了简单地确定一个值是否有效之外,验证器还可以
将值变异为有效形式。这方面的一个例子是
强制(类型)
函数,它返回强制其
给定类型的参数:
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
8
这个例子还展示了一个常见的习惯用法,其中一个可选的人类可读的 可以提供消息。这可以大大提高 生成的错误消息。
词典
架构字典中的每个键值对都根据 对应数据字典中的键值对:
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
9
额外的字典键
默认情况下,数据中(而不是架构中)的任何其他键都将 触发异常:
>>> fromvoluptuousimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })0
此行为可以根据每个模式进行更改。容许
附加钥匙使用
架构(…,extra=allow_extra)
:
>>> fromvoluptuousimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })1
要删除其他密钥,请使用
架构(…,extra=remove_extra)
:
>>> fromvoluptuousimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })2
也可以使用catch all标记覆盖每个字典
令牌额外的
作为密钥:
>>> fromvoluptuousimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })3
所需的字典键
默认情况下,架构中的键不需要在数据中:
>>> fromvoluptuousimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })4
类似于额外密钥的工作方式,可以重写此行为 每个架构:
>>> fromvoluptuousimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })5
每一个密钥,带有标记标记必需(密钥)
:
>>> fromvoluptuousimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })6
可选字典键
如果模式具有required=true
,则键可以单独标记为
可选使用标记符号可选(键)
:
>>> fromvoluptuousimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })7
>>> fromvoluptuousimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })8
递归/嵌套模式
您可以使用voluptuous.self
定义嵌套架构:
>>> fromvoluptuousimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })9
扩展现有架构
通常,使用扩展了
要求。在这种情况下,可以使用schema.extend来创建新的
模式
:
>>> fromvoluptuousimportRequired,All,Length,Range>>> schema=Schema({... Required('q'):All(str,Length(min=1)),... Required('per_page',default=5):All(int,Range(min=1,max=20)),... 'page':All(int,Range(min=0)),... })0
原始的模式保持不变。
对象
架构字典中的每个键值对都根据 对应对象中的属性值对:
>>> fromvoluptuousimportRequired,All,Length,Range>>> schema=Schema({... Required('q'):All(str,Length(min=1)),... Required('per_page',default=5):All(int,Range(min=1,max=20)),... 'page':All(int,Range(min=0)),... })1
不允许任何值
要同时允许value为none,请使用any:
>>> fromvoluptuousimportRequired,All,Length,Range>>> schema=Schema({... Required('q'):All(str,Length(min=1)),... Required('per_page',default=5):All(int,Range(min=1,max=20)),... 'page':All(int,Range(min=0)),... })2
错误报告
如果传递了无效数据,验证器必须抛出一个无效的
异常
对他们来说。所有其他异常都被视为验证器中的错误,并且
不会被捕获。
每个无效的
异常都有一个关联的路径
属性,表示
数据结构中指向当前验证值的路径,以及
作为包含原始消息的错误消息
属性
例外。当您想捕获无效的
异常并向用户提供一些反馈,例如
一个http api。
>>> fromvoluptuousimportRequired,All,Length,Range>>> schema=Schema({... Required('q'):All(str,Length(min=1)),... Required('per_page',default=5):All(int,Range(min=1,max=20)),... 'page':All(int,Range(min=0)),... })3
路径
属性在错误报告期间使用,但也在匹配期间使用
以确定n错误应该报告给用户,或者如果下一个
应尝试匹配。这是通过比较
检查所在的路径,到发生错误的路径的深度。如果
据报告,错误深度超过一个级别。
其结果是匹配是深度优先的,并且失败速度很快
为了说明这一点,下面是一个模式示例:
>>> fromvoluptuousimportRequired,All,Length,Range>>> schema=Schema({... Required('q'):All(str,Length(min=1)),... Required('per_page',default=5):All(int,Range(min=1,max=20)),... 'page':All(int,Range(min=0)),... })4
顶级列表中的每个值都是按顺序首先匹配深度的。鉴于
输入[[6]]
的数据,内部列表将匹配
模式,但文本6
与
那个名单。此错误将立即报告给用户。不
尝试回溯:
>>> fromvoluptuousimportRequired,All,Length,Range>>> schema=Schema({... Required('q'):All(str,Length(min=1)),... Required('per_page',default=5):All(int,Range(min=1,max=20)),... 'page':All(int,Range(min=0)),... })5
如果我们传递数据[6]
,则6
不是列表类型,因此不会
递归到架构的第一个元素中。匹配将继续
到架构中的第二个元素,并成功:
>>> fromvoluptuousimportRequired,All,Length,Range>>> schema=Schema({... Required('q'):All(str,Length(min=1)),... Required('per_page',default=5):All(int,Range(min=1,max=20)),... 'page':All(int,Range(min=0)),... })6
多字段验证
涉及多个字段的验证规则可以实现为
自定义验证器。建议使用all()
进行两次通过
验证-第一次检查数据的基本结构,
只有在那之后,第二次传球应用你的交叉场
验证器:
>>> fromvoluptuousimportRequired,All,Length,Range>>> schema=Schema({... Required('q'):All(str,Length(min=1)),... Required('per_page',default=5):All(int,Range(min=1,max=20)),... 'page':All(int,Range(min=0)),... })7
使用此结构,您的多字段验证器将使用 第一次"通过"时的预验证数据,因此不必 它自己的类型检查它的输入。
另一方面,如果验证的第一次"通过"失败,则 跨域验证器将不运行:
>>> fromvoluptuousimportRequired,All,Length,Range>>> schema=Schema({... Required('q'):All(str,Length(min=1)),... Required('per_page',default=5):All(int,Range(min=1,max=20)),... 'page':All(int,Range(min=0)),... })8
运行测试。
voluptuous正在使用鼻子测试:
>>> fromvoluptuousimportRequired,All,Length,Range>>> schema=Schema({... Required('q'):All(str,Length(min=1)),... Required('per_page',default=5):All(int,Range(min=1,max=20)),... 'page':All(int,Range(min=0)),... })9
为什么要在另一个验证库上使用volupturous?
验证器是简单的可调用函数 :无需子类化任何内容,只需使用函数即可。
错误是简单的例外。
:验证器只需引发invalid(msg)
并期望用户获得
有用的信息。
模式是基本的python数据结构。
:您的数据应该是字符串的整数键字典吗?
{int:str}
做你所期望的。整数、浮点数或
串?[int,float,str]
从头开始设计,不仅用于验证表单。
:嵌套数据结构的处理方式与任何其他
类型。需要一份字典清单吗?[{}]
一致性。 :架构中的类型被检查为类型。数值比较如下 价值观。调用可调用项进行验证。简单,
其他库和启示
性感的灵感来自 validino,在较小程度上, jsonvalidator和 json\u模式
pytest voluptuous是
pytest的插件
在assert
s中使用volupturous验证器。
我非常喜欢这些库所提倡的轻量级风格 像formencode这样的库的复杂性。