zope 3应用程序的rest框架

z3c.rest的Python项目详细描述


详细文档

在zope 3中构建restive服务的框架

这个包实现了几个与构建restive web相关的组件。 使用zope发布服务器的服务。每一组组件都记录在 相应的文本文件。

  • client.txt [必须读取]

    这个包还提供了一个rest web客户端,可以用来测试 或者用于访问应用程序中的restive api。

  • null.txt [高级用户]

    为了创建新资源,发布服务器必须能够遍历到 尚未存在的资源/对象。这个文件解释了那些空的 资源工作。

  • traverser.txt [高级用户]

    遍历器模块包含几个遍历助手组件 常见的遍历场景,suhc作为容器和空资源。

  • rest.txt [信息]

    本文介绍了在 出版商。它还讨论了 出版商。

rest客户端

rest客户端提供了一个简单的python api,可以轻松地与restive交互。 网络服务。它的设计与zope的测试有相似的api 浏览器,

让我们从实例化客户机开始。当然我们有一个版本 直接与zope发行商对话的客户:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()

为了进行测试,我们为文件夹定义了一个简单的rest api。这个 最简单的调用是检索根文件夹的内容:

< Buff行情>
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>

您还可以实例化提供url的客户机:

< Buff行情>
>>> client = testing.RESTClient('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>

还支持https url

< Buff行情>
>>> client = testing.RESTClient('https://localhost/')
Using SSL
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>

获取资源

open() 方法隐式地使用"get"http方法。另一种选择 将使用这个:

< Buff行情>
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>

还有其他几条回复信息是 可用:

< Buff行情>
>>> client.url
'http://localhost/'
>>> client.status
200
>>> client.reason
'Ok'
>>> client.fullStatus
'200 Ok'
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '204'),
 ('Content-Type', 'text/xml;charset=utf-8')]

如果尝试访问不存在的资源,则不会引发异常,但 状态为"404"(未找到)当然:

< Buff行情>
>>> client.get('http://localhost/unknown')
>>> client.fullStatus
'404 Not Found'
>>> client.contents
''
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '0')]

与原始测试浏览器一样,我可以关闭zope错误处理和 python异常将通过发布服务器传播:

< Buff行情>
>>> client.handleErrors = False
>>> client.get('http://localhost/unknown')
Traceback (most recent call last):
...
NotFound: Object: <zope.site.folder.Folder ...>, name: u'unknown'
>>> client.handleErrors = True

因为restiveapi经常使用查询字符串键值对来参数化 请求,这个rest客户端对它有很强的支持。例如,您可以 只需在url中指定参数即可:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
0

也可以通过参数指定参数:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
1

您甚至可以将两种指定参数的方法结合起来:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
2

但是我们的小演示api可以做更多的事情。参数也可以指定为 带有特殊前缀的头。可以全局指定头,然后 用于每个请求:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
3

"open"方法还有一个headers参数,用于指定头 一次:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
4
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
5

最后,在处理实际站点时,可能会发生套接字错误。误差 传播,但会记录错误号和消息:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
6
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
7

创建新资源

现在让我们在服务器根目录中创建一个新资源。我们的小样品 应用程序只需创建另一个收藏:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
8
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
9

每个人都可以访问文件夹资源。但我如果你想 修改任何资源,您必须登录:

< Buff行情>
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
0

所以让我们再试一次:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
8
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
2

我们现在可以查看根容器并在其中查看项目:

< Buff行情>
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
3

顺便说一下,您现在可以使用相对url访问 folder1 资源:

< Buff行情>
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
4
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
5
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
6

当我们试图在不存在的资源上创建一个资源时,会得到一个 404错误:

< Buff行情>
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
7
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
8

修改资源

修改给定的资源可以通过post或put完成,但是它们有不同的 语义学。让我们先看看帖子。我们现在想改变 文件夹的标题;可以按如下方式完成:

