#形态学是一个python数据验证库

morpholog的Python项目详细描述


形态学是一个python数据验证库

构建状态coverage statusgitter chat

形态学是一个python数据验证库。它主要用于验证作为json传入python的数据, 山药等

它有三个目标:

  1. 简单。
  2. 支持复杂的数据结构。
  3. 提供有用的错误信息。

联系人

要归档错误,请在github上创建一个新问题,并提供一个如何复制该问题的简短示例。

文档

文档在这里提供。

更改日志

请参见changelog.md

给我举个例子

twitter的用户搜索api接受 查询URL,例如:

$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'

为了验证这一点,我们可以使用如下模式:

>>> frommorphologyimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })

这个模式非常简洁和粗略地描述了 API,会很好的工作。但也有一些问题。首先,它 不能完全表达api的约束。根据API, 每页最多应限制为20,默认为5,对于 例子。为了更准确地描述api的语义,我们 架构需要更彻底地定义:

>>> frommorphologyimportRequired,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"是必需的:

>>> frommorphologyimportMultipleInvalid,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

验证功能

验证器是简单的可调用函数,当 它们遇到无效数据。确定有效性的标准是 完全取决于实现;它可以检查值是否有效 带有pwd.getpwnam()的用户名,它可以检查值是否为 特定类型,依此类推。

最简单的验证程序是一个python函数,它引发 参数无效时出现valueerror。方便,许多内置 python函数具有此属性。下面是一个约会的例子 验证器:

$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
4
$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
5

除了简单地确定一个值是否有效之外,验证器还可以 将值变异为有效形式。这方面的一个例子是 强制(类型)函数,它返回强制其 给定类型的参数:

$ 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

此行为可以根据每个模式进行更改。允许 附加钥匙使用 架构(…,extra=allow_extra)

$ curl 'https://api.twitter.com/1.1/users/search.json?q=python&per_page=20&page=1'
9

要删除其他密钥,请使用 架构(…,extra=remove_extra)

>>> frommorphologyimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })
0

也可以使用catch all标记覆盖每个字典 令牌额外的作为密钥:

>>> frommorphologyimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })
1

所需的字典键

默认情况下,架构中的键不需要在数据中:

>>> frommorphologyimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })
2

类似于额外密钥的工作方式,可以重写此行为 每个架构:

>>> frommorphologyimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })
3

每一个密钥,带有标记标记必需(密钥)

>>> frommorphologyimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })
4

可选字典键

如果模式具有required=true,则键可以单独标记为 可选使用标记符号可选(键)

>>> frommorphologyimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })
5
>>> frommorphologyimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })
6

递归/嵌套模式

您可以使用词法.self定义嵌套模式:

>>> frommorphologyimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })
7

扩展现有架构

通常,使用扩展了 要求。在这种情况下,可以使用schema.extend来创建新的 模式

>>> frommorphologyimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })
8

原始的模式保持不变。

对象

架构字典中的每个键值对都根据 对应对象中的属性值对:

>>> frommorphologyimportSchema>>> schema=Schema({... 'q':str,... 'per_page':int,... 'page':int,... })
9

不允许任何值

要同时允许value为none,请使用any:

>>> frommorphologyimportRequired,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

错误报告

如果传递了无效数据,验证器必须抛出一个无效的异常 对他们来说。所有其他异常都被视为验证器中的错误,并且 不会被捕获。

每个无效的异常都有一个关联的路径属性,表示 数据结构中指向当前验证值的路径,以及 作为包含原始消息的错误消息属性 例外。当您想捕获无效的 异常并向用户提供一些反馈,例如 一个http api。

>>> frommorphologyimportRequired,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

路径属性在错误报告期间使用,但也在匹配期间使用 确定是否应将错误报告给用户,或者 应尝试匹配。这是通过比较 检查所在的路径,到发生错误的路径的深度。如果 据报告,错误深度超过一个级别。

其结果是匹配是深度优先的,并且失败速度很快

为了说明这一点,下面是一个模式示例:

>>> frommorphologyimportRequired,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

顶级列表中的每个值都是按顺序首先匹配深度的。鉴于 输入[[6]]的数据,内部列表将匹配 模式,但文本6与 那个名单。此错误将报告给美国立刻。不 尝试回溯:

>>> frommorphologyimportRequired,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

如果我们传递数据[6],则6不是列表类型,因此不会 递归到架构的第一个元素中。匹配将继续 到架构中的第二个元素,并成功:

>>> frommorphologyimportRequired,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

运行测试。

形态学正在使用鼻测试:

>>> frommorphologyimportRequired,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

为什么在另一个验证库上使用形态学?

验证器是简单的可调用函数 :无需子类化任何内容,只需使用函数即可。

错误是简单的例外。 :验证器只需引发invalid(msg)并期望用户获得 有用的信息。

模式是基本的python数据结构。 :您的数据应该是字符串的整数键字典吗? {int:str}做你所期望的。整数、浮点数或 串?[int,float,str]

从头开始设计,不仅用于验证表单。 :嵌套数据结构的处理方式与任何其他 类型。需要一份字典清单吗?[{}]

一致性。 :架构中的类型被检查为类型。数值比较如下 价值观。调用可调用项进行验证。简单,

沿袭

形态学几乎是这个库的直接分支。 此问题已打开,解决了不适当的 名字的性质,但被原作者草率地关闭了。不幸的是,这阻止了一个伟大的图书馆 在专业、包容的环境中使用,唯一的解决方案是使用fork来处理这个特定的 问题。重要的是要认识到亚历克托马斯和其他出资人应该得到 这里的功能。

在未来,我打算移植任何重要的升级,并将尝试保持版本同步,以便 可与另一个互换,只需简单地全部替换即可。由于各种建造的原因,形态小版本 相当于10x(父级次要版本)+c,其中c是0-9,只与集成修复有关。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java密钥适配器在JComponent中不工作   动态编程我试图在java中使用递归自顶向下DP实现TSP。逻辑是正确的,但答案不同   java当我在BundleActivator中注册Servlet而不使用web时,“TransportGuarrance”的等价物是什么。xml?   java膨胀视图与膨胀元素   用zxing从图像中检测二维码的java   使用GroupLayout将java组件呈现在彼此的顶部   Java Android:如何在一秒钟内添加15次数组?   tomcat无法查找java邮件会话的JNDI资源。无法连接到主机,端口:localhost,25;超时1;   spring如何使用org。springframework。网状物滤器CharacterEncodingFilter以更正字符编码?   数据集的java并发处理   爪哇反应堆:如何从标准丁烷中产生助焊剂?   java在本地运行storm NoClassDefFoundError   为用户定义的类使用setDate的数组。。JAVA   如何将节点附加到java中现有的XML文件中