XML-RPC views
=============
XML-RPC Methods
---------------
There are two ways to write XML-RPC views. You can write views that
provide "methods" for other objects, and you can write views that have
their own methods. Let's look at the former case first, since it's a
little bit simpler.
Let's write a view that returns a folder listing:
>>> class FolderListing:
... def contents(self):
... return list(self.context.keys())
Now we'll register it as a view:
>>> 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.app.folder.folder.IFolder"
... methods="contents"
... class="zope.app.publisher.xmlrpc.README.FolderListing"
... permission="zope.ManageContent"
... />
... </configure>
... """)
Now, we'll add some items to the root folder:
>>> 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.app.folder.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.app.folder.folder.Folder&new_value=f2""")
HTTP/1.1 303 See Other
...
And call our xmlrpc method:
>>> from zope.app.testing.xmlrpc import ServerProxy
>>> proxy = ServerProxy("http://mgr:mgrpw@localhost/")
>>> proxy.contents()
['f1', 'f2']
Note that we get an unauthorized error if we don't supply authentication
credentials:
>>> proxy = ServerProxy("http://localhost/")
>>> proxy.contents()
Traceback (most recent call last):
ProtocolError: <ProtocolError for localhost/: 401 401 Unauthorized>
Named XML-RPC Views
-------------------
Now let's look at views that have their own methods or other
subobjects. Views that have their own methods have names that appear
in URLs and they get traversed to get to their methods, as in::
.../somefolder/listing/contents
To make this possible, the view has to support traversal, so that,
when it is traversed, it traverses to its attributes. To support
traversal, you can implement or provide an adapter to
`zope.publisher.interfaces.IPublishTraverse`. It's actually better to
provide an adapter so that accesses to attributes during traversal are
mediated by the security machinery. (Object methods are always bound
to unproxied objects, but adapters are bound to proxied objects unless
they are trusted adapters.)
The 'zope.app.publisher.xmlrpc' package provides a base class,
`MethodPublisher`, that provides the necessary traversal support. In
particulat, it has an adapter that simply traverses to attributes.
If an XML-RPC view isn't going to be public, then it also has to
implement 'zope.location.ILocation' so that security grants can be
acquired for it, at least with Zope's default security policy. The
`MethodPublisher` class does that too.
Let's modify our view class to use `MethodPublisher`:
>>> from zope.app.publisher.xmlrpc import MethodPublisher
>>> class FolderListing(MethodPublisher):
...
... def contents(self):
... return list(self.context.keys())
Note that `MethodPublisher` also provides a suitable `__init__`
method, so we don't need one any more. This time, we'll register it
as as a named view:
>>> 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
... name="listing"
... for="zope.app.folder.folder.IFolder"
... methods="contents"
... class="zope.app.publisher.xmlrpc.README.FolderListing"
... permission="zope.ManageContent"
... />
... </configure>
... """)
Now, when we access the `contents`, we do so through the listing view:
>>> proxy = ServerProxy("http://mgr:mgrpw@localhost/listing/")
>>> proxy.contents()
['f1', 'f2']
>>> proxy = ServerProxy("http://mgr:mgrpw@localhost/")
>>> proxy.listing.contents()
['f1', 'f2']
as before, we will get an error if we don't supply credentials:
>>> proxy = ServerProxy("http://localhost/listing/")
>>> proxy.contents()
Traceback (most recent call last):
ProtocolError: <ProtocolError for localhost/listing/: 401 401 Unauthorized>
Parameters
----------
Of course, XML-RPC views can take parameters, too:
>>> class ParameterDemo:
... def __init__(self, context, request):
... self.context = context
... self.request = request
...
... def add(self, first, second):
... return first + second
Now we'll register it as a view:
>>> 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.app.folder.folder.IFolder"
... methods="add"
... class="zope.app.publisher.xmlrpc.README.ParameterDemo"
... permission="zope.ManageContent"
... />
... </configure>
... """)
Then we can issue a remote procedure call with a parameter and get
back, surprise!, the sum:
>>> proxy = ServerProxy("http://mgr:mgrpw@localhost/")
>>> proxy.add(20, 22)
42
Faults
------
If you need to raise an error, the prefered way to do it is via an
`xmlrpclib.Fault`:
>>> import xmlrpclib
>>> class FaultDemo:
... def __init__(self, context, request):
... self.context = context
... self.request = request
...
... def your_fault(self):
... return xmlrpclib.Fault(42, "It's your fault!")
Now we'll register it as a view:
>>> 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.app.folder.folder.IFolder"
... methods="your_fault"
... class="zope.app.publisher.xmlrpc.README.FaultDemo"
... permission="zope.ManageContent"
... />
... </configure>
... """)
Now, when we call it, we get a proper XML-RPC fault:
>>> proxy = ServerProxy("http://mgr:mgrpw@localhost/")
>>> proxy.your_fault()
Traceback (most recent call last):
Fault: <Fault 42: "It's your fault!">
DateTime values
---------------
Unfortunately, `xmlrpclib` does not support Python 2.3's new
`datetime.datetime` class (it should be made to, really). DateTime
values need to be encoded as `xmlrpclib.DateTime` instances:
>>> import xmlrpclib
>>> class DateTimeDemo:
... def __init__(self, context, request):
... self.context = context
... self.request = request
...
... def epoch(self
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
共96个文件
py:58个
zcml:15个
txt:9个
资源分类:Python库 所属语言:Python 资源全名:zope.app.publisher-3.4.0b1dev-r78108.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
资源推荐
资源详情
资源评论
收起资源包目录
zope.app.publisher-3.4.0b1dev-r78108.tar.gz (96个子文件)
zope.app.publisher-3.4.0b1dev-r78108
PKG-INFO 272B
CHANGES.txt 564B
bootstrap.py 2KB
src
zope
app
__init__.py 200B
publisher
testing.py 1011B
pagetemplateresource.py 2KB
tests
test_fieldconverters.py 2KB
__init__.py 38B
xmlrpc
README.txt 12KB
tests
test_directives.py 4KB
xmlrpc_nonamenoperm.zcml 342B
xmlrpc.zcml 2KB
__init__.py 61B
xmlrpc_error.zcml 426B
test.pt 38B
test_functional.py 2KB
xmlrpc_noperm.zcml 361B
meta.zcml 302B
metaconfigure.py 4KB
__init__.py 2KB
configure.zcml 1KB
metadirectives.py 3KB
meta.zcml 173B
DEPENDENCIES.cfg 17B
browser
resourcemeta.py 4KB
resource.py 1KB
menumeta.py 10KB
i18nfileresource.py 3KB
pagetemplateresource.py 2KB
i18nresourcemeta.py 4KB
directoryresource.py 4KB
tests
test_browserlanguages.py 3KB
test_directives.py 41KB
test_pagetemplateresource.py 2KB
support.py 1KB
test_directoryresource.py 5KB
test_icondirective.py 7KB
testfiles
subdir
test.gif 909B
test3.pt 64B
test2.pt 62B
png 10B
test.txt 10B
test.pt 38B
test.gif 909B
testresource.pt 58B
menus-permissions.zcml 456B
test_fileresource.py 4KB
menus.zcml 2KB
test_resource.py 2KB
test_menu.py 1KB
__init__.py 61B
addmenuitems.zcml 640B
test_api.py 936B
testi18nfileresource.py 5KB
test_menudirectives.py 5KB
templateclass.py 789B
test_resources.py 3KB
test_addMenuItem.py 14KB
test_fields.py 1KB
managementviewselector.py 2KB
meta.zcml 4KB
metaconfigure.py 14KB
__init__.py 5KB
menu.py 6KB
fields.py 4KB
configure.zcml 3KB
resources.py 2KB
fileresource.py 5KB
viewmeta.py 14KB
vocabulary.py 1KB
icon.py 4KB
metadirectives.py 21KB
menu.txt 20KB
__init__.py 61B
http.zcml 521B
fieldconverters.py 2KB
interfaces
http.py 2KB
ftp.py 5KB
browser.py 6KB
__init__.py 61B
xmlrpc.py 973B
configure.zcml 228B
fileresource.py 2KB
ftesting.zcml 1KB
i18n.py 939B
__init__.py 200B
zope.app.publisher.egg-info
PKG-INFO 272B
requires.txt 429B
not-zip-safe 1B
SOURCES.txt 4KB
top_level.txt 5B
namespace_packages.txt 14B
dependency_links.txt 1B
setup.cfg 69B
setup.py 2KB
buildout.cfg 166B
共 96 条
- 1
资源评论
挣扎的蓝藻
- 粉丝: 12w+
- 资源: 15万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功