跳转到主要内容

Zope 3的XML-RPC方法自省支持

项目描述

此Zope 3软件包提供了一个XML-RPC自省机制。

详细文档

XMLRPC自省

现在什么是自省?

此Zope 3软件包提供了一个xmlrpcintrospection机制,如此处定义

http://xmlrpc-c.sourceforge.net/xmlrpc-howto/xmlrpc-howto-api-introspection.html

它注册了三个新的xmlrpc方法

  • listMethods():列出当前对象注册的所有xmlrpc方法(即视图)

  • methodHelp(method_name):返回给定方法的文档。

  • methodSignature(method_name):返回给定方法的签名。

如何使用它?

基本上,如果您想将自省添加到您的XMLRPCView中,您只需为视图中的每个方法添加一个装饰器,该装饰器指定方法的返回类型和参数类型。

装饰器名为xmlrpccallable

>>> from zope.app.xmlrpcintrospection.xmlrpcintrospection import xmlrpccallable
>>> from zope.app.publisher.xmlrpc import XMLRPCView
>>> class MySuperXMLRPCView(XMLRPCView):
...     @xmlrpccallable(str, str, str, str)
...     def myMethod(self, a, b, c):
...         """ my help """
...         return '%s %s, %s, lalalala, you and me, lalalala' % (a, b, c)

myMethod()然后将是可自省的。(以下是一个完整的示例,grep(*))

它是如何工作的?

它基于apidoc软件包提供的自省机制。

* 从xmlrpc doctests中提取 *

让我们编写一个返回文件夹列表的视图

>>> class FolderListing:
...     def contents(self):
...         return list(self.context.keys())

现在我们将它注册为一个视图

>>> from zope.configuration import xmlconfig
>>> ignored = xmlconfig.string("""
... <configure
...     xmlns="http://namespaces.zope.org/zope"
...     xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc"
...     >
...   <!-- We only need to do this include in this example,
...        Normally the include has already been done for us. -->
...   <include package="zope.app.publisher.xmlrpc" file="meta.zcml" />
...
...   <xmlrpc:view
...       for="zope.site.interfaces.IFolder"
...       methods="contents"
...       class="zope.app.xmlrpcintrospection.README.FolderListing"
...       permission="zope.ManageContent"
...       />
... </configure>
... """)

现在,我们在根文件夹中添加一些项目

>>> print http(r"""
... POST /@@contents.html HTTP/1.1
... Authorization: Basic bWdyOm1ncnB3
... Content-Length: 73
... Content-Type: application/x-www-form-urlencoded
...
... type_name=BrowserAdd__zope.site.folder.Folder&new_value=f1""")
HTTP/1.1 303 See Other
...
>>> print http(r"""
... POST /@@contents.html HTTP/1.1
... Authorization: Basic bWdyOm1ncnB3
... Content-Length: 73
... Content-Type: application/x-www-form-urlencoded
...
... type_name=BrowserAdd__zope.site.folder.Folder&new_value=f2""")
HTTP/1.1 303 See Other
...

并调用我们的xmlrpc方法

>>> print http(r"""
... POST / HTTP/1.0
... Authorization: Basic bWdyOm1ncnB3
... Content-Length: 102
... Content-Type: text/xml
...
... <?xml version='1.0'?>
... <methodCall>
... <methodName>contents</methodName>
... <params>
... </params>
... </methodCall>
... """)
HTTP/1.0 200 OK
...
<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><array><data>
<value><string>f1</string></value>
<value><string>f2</string></value>
</data></array></value>
</param>
</params>
</methodResponse>
<BLANKLINE>

* xmlrpc doctests的结束 *

现在我们想要为此视图提供自省。让我们添加三个新的xmlrcp方法,它们发布了自省API。

>>> ignored = xmlconfig.string("""
... <configure
...     xmlns="http://namespaces.zope.org/zope"
...     xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc"
...     >
...   <!-- We only need to do this include in this example,
...        Normally the include has already been done for us. -->
...   <include package="zope.app.publisher.xmlrpc" file="meta.zcml" />
...   <xmlrpc:view
...     for="zope.interface.Interface"
...     methods="listMethods  methodHelp methodSignature"
...     class="zope.app.xmlrpcintrospection.xmlrpcintrospection.XMLRPCIntrospection"
...     permission="zope.Public"
...     />
... </configure>
... """)
它们与XMLRPCIntrospection类相关联,实际上

