一个简短的hal客户
HALEas的Python项目详细描述
黑利
一个非常简单和简短的HAL客户端,其设计目标如下:
- 对链接列表的统一访问,而不管是否存在一种或多种链接。您始终可以遍历rel的单个实例。
- 通过任何属性(而不仅仅是关系类型)对链接的统一访问。
- 对嵌入和链接资源的统一访问。嵌入的资源通过.links()方法访问,就像链接的资源一样,但是有一个值为true的.is_preview属性。如果您试图访问嵌入资源的不存在属性,则HARLAST将获取完整的表示,并尝试满足该请求。如果愿意,可以使用完整资源的.preview属性检查完整资源表示与嵌入资源表示之间的不一致。
- 完全访问Python请求库的底层功能
从PYPI安装
pip install haleasy
从Github安装
git clone https://github.com/mattclarkdotnet/haleasy.git python setup.py install
基本用法
通过获取url创建haleasy资源:
>>> from haleasy import HALEasy >>> h = HALEasy('http://haltalk.herokuapp.com/')
获取资源属性的字典:
>>> h.properties() {u'hint_1': u'You need an account to post stuff..', u'hint_2': u'Create one by POSTing via the ht:signup link..', u'hint_3': u'Click the orange buttons on the right to make POST requests..', u'hint_4': u'Click the green button to follow a link with a GET request..', u'hint_5': u'Click the book icon to read docs for the link relation.', u'welcome': u'Welcome to a haltalk server.'}
获取资源链接的列表:
>>> h.links() [{u'href': u'/users', 'rel': u'http://haltalk.herokuapp.com/rels/users'}, {u'href': u'/', 'rel': u'self'}, {u'href': u'/users/{name}', 'rel': u'http://haltalk.herokuapp.com/rels/me', u'templated': True}, {u'href': u'/posts/latest', 'rel': u'http://haltalk.herokuapp.com/rels/latest-posts'}, {u'href': u'/signup', 'rel': u'http://haltalk.herokuapp.com/rels/signup'}]
获取这些链接的关系列表:
>>> h.rels() [u'http://haltalk.herokuapp.com/rels/users', u'self', u'http://haltalk.herokuapp.com/rels/me', u'http://haltalk.herokuapp.com/rels/latest-posts', u'http://haltalk.herokuapp.com/rels/signup']
列出具有给定rel::
的所有链接>>> h.links(rel='http://haltalk.herokuapp.com/rels/signup') [{u'href': u'/signup', 'rel': u'http://haltalk.herokuapp.com/rels/signup'}]
查找具有给定rel::
的第一个链接>>> h.link(rel='http://haltalk.herokuapp.com/rels/signup') {u'href': u'/signup', 'rel': u'http://haltalk.herokuapp.com/rels/signup'}
您可以通过属性的任意组合来查找链接:
>>> h.links(rel='http://haltalk.herokuapp.com/rels/me', templated=True) [{u'href': u'/users/{name}', 'rel': u'http://haltalk.herokuapp.com/rels/me', u'templated': True}]
通过调用链接的.follow()方法来跟踪链接:
>>> u = h.link(rel='http://haltalk.herokuapp.com/rels/users').follow() >>> u.links(title='Fred Wilson') [{u'href': u'/users/fred', 'rel': u'http://haltalk.herokuapp.com/rels/user', u'title': u'Fred Wilson'}, {u'href': u'/users/ryan', 'rel': u'http://haltalk.herokuapp.com/rels/user', u'title': u'Fred Wilson'}, {u'href': u'/users/joe', 'rel': u'http://haltalk.herokuapp.com/rels/user', u'title': u'Fred Wilson'}, ...
非GET请求
为.follow()方法提供方法和数据参数以执行非GET请求:
>>> s = h.link(rel='http://haltalk.herokuapp.com/rels/signup').follow(method='POST', data={'username': '7654321', 'password': '1234567'}) >>> s.properties() {u'username': u'7654321', u'bio': None, u'real_name': None} >>> s.url 'http://haltalk.herokuapp.com/users/7654321' >>> s.path '/users/7654321' >>> s.host 'http://haltalk.herokuapp.com'
从JSON字符串而不是url加载
您可以直接提供json字符串,但还需要提供url:
>>> haldoc = json.dumps({ "_links": { "self": { "href": "/api_root" }, "sample_hal_rel1": { "href": "/thing1" }, }, "p1": "v1" } >>> h = HALEasy('http://dummy.local/', json_str=haldoc)
模板链接uri
通过向.follow()方法提供其他参数来填充URI模板:
>>> u2 = h.link(rel='ht:me').follow(name='fred')
嵌入式资源
嵌入资源的访问方式与普通资源相同,但它们的.is_preview属性设置为true:
>>> haldoc = json.dumps({ "_links": { "self": { "href": "/api_root" }, "sample_hal_rel1": { "href": "/thing1" }, }, "p1": "v1" "_embedded": { "sample_hal_rel1": { "a": "b", "_links": { "self": { "href": "/thing1", } }, } >>> h = HALEasy('http://dummy.local/', json_str=haldoc) >>> e = h.link(rel="sample_hal_rel1") >>> e.is_preview True
如果访问未定义的嵌入式资源的属性,haleasy将获取实际资源并尝试从中为您提供值:
>>> e.is_preview True >>> e['a'] 'b' >>> e['c'] # HalEasy wil fetch /thing1. Assuming 'c' is a property of the full resource with value 'd' we will get: 'd' >>> e.is_preview # e is no longer a preview resource, as we fetched it from the server False
如果某个属性在嵌入资源和实际资源之间具有不同的值,则实际资源值将覆盖嵌入资源值
匿名嵌入资源
如果嵌入的资源有一个没有ref的自链接,那么您仍然可以通过自链接的其他属性(例如name)找到它。如果嵌入的资源根本没有自链接,那么它将被赋予一个逻辑链接,其属性仅为{'href':''},这样它仍然可以通过其父文档的.lonks()方法访问这种模式对于诸如暂时的表单提交错误之类的事情是有用的,因为没有可链接到的持久资源。
身份验证和http会话
HALEasy使用请求,因此可以将任何参数传递给HALEasy构造函数或.follow()方法,它们将传递给requests.Session.request():
>>> h = HALEasy('http://some.authenticated.server/api', auth=('uuu', 'ppp')) >>> from requests.auth import HTTPDigestAuth >>> h = HALEasy('http://some.authenticated.server/api', auth=HTTPDigestAuth('uuu', 'ppp'))
您还可以在自己的会话对象中创建和pas::
>>> from requests import Session >>> mysession = Session() >>> mysession.auth = ('u', 'p') >>> h = HALEasy('http://some.authenticated.server/api', session=mysession)
如果您没有传入会话,那么HALEasy将创建并使用一个会话来确定管理单个请求所需的任何重定向
当重复请求时,您需要继续传入自己的会话对象,因为HALEasy不知道您的真实意图,因此不会为您管理会话:
>>> mysession = Session() >>> mysession.auth = ('u', 'p') >>> h = HALEasy('http://some.authenticated.server/api', session=mysession) >>> h2 = h.link(rel='somerel').follow(session=mysession)
改变违约行为
传递给haleasy构造函数的任何附加关键字参数都会自动传递给t他通过http客户端请求.session.send()方法。为HTTP方法(GET)和Accept和Content类型头(application/json)提供默认值然而,根据最小意外的设计原则,提供的其他关键字arg不会跨HALEasy实例传播如果您希望它们传播,您应该将halhttpclient子类化
>>> from haleasy import HALEasy, HALHttpClient >>> class MyHttpClient(HALHttpClient): ... DEFAULT_METHOD = 'POST' >>> class MyHALEasy(HALEasy): ... HTTP_CLIENT_CLASS = MyHttpClient >>> h = MyHALEasy('http://haltalk.herokuapp.com/')