A library for all things hypermedia. insipred by Halboy and Halboy.js
- Create hypermedia resources
- Marshal to and from plain python dicts
- Navigate JSON+HAL APIs
With PyHalboy you can create resources, and pull information from them.
from pyhalboy import Resource
discountResource = Resource()
.add_link('self', '/discounts/1256')
.add_property('discountPercentage', 10)
itemResources = [
Resource()
.add_link('self', '/items/534')
.add_property('price', 25.48)
]
resource = Resource()
.add_link('self', '/orders/123')
.add_link('creator', '/users/rob')
.add_resource('discount', discountResource)
.add_resource('items', itemResources)
.add_property('state', 'dispatching')
resource.get_link('self')
// { href: '/orders/123' }
resource.get_href('self')
// '/orders/123'
resource.get_property('state')
// 'dispatching'
resource
.get_resource('creator')
.get_property('discountPercentage')
// 10
resource
.get_resource('items')[0]
.get_property('price')
// 25.48
You can create HAL resources from plain JS objects, and vice versa.
from pyhalboy import Resource
itemResources = [
Resource()
.add_link('self', '/items/534')
.add_property('price', 25.48)
]
resource =
new Resource()
.add_link('self', '/orders/123')
.add_link('creator', '/users/rob')
.add_resource('items', itemResources)
.add_property('state', 'dispatching')
resource.to_object()
// {
// _links: {
// self: { href: '/orders/123' },
// creator: { href: '/users/rob' }
// },
// _embedded: {
// items: [{
// _links: {
// self: { href: '/items/534' }
// },
// price: 25.48
// }]
// },
// state: 'dispatching'
// }
Resource.from_object(resource.to_object())
.get_href('self')
// '/orders/123'
Provided you're calling a HAL+JSON API, you can discover the API and navigate
through its links. When you've found what you want, you call
navigator.resource()
and you get a plain old HAL resource, which you can inspect
using any of the methods above.
from pyhalboy import Navigator
// GET / - 200 OK
// {
// "_links": {
// "self": {
// "href": "/"
// },
// "users": {
// "href": "/users"
// },
// "user": {
// "href": "/users/{id}",
// "templated": true
// }
// }
// }
discovery_result = Navigator.discover('https://api.example.com/')
users_result = discovery_result.get('users')
users_result.status()
// 200
users_result.location()
// 'https://api.example.com/users'
robResult = discovery_result.get('user', {id :'rob'})
robResult.location()
// 'https://api.example.com/users/rob'
sue_result = discovery_result.post('user', {
'id': 'sue',
'name': 'Sue',
'title': 'Dev'
})
sue_result.location()
// 'https://api.example.com/users/sue'
sue_result
.resource()
.get_property('title')
// 'Dev'
Feel free to submit PRs and raise bugs.
python setup.py install sdist bdist_wheel
twine upload --repository-url https://test.pypi.org/legacy/ dist/*