了解如何查找所有接口

然后调用我们的xmlrpc方法,该方法应列出内容方法

>>> print http(r"""
... POST / HTTP/1.0
... Content-Type: text/xml
...
... <?xml version='1.0'?>
... <methodCall>
... <methodName>listMethods</methodName>
... <params>
... </params>
... </methodCall>
... """, handle_errors=False)
HTTP/1.0 200 OK
...
<?xml version='1.0'?>
<methodResponse>
...
<value><string>contents</string></value>
...
</methodResponse>
<BLANKLINE>

让我们尝试添加另一个方法,看看它是否会被列出...

>>> class FolderListing2:
...     def contents2(self):
...         return list(self.context.keys())
>>> from zope.configuration import xmlconfig
>>> ignored = xmlconfig.string("""
... <configure
...     xmlns="http://namespaces.zope.org/zope"
...     xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc"
...     >
...   <!-- We only need to do this include in this example,
...        Normally the include has already been done for us. -->
...   <include package="zope.app.publisher.xmlrpc" file="meta.zcml" />
...
...   <xmlrpc:view
...       for="zope.site.interfaces.IFolder"
...       methods="contents2"
...       class="zope.app.xmlrpcintrospection.README.FolderListing2"
...       permission="zope.ManageContent"
...       />
... </configure>
... """)
>>> print http(r"""
... POST / HTTP/1.0
... Content-Type: text/xml
...
... <?xml version='1.0'?>
... <methodCall>
... <methodName>listMethods</methodName>
... <params>
... </params>
... </methodCall>
... """, handle_errors=False)
HTTP/1.0 200 OK
...
<?xml version='1.0'?>
<methodResponse>
...
<value><string>contents</string></value>
<value><string>contents2</string></value>
...
</methodResponse>
<BLANKLINE>

现在我们想要测试methodHelp和methodSignature,以检查它们是否返回:

  • 方法文档

  • 属性列表

在RPC中,属性列表必须以类型数组的形式返回

[返回类型,param1类型,param2类型]

由于在Python中我们无法为方法返回类型设置静态类型,因此我们在此引入了一种基于装饰器的新机制,允许xmlrpcview开发者添加自己的签名。

如果没有提供签名,则返回默认列表

[None, None, None…]

装饰器向函数对象添加两个新参数,以获取签名。

>>> from zope.app.xmlrpcintrospection.xmlrpcintrospection import xmlrpccallable
>>> class JacksonFiveRPC:
...     @xmlrpccallable(str, str, str, str)
...     def says(self, a, b, c):
...         return '%s %s, %s, lalalala, you and me, lalalala' % (a, b, c)

让我们尝试获取签名

>>> JacksonFiveRPC().says.return_type
<type 'str'>
>>> JacksonFiveRPC().says.parameters_types
(<type 'str'>, <type 'str'>, <type 'str'>)

方法仍然可以按需调用

>>> JacksonFiveRPC().says('a', 'b', 'c')
'a b, c, lalalala, you and me, lalalala'

让我们尝试装饰和不装饰的方法签名(*)

>>> class JacksonFiveRPC:
...     @xmlrpccallable(str, str, str, str)
...     def says(self, a, b, c):
...         return '%s %s, %s, lalalala, you and me, lalalala' % (a, b, c)
...     def says_not_decorated(self, a, b, c):
...         return '%s %s, %s, lalalala, you and me, lalalala' % (a, b, c)
>>> from zope.configuration import xmlconfig
>>> ignored = xmlconfig.string("""
... <configure
...     xmlns="http://namespaces.zope.org/zope"
...     xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc"
...     >
...   <!-- We only need to do this include in this example,
...        Normally the include has already been done for us. -->
...   <include package="zope.app.publisher.xmlrpc" file="meta.zcml" />
...
...   <xmlrpc:view
...       for="zope.site.folder.IFolder"
...       methods="says says_not_decorated"
...       class="zope.app.xmlrpcintrospection.README.JacksonFiveRPC"
...       permission="zope.ManageContent"
...       />
... </configure>
... """)