< Buff行情>
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
9
>>> client = testing.RESTClient('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
0
>>> client = testing.RESTClient('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
1

如上所述,它还必须适用于PUT:

< Buff行情>
>>> client = testing.RESTClient('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
2
>>> client = testing.RESTClient('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
0
>>> client = testing.RESTClient('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
4

删除资源

删除资源和所有其他方法一样简单。让我们删除我们的 文件夹1 < Buff行情>

>>> client = testing.RESTClient('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
5
>>> client = testing.RESTClient('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
0

所以资源真的没有了:

< Buff行情>
>>> client = testing.RESTClient('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
7

不应删除不存在的资源:

< Buff行情>
>>> client = testing.RESTClient('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
8

此外,我们不能删除根文件夹:

< Buff行情>
>>> client = testing.RESTClient('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
9

搜索响应数据

虽然不是必需的,但大多数rest服务都是基于xml的。因此,客户 支持使用xpath检查结果xml。让我们创造一些 文件夹使其更有趣:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
8
>>> client = testing.RESTClient('https://localhost/')
Using SSL
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
1

接下来我们得到根文件夹资源:

< Buff行情>
>>> client = testing.RESTClient('https://localhost/')
Using SSL
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
2

但一般来说,在字符串级别检查xml输出是乏味的。所以 让我们编写一个很酷的xpath表达式来提取所有 项目:

< Buff行情>
>>> client = testing.RESTClient('https://localhost/')
Using SSL
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
3

然而,我们常常特别查询一个结果。在这种情况下,我们 不想收到列表:

< Buff行情>
>>> client = testing.RESTClient('https://localhost/')
Using SSL
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
4

现在,如果检测到多个匹配,即使我们只期望一个匹配,那么 出现值错误

< Buff行情>
>>> client = testing.RESTClient('https://localhost/')
Using SSL
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
5

访问链接

因为我们希望rest客户端的行为像浏览器一样-至少有一点 bit–我们还可以使用 getlink() 方法访问链接:

< Buff行情>
>>> client = testing.RESTClient('https://localhost/')
Using SSL
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
6

默认情况下,按标题查找链接。但你也可以通过 URL:

< Buff行情>
>>> client = testing.RESTClient('https://localhost/')
Using SSL
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
7

如果忘记指定标题或url,则会收到一个 valueerror

< Buff行情>
>>> client = testing.RESTClient('https://localhost/')
Using SSL
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
8

链接也可以是相对的,例如acl的链接:

< Buff行情>
>>> client = testing.RESTClient('https://localhost/')
Using SSL
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
9
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
0

链接最酷的部分是您可以单击它:

< Buff行情>
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
1
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
2
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
5

穿越时间

就像在真正的浏览器中一样,您可以返回到以前的状态。例如, 目前我们正在查看文件夹1,…

< Buff行情>
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
5

但如果我后退一步,我就回到根文件夹:

< Buff行情>
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
5
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
6
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
7

但如果你也能重新加载,回到历史上就很酷了。所以让我们 删除文件夹2 < Buff行情>

>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
8

现在我们返回两个步骤:

< Buff行情>
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
9
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
6
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
7

如所料,内容尚未改变。所以让我们重新加载:

< Buff行情>
>>> client.url
'http://localhost/'
>>> client.status
200
>>> client.reason
'Ok'
>>> client.fullStatus
'200 Ok'
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '204'),
 ('Content-Type', 'text/xml;charset=utf-8')]
2
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
6
>>> client.url
'http://localhost/'
>>> client.status
200
>>> client.reason
'Ok'
>>> client.fullStatus
'200 Ok'
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '204'),
 ('Content-Type', 'text/xml;charset=utf-8')]
4

请注意,返回零步没有任何作用:

< Buff行情>
>>> client.get('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
6
>>> client.url
'http://localhost/'
>>> client.status
200
>>> client.reason
'Ok'
>>> client.fullStatus
'200 Ok'
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '204'),
 ('Content-Type', 'text/xml;charset=utf-8')]
6
>>> client.open('http://localhost/')
>>> print client.contents
<?xml version="1.0" ?>
<folder xmlns:xlink="http://www.w3.org/1999/xlink">
  <name></name>
  <title></title>
  <items>
  </items>
  <acl xlink:type="simple" xlink:href="acl" xlink:title="ACL"/>
</folder>
5

另外,如果您试图回到时间开始之后,则值错误为 提升D:

< Buff行情>
>>> client.url
'http://localhost/'
>>> client.status
200
>>> client.reason
'Ok'
>>> client.fullStatus
'200 Ok'
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '204'),
 ('Content-Type', 'text/xml;charset=utf-8')]
8

绝对URL

如上所述,我们允许指定相对url,一个带有 已创建URL。一个名为 absoluteUrl() 的函数用于计算 新的绝对URL。

< Buff行情>
>>> client.url
'http://localhost/'
>>> client.status
200
>>> client.reason
'Ok'
>>> client.fullStatus
'200 Ok'
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '204'),
 ('Content-Type', 'text/xml;charset=utf-8')]
9

基本功能很简单:

< Buff行情>
>>> client.get('http://localhost/unknown')
>>> client.fullStatus
'404 Not Found'
>>> client.contents
''
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '0')]
0

