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 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | fead926e3f1f7f39bc62f5906634d143973d00b7b34f24e691cc2b5bfe7870a6 |
|
MD5 | 8cf0e7fc13ece3743f96f92d05682d74 |
|
BLAKE2b-256 | 4cb9ec4ad5e62eca449af19c9bb3fb3ef1e0de05a260f0a60e1ca59c9e5e2878 |