现在让我们尝试获取 says() 的签名

>>> print http(r"""
... POST / HTTP/1.0
... Content-Type: text/xml
...
... <?xml version='1.0'?>
... <methodCall>
... <methodName>methodSignature</methodName>
... <params>
... <param>
... <value>says</value>
... </param>
... </params>
... </methodCall>
... """, handle_errors=False)
HTTP/1.0 200 OK
...
<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><array><data>
<value><array><data>
<value><string>str</string></value>
<value><string>str</string></value>
<value><string>str</string></value>
<value><string>str</string></value>
</data></array></value>
</data></array></value>
</param>
</params>
</methodResponse>
<BLANKLINE>

现在让我们尝试获取 says_not_decorated() 的签名

>>> print http(r"""
... POST / HTTP/1.0
... Content-Type: text/xml
...
... <?xml version='1.0'?>
... <methodCall>
... <methodName>methodSignature</methodName>
... <params>
... <param>
... <value>says_not_decorated</value>
... </param>
... </params>
... </methodCall>
... """, handle_errors=False)
HTTP/1.0 200 OK
...
<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><array><data>
<value><array><data>
<value><string>undef</string></value>
<value><string>undef</string></value>
<value><string>undef</string></value>
<value><string>undef</string></value>
</data></array></value>
</data></array></value>
</param>
</params>
</methodResponse>
<BLANKLINE>

最后但同样重要的是,方法帮助

>>> class JacksonFiveRPCDocumented:
...     @xmlrpccallable(str, str, str, str)
...     def says(self, a, b, c):
...         """ this is the help for
...             says()
...         """
...         return '%s %s, %s, lalalala, you and me, lalalala' % (a, b, c)
...     def says_not_documented(self, a, b, c):
...         return '%s %s, %s, lalalala, you and me, lalalala' % (a, b, c)
>>> from zope.configuration import xmlconfig
>>> ignored = xmlconfig.string("""
... <configure
...     xmlns="http://namespaces.zope.org/zope"
...     xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc"
...     >
...   <!-- We only need to do this include in this example,
...        Normally the include has already been done for us. -->
...   <include package="zope.app.publisher.xmlrpc" file="meta.zcml" />
...
...   <xmlrpc:view
...       for="zope.site.folder.IFolder"
...       methods="says says_not_documented"
...       class="zope.app.xmlrpcintrospection.README.JacksonFiveRPCDocumented"
...       permission="zope.ManageContent"
...       />
... </configure>
... """)
>>> print http(r"""
... POST / HTTP/1.0
... Content-Type: text/xml
...
... <?xml version='1.0'?>
... <methodCall>
... <methodName>methodHelp</methodName>
... <params>
... <param>
... <value>says</value>
... </param>
... </params>
... </methodCall>
... """, handle_errors=False)
HTTP/1.0 200 OK
...
<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><string> this is the help for
             says()
         </string></value>
</param>
</params>
</methodResponse>
<BLANKLINE>
>>> print http(r"""
... POST / HTTP/1.0
... Content-Type: text/xml
...
... <?xml version='1.0'?>
... <methodCall>
... <methodName>methodHelp</methodName>
... <params>
... <param>
... <value>says_not_documented</value>
... </param>
... </params>
... </methodCall>
... """, handle_errors=False)
HTTP/1.0 200 OK
...
<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><string>undef</string></value>
</param>
</params>
</methodResponse>
<BLANKLINE>

更改

3.5.1 (2010-02-06)

  • 通过包含 zope.login 修复测试

  • 从 zope.app.securitypolicy.browser.tests 包含 ftesting.zcml

  • 从 zope.securitypolicy 包含 meta.zcml

3.5.0 (2009-02-01)

  • 使用 zope.site 更新 zope.app.folder

3.4.0 (2007-11-03)

  • 首次发布独立于主 Zope 树。

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

zope.app.xmlrpcintrospection-3.5.1.tar.gz (10.3 kB 查看哈希值)

上传时间

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面