如果url的新部分是绝对的,它还会检测到 替换原始基URL:

< Buff行情>
>>> client.get('http://localhost/unknown')
>>> client.fullStatus
'404 Not Found'
>>> client.contents
''
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '0')]
1

如果基URL没有尾随斜杠,则会自动添加:

< Buff行情>
>>> client.get('http://localhost/unknown')
>>> client.fullStatus
'404 Not Found'
>>> client.contents
''
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '0')]
2

新url结尾的斜杠将被保留:

< Buff行情>
>>> client.get('http://localhost/unknown')
>>> client.fullStatus
'404 Not Found'
>>> client.contents
''
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '0')]
3
>>> client.get('http://localhost/unknown')
>>> client.fullStatus
'404 Not Found'
>>> client.contents
''
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '0')]
4

该函数还处理包含查询字符串的更复杂的url 正确:

< Buff行情>
>>> client.get('http://localhost/unknown')
>>> client.fullStatus
'404 Not Found'
>>> client.contents
''
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '0')]
5
>>> client.get('http://localhost/unknown')
>>> client.fullStatus
'404 Not Found'
>>> client.contents
''
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '0')]
6

如果基url包含查询字符串,则生成的url也将:

< Buff行情>
>>> client.get('http://localhost/unknown')
>>> client.fullStatus
'404 Not Found'
>>> client.contents
''
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '0')]
7
>>> client.get('http://localhost/unknown')
>>> client.fullStatus
'404 Not Found'
>>> client.contents
''
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '0')]
8
>>> client.get('http://localhost/unknown')
>>> client.fullStatus
'404 Not Found'
>>> client.contents
''
>>> client.headers
[('X-Powered-By', 'Zope (www.zope.org), Python (www.python.org)'),
 ('Content-Length', '0')]
9
>>> client.handleErrors = False
>>> client.get('http://localhost/unknown')
Traceback (most recent call last):
...
NotFound: Object: <zope.site.folder.Folder ...>, name: u'unknown'
0

如果基URL和相对URL都提供查询字符串,则它们将被合并:

< Buff行情>
>>> client.handleErrors = False
>>> client.get('http://localhost/unknown')
Traceback (most recent call last):
...
NotFound: Object: <zope.site.folder.Folder ...>, name: u'unknown'
1
>>> client.handleErrors = False
>>> client.get('http://localhost/unknown')
Traceback (most recent call last):
...
NotFound: Object: <zope.site.folder.Folder ...>, name: u'unknown'
2
>>> client.handleErrors = False
>>> client.get('http://localhost/unknown')
Traceback (most recent call last):
...
NotFound: Object: <zope.site.folder.Folder ...>, name: u'unknown'
3

空资源

有时有必要遍历到尚不存在的资源。在 特别是,当使用"put"或"post"创建资源时,这是必需的。它 导线工有责任正确处理这些情况 生成空资源。本文档仅描述他们的行为。

空资源很容易使用容器和 资源:

< Buff行情>
>>> client.handleErrors = False
>>> client.get('http://localhost/unknown')
Traceback (most recent call last):
...
NotFound: Object: <zope.site.folder.Folder ...>, name: u'unknown'
4
>>> client.handleErrors = False
>>> client.get('http://localhost/unknown')
Traceback (most recent call last):
...
NotFound: Object: <zope.site.folder.Folder ...>, name: u'unknown'
5
>>> client.handleErrors = False
>>> client.get('http://localhost/unknown')
Traceback (most recent call last):
...
NotFound: Object: <zope.site.folder.Folder ...>, name: u'unknown'
6

空资源是位置,因此安全性可用:

< Buff行情>
>>> client.handleErrors = False
>>> client.get('http://localhost/unknown')
Traceback (most recent call last):
...
NotFound: Object: <zope.site.folder.Folder ...>, name: u'unknown'
7

