使用wadl文件作为指南导航http资源。

wadllib的Python项目详细描述



Copyright(C)2008—2013规范有限公司BR/> BR/>此文件是WADLLIB的一部分。
BR/> WADLLIB是免费软件:您可以在
< GB/>自由软件基金会发布的GNU小通用公共许可证的条款下重新分发和/或修改它。许可证。

wadllib的分发是希望它有用,但没有任何
保证;甚至没有针对特定目的的适销性或适用性的暗示保证。有关
更多详细信息,请参阅gnu less general public license。


您应该已经收到gnu less general public license
和wadllib的副本。如果没有,请参阅<;http://www.gnu.org/licenses/>;

*****


>应用程序对象表示由wadl
文件描述的Web服务。

>;>;>;>;
>;
application构造函数的第一个参数是找到wadl文件的url。第二个参数可能是原始的wadl标记。

>;>wadl_string=pkg_resources.resource_string(
…)wadllib.tests.data,'launchpad wadl.xml')
>;>;wadl=application("http://api.launchpad.dev/beta/",wadl\u string)


>或者第二个参数可以是包含标记的打开文件句柄。

>;>;cleanups=[]
>;>;def application\u for(filename,url="http://www.example.com/":
…wadl_stream=pkg_resources.resource_stream(
…)wadllib.tests.data',filename)
…清除。附加(wadl_stream)
…返回应用程序(url,wadl_stream)
>;>wadl=application_for("launchpad wadl.xml",
…"http://api.launchpad.dev/beta/"



链接导航
==


查找资源的首选技术是从wadl文件中定义的资源之一开始,然后按照链接进行操作。此代码
检索根资源的定义。

>;>;service_root=wadl.get_resource_by_path('')
>;>;service_root.url
'http://api.launchpad.dev/beta/'
>;>;service_root.type_url
'service root'

资源支持get。

>;>get_method=service_root.get_method('get')
>;>get_method.id
‘service root get’

>;>get_method=service_root.get_method('get')
>;get_method.id
‘service root get’

t要调用此方法,我们向服务发送get请求
根url。

>;>;get_method.name
"get"
>;>;get_method.build_request_url()
"http://api.launchpad.dev/beta/"

资源的wadl描述知道哪些表示是
可用于该资源。在本例中,服务器根资源
有一个json表示,它定义了诸如
"people_collection_link"之类的参数,这是指向launchpad中人员列表的链接。我们
应该能够使用get_parameter()方法来获取"people_collection_link"参数的wadl
定义,并找到更多关于它的
例如,它是到另一个资源的链接吗?

>;>def test_raises(exc_class,method,*args,**kwargs):
…尝试:
…方法(*args,**kwargs)
…例外情况除外:
…#同时支持python<;2.6和>;=3的扭曲。
…e=sys.exc_info()[1]
…如果是(e,exc_类):
…打印(E)
…返回
…升高
…引发异常("预期异常%s未引发%exc_类)

>>>;来自wadllib.ap应用程序导入noboundrepresentationerror
>;>;link_name='people_collection_link'
>;>;test_raises(
…noboundrepresentationerror,service_root.get_参数,link_name)
资源未绑定到任何表示,并且未指定媒体类型。

oops。代码无法知道"people_collection_link"是json表示形式的参数还是其他类型的表示形式。我们可以传递一个媒体类型以获取参数,并让它知道参数所处的表示形式。

>;>;link_parameter=service_root.get_parameter(
…link_name,"application/json")
>;>test_raises(noboundrepresentationerror,link_parameter.get_value)
资源未绑定到任何表示。

参数是可用的,但没有值,因为
没有与资源关联的实际数据。浏览器可以查找get方法的描述以向服务根发出实际的get请求,并将得到的表示绑定到服务根的wadl描述。

由WADL描述理解的媒体类型的E。

>;>>来自WADLLIB。应用程序导入不支持的媒体类型错误
>;>>测试引发(
…UnsupportedMediaTypeerror,服务根。绑定,
…<;html>;某些html<;html>;','文本/html')
此资源未定义媒体类型text/html的表示形式

服务根资源的wadl描述具有json
表示形式。这里是。

>;>json_representation=service_root.get_representation_definition(
…)application/json')
>;>;json_表示。media_type
"application/json"

我们已经有了服务根资源的wadl表示,所以
让我们尝试将其绑定到该json表示。我们使用文件中的测试json
数据来模拟对
服务根目录的get请求的结果。


>;>def get\u test data(filename):
…返回pkg_resources.resource_字符串(
…)wadllib.tests.data',filename+'.json')

>>>def bind_to_testdata(resource,filename):
…return resource.bind(get_test data(filename),'application/json')

nd_service_root.parameter s())
['bugs_collection_link','people_collection_link']
>;>service root get']


现在绑定的资源对象有一个json表示,现在
"people_collection_link"有意义了。我们可以按照
"people_collection_link"指向新的资源对象。

>;>link_parameter=bound_service_root.get_parameter(link_name)
>;>link_parameter.style
"plain"
>;http://api.launchpad.dev/beta/people
>;>personset_resource=link_参数。linked_resource
>;>personset_resource.\uu class庘u
<;class'wadllib.application.resource'>;
>;>print(personset庘resource.url)
http://api.launchpad.dev/beta/people
>;>;personset_resource.type戋url
'http://api.launchpad.dev/beta/people'


此新资源是人员集合。

>;>;personset戋resource.id
"人员集合"资源支持标准get请求
,以及特殊get和重载post。get_method()方法
用于检索
可能发出的http请求的wadl定义。下面是如何获取标准get
请求的wadl定义。

>;>;get_method=personset_resource.get_method('get')
>;>;get_method.id
"people get"

t>>personset_resource.get_method('get').id
"people get"


要调用特殊的get请求,客户端将"ws.op"查询
参数设置为固定字符串"findperson"。

>;find_method=personset_resource.get_method(
…查询参数={'ws.op':'findperson'})
>;>;查找方法.id
'people findperson'

_url(text="foo")
http://api.launchpad.dev/beta/people?text=foo&ws.op=findperson

>>print(find_method.build_request_url(
…{'ws.op':'findperson','text':'bar'}))
http://api.launchpad.dev/beta/people?text=bar&ws.op=findperson

或必需的参数"text"

>;>;find_method.build_request_url(
…{'ws.op':'findaperson','text':'foo'})
…#doctest:+省略号,+normalize_whitespace
回溯(最后一次调用):

值错误:参数'ws.op'的值'findaperson'与固定值'findperson'冲突



要调用重载的post请求,客户端设置'ws.op'
查询变量固定字符串'newteam':

>>gt;create_team_method=personset_resource.get_method(
…'post',representation_params={'ws.op':'newteam'})
>;>create_team_method.id
'people newteam'

名称或固定参数匹配的wadl方法时返回none。

>;>print(personset_resource.get_method('nosuchmethod'))


>>>打印(personset_resource.get_method(
…)post',query_params={'ws_op':'nosuchparam'})
none


假设浏览器向person set资源发出get请求并返回一个表示。我们可以将该表示绑定到我们对人员集资源的
描述。

>;>;bound_person set=bind_to_testdata(personset_resource,'personset')
>;>;bound_personset.get_parameter("start")。get_value()
0
>;>;bound_personset.get_parameter("total_size").get_value()
63


_ collection_link")
>>gt;打印(下一页_link.get_value())
http://api.launchpad.dev/beta/people?ws.start=5&ws.size=5
>;>;第二页=下一页链接。链接的资源
>;>;绑定的第二页=绑定到测试数据(第二页,"personset-page2")
>;>;打印(绑定的第二页。url)
http://api.launchpad.dev/beta/people?ws.start=5&ws.size=5
>;>bound_page_two.get_parameter("start").get_value()
5
>;>print(bound_page_two.get_parameter("next_collection_link").get_value())
http://api.launchpad.dev/beta/people?威斯塔rt=10&ws.size=5

响应将包含多个http头,
包括"location",这将指向新创建的团队。

>>headers={location':'http://api.launchpad.dev/~newteam'}
>>response=create_team_method.response.bind(headers)
>>location_parameter=response.get_parameter('location')
>>>gt>gt;location_参数。get_值()
'http://api.launchpad.dev/~new team'
>>>>>>gt>gt;新的团队=location_参数。新的团队=location_参数。链接的资源
>>gt;新的团队。url
'http://api.launchpad.dev/~newteam'
>>>>>http://api.launchpad.dev/~newteam'
>'http://api.launchpad.launchpad.dev/beta/dev/beta/beta/http://api.launchpad.launchpa'

检查ng links
----


参数的"linked_resource"属性允许您跟随链接
到另一个对象。参数的"link"属性允许您在跟踪链接之前检查链接。

>;>;导入json
>;>;links\u wadl=application\u for('links-wadl.xml')
>;>;service\u root=links\u wadl.按路径获取资源(''
>;>;representation=json.dumps(
…{标量值':'foo',
…'已知链接':'http://known/',
…'未知链接:'http://unknown/'})
>;>;绑定根=服务根。绑定(表示)

>;>;打印(绑定根。获取根参数("标量值").link)
none

>;>;已知资源=绑定根。获取根参数("已知链接")
>;>;未知资源=绑定根。获取根参数("unknow"n_link")

>;>print(known_resource.link.can_follow)
true
>;>print(known_resource.link.can_follow)
false

使用.linked_resource或.link.follow跟踪此链接将导致wadllib错误。您需要使用常规的http库或其他工具来跟踪链接。

>;
>;已知资源。链接。跟踪
<;wadllib.application.resource object…>;
>;
>;已知资源。链接的资源
<;wadlib.application.resource object…>;

>;
>;来自wadlib.application在导入wadlerror时,
>;>test_raises(wadlerror,getattr,unknown_resource.link,'follow')
如果目标没有wadl
描述,则无法跟踪链接。请改用常规http客户端。

>;>;测试引发(wadlerror、getattr、未知的资源、"链接的资源")
当目标没有wadl
描述时,无法跟踪链接。尝试改用常规http客户端。

_键入>;标记。有时在wadl<;method>;标记中定义表示法


>;find_method=personset_resource.get_method(
…查询参数={'ws.op':'find'})
>;>;查找方法.id
'people find'

>;>;表示定义=(
…find_method.response.get_representation_definition(
…)application/json'))


此处定义的
表示可能没有wadl<;resource>;或<;resource\u type>;标记。这就是为什么wadlib可以只使用表示定义来实例化匿名资源对象。


>;从wadlib.application import resource
>>wadl,"http://foo/",表示定义在.tag上)

get_testdata('personset'),'application/json',
…representation_definition=representation_definition)

total_size','application/json').get_value())
63


resource instantiation
==


URCE
>;>limi_person=资源(WADL,"http://api.launchpad.dev/beta/~limi",
…http://api.launchpad.dev/beta/person"
>>gt;排序([limi person.method iter中的方法的方法ID])[:3]
["person-acceptinvitationtobememberof","person addmember","person declineinvitationtobememberof"]

>;"bound_limi=bind_to懔testdata(limi person,"person limi")
>>gt;排序(bound懔limi.parameter_names())[:3]
['admins_collection_link','confirmed_email_addresses_collection_link',
'date_created']
>;>languages_link=bound_limi.get_parameter("languages_collection_link")
>;http://api.launchpad.dev/beta/~limi/languages

创建表示时将资源转换为表示。

>;>;limi_data=get_testdata('person-limi')
>;>;bound_limi=resource(
…wadl,"http://api.launchpad.dev/beta/~limi",
http://api.launchpad.dev/beta/person",Limi_数据,
…application/json"
>>>>打印(绑定limi.get_参数(
…"languages_collection_link").get_value())
http://api.launchpad.dev/beta/~limi/languages

>默认情况下,表示被视为字符串,并根据传递给资源构造函数的媒体类型进行处理。如果
您已经处理了表示,请为
"表示需要处理"参数传入false。

/>"…"http://api.launchpad.dev/beta/"个人",处理的"Limi"数据,
…application/json,"false"
>;>print(bound_limi.get_参数(
…)languages_collection_link").get_value())
http://api.launchpad.dev/beta/~limi/languages

>大多数情况下,资源的表示类型是通过向该资源发送标准get得到的类型。如果不是这样的话,可以将representation definition指定为bind()的
"representation\u definition"参数或resource
构造函数,以显示表示的实际外观。这里有一个例子。


person resource上有一个方法,比如bound_limi,它由一个独特的查询参数标识:ws.op=getMembersByStatus。

>;>method=bound_limi.get_method(
…query_params={'ws.op':'findpathtoteam'})


使用get请求调用此方法,您将从
人员列表返回一个页面。

>;>;人员页面重复定义=(
…method.response.get_representation_definition('application/json')
>;>people_repr_definition.tag.attrib['ref']
'http://api.launchpad.dev/beta/person page'

/>>>>>people_page_repr=get_testdata('personset')

wadllib会认为表示的类型是
"person-full",这是绑定limi的默认get类型。

>;>bad_people_page=bound_limi.bind(people_page_repr)
>;>print(bad_people_page.get_parameter('total_size'))
none

如果有一个"person full"表示,我们将无法获取此类表示的参数值。


>;bad_people_page.get_parameter('name').get_value()
traceback(最近的最后一次调用):

keyrerror:'name'

死胡同*但是*,如果我们将正确的表示形式
类型传递到bind()中,我们可以访问与
"person-page"表示形式相关联的参数。

>;>;people-page=bound\u limi.bind(
…"人"页面"报告"
…representation_definition=people_page_repr_definition)
>;>;people_page.get_parameter('total_size').get_value()
63


表示定义('text/html')
none

>>>服务根=数据类型。按路径('')获取资源。

>>>表示=json.dumps(
…{日期':'2007-10-20',
…'a"u datetime":"2005-06-06t08:59:51.619713+00:00"})
>;>;绑定根=服务根。绑定(表示,'application/json')

>;>;绑定根。获取参数('a'u date')。获取值()
datetime.datetime(2007,10,20,0,0)
>;>;绑定根。获取参数("a_datetime").get_value()
datetime.datetime(2005、6、6、8,…)


"日期"字段可以包含时间戳,"日期"字段可以
省略时间戳。wadllib将把两者都转换为datetime对象。

>;>representation=json.dumps(
…{日期':'2005-06-06t08:59:51.619713+00:00',
…'a懔datetime':'2007-10-20'})
>;>;bound懔root=service懔root.bind(表示,"application/json")

>;>;bound懔root.get懔parameter('a懔datetime').get懔value()
datetime.datetime(2007,10,20,0,0)
>;>;bound懔root.get懔parameter('a懔date').get懔valuee()
datetime.datetime(2005、6、6、8,…)

如果
值是无法解析为DateTime对象的字符串,则会得到一个
值错误。

>;>;representation=json.dumps(
…{'a_date':'foo','a_datetime':none})
>;>bound_root=service_root.bind(表示,"application/json")
>;>bound_root.get_parameter('a_date').get_value()
回溯(最近一次调用):

valueerror:foo
>;>print(bound_root.get_parameter('a_datetime').get_value())
none


representation creating
======



调用某些方法时必须提供表示。
representation()方法可以帮助您在不知道如何组合表示的
详细信息的情况下构建表示。

>;>;创建团队方法。构建表示(
…display_name='joe bloggs',name='joebloggs')
('application/x-www-form-urlencoded','display_name=joe+bloggs&;name=joebloggs&ws.op=newteam')

build_表示的返回值是2-包含生成表示的
媒体类型和字符串表示
本身的元组。与资源的url一起,这就是将表示发送到web服务器所需的全部内容。


>;>;绑定的"limi.get_method('patch')。构建表示(name='limi2')
('application/json','{"name":"limi2"}')

表示可能需要特定par的值。ameters.

>;>create_team_method.build_representation()
traceback(最近的最后一次调用):

valueerror:所需参数"display_name"没有值

>;>bound_limi.get_method('put')。build_representation(name='limi2')
tracebackk(最近一次调用时间):

valueerror:所需参数"mugshot_link"没有值


某些表示形式可能安全地包含二进制数据。

>;>binary_stream=pkg_resources.resource_stream(
…'wadllib.tests.data','multipart binary wadl.xml')
>>>>cleanups.append(binary_stream)
>>>>binary_wadl=应用程序(
…"http://www.example.com/",binary_stream)
>;>;service_root=binary_wadl.get_resource_by_path('')


>定义一个帮助程序,该帮助程序以与zope.publisher相同的方式处理表示。

>;>;导入cgi
>;>;导入io
>;>f断言消息部分(媒体类型,文档,应为):
…如果sys.version_info[0]==3和sys.version_info[1]<;3:
…#由于https://bugs.python.org/issue18013,我们做不了什么。对于预期值:
…如果不是ISINSTANCE(值,字节):
…value=value.encode('utf-8')
…在文档中断言值
…返回
…环境={
…'请求方法':'发布',
…'内容类型:媒体类型,
…内容长度:str(len(doc)),
…}
…夸尔格斯=(
…{'encoding':'utf-8'}如果sys.version_info[0]>;=3否则{})
…fs=cgi.fieldstorage(
…fp=io.bytesio(doc),environ=environ,keep_blank_values=1,
…**kwargs)
…值=[]
…定义附加值(字段):
…对于字段中的字段:
…如果字段。列表:
…附加值(field.list)
…其他:
…values.append(field.value)
…附加值(fs.list)
…assert values==需要,(
…'需要%s,得到%s%(需要,值))

>;>method=service_root.get_method('post','multipart/form data')
>;>media_type,doc=method.build_representation(
…text_field="text",binary_field=b"\x01\x02\r\x81\r")
>;>print(media_type)
multipart/form data;boundary=…
>;>assert_message_parts(media_type,doc,['text',b'\x01\x02\r\x81\r'])

>;>method=service_root.get_method('post','multipart/form data')
>>>媒体类型,doc=方法。构建表示(
…text_field="text\n",binary_field=b"\x01\x02\r\x81\n\r"
>;>print(media_type)
multipart/form data;boundary=…
>;>assert_message_parts(
…media_type,doc,['text\r\n',b'\x01\x02\r\x81\n\r'])

>;>;method=service_root.get_method('post','multipart/form data')
>;>;media_type,doc=method.build_表示(
…text_field="text\r\nmore\r\n",
…二进制字段=B"\x01\x02\r\n\x81\r\x82\n")
>;>打印(媒体类型)
多部分/表单数据;边界=…
>;>断言消息部分(
…媒体类型,文档,['text\r\nmore\r\n',b'\x01\x02\r\n\x81\r\x82\n'])

>;>;method=service_root.get_method('post','text/unknown')
>;>;method.build_representation(field="value")
回溯(最近一次调用的最后一次):

valueerror:不支持的媒体类型:"text/unknown"

options
=


ameters从预定义的选项列表中获取值。

>;>;option_wadl=application_for('options-wadl.xml')
>;>;definitions=option_wadl.representation_definitions
>;>;service_root=option_wadl.get_resource_by_path('')
>;>;defiinition=definitions['service-root-json']
>;>param=definition.params(service_-root)[0]
>;>print(param.name)
has_options
>;>sorted([option.value for option in param.options])
['value 1','value 2']

不在列表中的值。

>>定义。验证参数值(
…[参数],{'has_options':'value 1'})
{'has_options':'value 1'}

>>gt;定义。验证参数值(
…[参数],{'has_options':'无效值'})
回溯(最近一次调用最后一次):

value error:无效值'invalid value'用于参数
'has_options':有效值为:"值1","值2"



您尝试查找不存在的资源。

>;>print(wadl.get_resource_by_path('nosuchresource')
none

aceback(最近一次调用的最后一次):
keyerror:"没有这样的xml id:"nosuchtype"'


如果您试图查找参数与任何定义的方法都不匹配的方法,则将不会得到任何结果。

>;>;print(bound戋limi.get戋method(
…)post',representation_params={foo':'bar'}))



…清理
>;>>对于清理中的流:
…stream.close()



…目录树:
:glob:



docs/>




============

关于瓦德利布的新闻
======



1.3.3(2018-07-20)3.3(2018-07-07-7-20)
==========br/>

:放弃对python<;2.6;2.6;的支持





测试支持。
-实现mime多部分/表单数据的子集本地编码而不是使用标准库的email模块,该模块不能很好地处理二进制部分,并且会损坏二进制部分中的字节,这些字节看起来像line
结尾,具体方式取决于python版本。[错误=1729754]


1.3.2(2013-02-25)
====


-强制排序顺序以避免由于散列随机化而导致的测试失败。
lp:1132125
-确保关闭pkg_resources打开的流。resource_stream()以避免





1.3.1(2012-03-22)
==
==

=-更正导致日期时间问题的双传递字符串


<1.3.0(2012-01-27)
==
==


-添加python 3兼容性

-添加在跟踪链接之前检查链接的能力。

-确保示例数据已打包。


1.2.0(2011-02-03)
==
==


-现在可以在跟踪链接之前检查链接,查看它是否具有wadl描述,或者是否需要使用普通http客户端获取它。

使用.parameter s()方法覆盖资源的参数对象


1.1.8(2010-10-27)
=====


-此版本不包含代码更改,但生成系统已更改(再次)。这次包括setup.py使用的version.txt文件没有代码更改,但生成系统已被更改(再次)以包括测试中使用的示例数据。


1.1.6(2010-10-21)
==


-此版本不包含代码更改,但生成系统已被更改以包括测试中使用的示例数据。

1.1.5(2010-05-04)
===
==

-修复了一个错误(launchpad错误274074),该错误阻止在与
表示定义(而不是具有
表示定义的资源类型)直接关联的资源中查找
参数值。由james westby提供的错误修复。




-向安装文件中添加缺少的依赖项。



-从setup.py中删除sys.path hack。


>1.1.2(2009-08-08-20年)
=====



















>








>1.1.1.2(2009-08-08-08-20)1.2(2009-08-08-08-20瓦德利布意识到标记下面的<;option>;标记。

1.1(2009-07-09)
===


-使wadlib能够识别和生成
多部分/表单数据表示,包括包含二进制参数的表示。





1。0(2009-03-23)
=====


-PYPI的初始版本

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

推荐PyPI第三方库


热门话题
java创建猜谜游戏程序   JavaWebSocketContainer。connectToServer似乎挂起了   如何在java中中断函数   java c#socket client multiple BeginSend()未到达服务器   不可见的组件然后在Java中的窗格之间切换   java在应用程序类中使用静态接口安全吗?   java等待函数完成,直到回调到来   使用DataOutputStream时的java新行,Android   java服务对象的定义是什么?   基于视图的javahibernate复合密钥   java将varchar连接到char在JPA(oracle)中不起作用   如何在java中通过point类读取多个点?