容器也是父容器:

< Buff行情>
>>> client.handleErrors = False
>>> client.get('http://localhost/unknown')
Traceback (most recent call last):
...
NotFound: Object: <zope.site.folder.Folder ...>, name: u'unknown'
8

资源名称位于:

< Buff行情>
>>> client.handleErrors = False
>>> client.get('http://localhost/unknown')
Traceback (most recent call last):
...
NotFound: Object: <zope.site.folder.Folder ...>, name: u'unknown'
9

对于空资源有一个特殊的"put"实现。它通过 为容器查找名为"nullput"的视图。这边,一个空的 资源实现可用于所有容器实现。

< Buff行情>
>>> client.handleErrors = True
0
>>> client.handleErrors = True
1

由于我们的 文件夹 类不存在名为"nullput"的视图,因此我们得到501 返回状态:

< Buff行情>
>>> client.handleErrors = True
2

现在让我们注册一个简单的nullput视图:

< Buff行情>
>>> client.handleErrors = True
3
>>> client.handleErrors = True
4

让我们确保我们的位置结构设置正确,这样 url将起作用:

< Buff行情>
>>> client.handleErrors = True
5

现在我们准备好放置新资源:

< Buff行情>
>>> client.handleErrors = True
6
>>> client.handleErrors = True
1
>>> client.handleErrors = True
8
>>> client.handleErrors = True
9

静止快进器部件

能够控制和扩展遍历对于任何不稳定的 应用程序编程接口。这个包使用 z3c.traverser 包提供灵活的遍历机制。

rest可插入遍历器

rest可插入遍历器是为所有类型的组件注册的。其 在 z3c.traverser 包中对实现进行了全面测试。

< Buff行情> α
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
00
>>> client.handleErrors = True
0
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
02

项目容器遍历器插件

项容器继承的项映射接口是 python中最简单的映射接口。因此,一旦穿过这个 已实现项容器,它可以被所有其他容器使用 接口和实现。

让我们从创建一个非常简单的项目容器实现开始:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
03
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
04
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
05
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
06

创建遍历器插件实例之后,

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
07
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
08

我们可以遍历到该容器的子对象:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
09

如果没有财产可以找到r子项,可以发生一些有趣的事情。在正常情况下 案例, 未找到 被引发:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
10

但是,如果请求是PUT请求,则必须生成空资源:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
11

但是,只有当当前资源是最后一个资源时,才会创建空资源 遍历堆栈中的一个:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
12

就这样。

发布者挂接rest请求

阅读本文档在某种程度上要求读者 熟悉出版过程的基本步骤。

发布请求工厂

当wsgi服务器发送请求时,zope发布过程开始。 可对zope wsgi发布服务器调用的环境和响应初始化 应用程序[1]。然后,wsgi发布者应用程序负责 在发布服务器中处理请求并输出结果。

为了在发布服务器中处理请求,我们必须创建一个有效的 发布服务器请求对象。wsgi发布服务器应用程序使用一个请求 为此目的而制造。此包实现此工厂以确保 始终会创建一个特殊的rest请求(基于http请求)。

使用zodb数据库对象实例化请求工厂:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
13

现在创建工厂:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
14

当请求从服务器传入时,将按如下方式创建该请求:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
15
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
16
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
17

我们现在有一个有效的请求,可以通过发布服务器发送:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
18

但是,请求只负责表示网络请求 在发布者中,对应用程序没有直接的了解。但是 请求连接到特定的应用程序(在本例中为zope 3) 称为出版物的组件。

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
19

因为我们不需要特殊的rest发布,所以我们只是重用 更通用的http版本。出版物对所有人都是一样的 请求。它还包含对数据库的引用:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
20

不幸的是,通过 发布服务器成功。该出版物还需要 发布可用,包括遍历、安全性和 构建数据库。但是,我们仍然可以看到一个失败:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
21

让我们放松一下。最初,我们从创造一个 内部使用rest请求的发布者wsgi应用程序实例。所有 您需要做的是:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
22

当wsgi服务器向wsgi应用程序发送请求时,如下所示 发生:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
23
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
24
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
25

其余请求

在大多数情况下,rest请求与http请求相同,因此我不会 详细介绍http请求api。

rest请求主要扩展http请求,因为它解析查询 一组参数中的URL字符串。这发生在 processinputs()

如果没有查询字符串,则参数映射为空:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
26

现在让我们传递几个参数:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
27

我们还重写了一些请求的映射方法,以便 和环境值可作为请求的一部分:

< Buff行情>
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
28
>>> from z3c.rest import testing
>>> client = testing.RESTClient()
29

其余响应

rest响应与http响应几乎相同,只是 它的异常处理程序返回XML而不是HTML。然而,这种方法是 仅用F或经典和字符串异常。

从响应开始,

<阻塞率> 啊!

…我们现在可以调用处理程序:

<阻塞率> AAAAAAAA 131号 AAAAAAA 132

让我们也尝试一个字符串异常:

<阻塞率> AAAAAAA 133

重定向异常是特殊的。它实际上导致请求 已重定向。

<阻塞率> AAAAAAAA 134号 aaaaaaaaa135号

休息视图

与浏览器视图不同,rest视图并不代表它自己的子资源。 (找到index.html)。相反,它仅仅定义了http的行为 特定内容组件的方法。

下面是一个示例:

<阻塞率> AAAAAAA 136

restview基类提供了一个合适的构造函数:

<阻塞率> 啊! AAAAAAA 138 AAAAAAA 139

当发布者遍历到myobj时,它将根据 http方法,搜索为get。然后它还希望找到一种同样的方法 命名并将其命名为@u[2]。

<阻塞率> AAAAA H140

与所有其他视图一样,rest视图公开其上下文和请求:

<阻塞率> AAAAA H141

因此,必须找到一个视图,这样它也有一个父视图:

<阻塞率> AAAAA H142

当然,您可以将其设置为其他值:

<阻塞率> AAAAA H143

更改

0.4.0(2010-10-05)

  • 在zope.app.http://cite>
  • 上添加了未声明但必需的安装依赖项

0.3.0(2010-10-05)

  • 添加了未声明的测试依赖项。
  • 更新了测试设置并修复了使用ZTK 1.0运行的测试。
  • 使用python的 doctest 模块而不是不赞成 zope.testing.doctest

0.2.5(2008-09-16)

  • bug/misfeature:最终按照需要处理url合并。所以 添加了大量测试来记录行为。

0.2.4(2008-09-04)

  • restclient()现在可以正确地解释 https:// url。

0.2.3(2008-03-20)

  • 错误/错误特征:叹气,正确转动尾部斜线 我觉得很痛苦。我真的希望我能让它正常工作 现在是rest客户机。

0.2.2(2008年3月19日)

  • bug/misfeature:客户端总是在url的末尾添加斜线。但是 一些restapi对此非常敏感。现在斜线只保留了 如果有的话,但不会有其他的添加。

0.2.1(2008-03-06)

  • 错误:有时没有读取响应体和客户端的内容 是空的。不幸的是,这个问题不能可靠地再现,但是 调试表明连接已提前关闭。(罗伊·马修)
  • 功能:使软件包python 2.4和2.5兼容。
  • 特点:z3c.rest需要lxml 2.0。

0.2.0(2008-03-03)

  • 特性:使http调用者可以为rest客户机插入,允许 除restriquest之外的请求类型

0.1.0(2008-03-03)

  • 初始释放
    • publisher挂钩以构建专用rest服务器
    • 错误视图支持
    • 基于z3c.traverser的可插拔rest traverser
    • rest客户端
    • 最小示例应用程序
    < /李>

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

推荐PyPI第三方库


热门话题
java如何在sqlite数据库中保存特定列的历史记录   java如何更改/更新timeseriechart名称(JFreeChart)   java如何将整数转换为可绘制的   汇编什么解释Java的字节码   java查找已编译的类版本号   我应该什么时候在ColdFusion应用程序中使用Java?   java当一个实体的两个字段为(unique=true)时,如何处理JPA异常?   java为什么在所有其他实例都正确的情况下返回错误的布尔值?   java Hibernate每次都准备语句   java停留在平均字长上   对Java和日语字符进行编码   java如何将导致异常的方法的错误消息传递给侦听器中的onTestFailure方法   java代码没有打印结果   java为什么私有内部接口的方法必须是公共的?   休眠发生错误。有关详细信息,请参阅错误日志。JAVAlang.NullPointerException