From ad4676bc38f1422a8a3e9e5b09a136de23a5c6ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florent=20Cayr=C3=A9?= Date: Fri, 26 Jan 2018 14:44:18 +0100 Subject: [PATCH 1/2] Generate unique keys when parsing document links (API change) - do no more use URL path as a key, but the complete URL - expand curies to the full URL to avoid collisions too Note that this changes the API, as the keys to retrieve the links of a document have changed. --- hal_codec/__init__.py | 33 +++++++++++++++++++-------------- tests/test_codec.py | 14 +++++++------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/hal_codec/__init__.py b/hal_codec/__init__.py index 0b27c2a..20d8da4 100644 --- a/hal_codec/__init__.py +++ b/hal_codec/__init__.py @@ -127,19 +127,16 @@ def _parse_link(data, base_url=None): return Link(url=url, fields=fields) -def _map_to_coreapi_key(key): - # HAL uses 'rel' values to index links and nested resources. - if key.startswith('http://') or key.startswith('https://'): - # Fully qualified URL - just use last portion of the path. - return urlparse.urlsplit(key).path.split('/')[-1] - elif ':' in key: - # A curried 'rel' value. Use the named portion. - return key.split(':', 1)[1] - # A reserved 'rel' value, such as "next". +def _map_to_coreapi_key(key, curies): + if ':' in key: + prefix, suffix = key.split(':', 1) + curie = curies.get(prefix) + if curie is not None and curie['templated'] is True: + key = uritemplate.expand(curie['href'], rel=suffix) return key -def _parse_document(data, base_url=None): +def _parse_document(data, base_url=None, curies=None): links = _get_dict(data, '_links') embedded = _get_dict(data, '_embedded') @@ -149,12 +146,19 @@ def _parse_document(data, base_url=None): title = _get_string(self, 'title') content = {} + if curies is None: + curies = {} + + if 'curies' in links: + for curie in links['curies']: + curies[curie['name']] = curie for key, value in links.items(): + if key in ('self', 'curies'): continue - key = _map_to_coreapi_key(key) + key = _map_to_coreapi_key(key, curies) if isinstance(value, list): if value and 'name' in value[0]: @@ -176,11 +180,12 @@ def _parse_document(data, base_url=None): # Embedded resources. for key, value in embedded.items(): - key = _map_to_coreapi_key(key) + key = _map_to_coreapi_key(key, curies) if isinstance(value, list): - content[key] = [_parse_document(item, base_url=url) for item in value] + content[key] = [_parse_document(item, base_url=url, curies=curies) + for item in value] elif isinstance(value, dict): - content[key] = _parse_document(value, base_url=url) + content[key] = _parse_document(value, base_url=url, curies=curies) # Data. for key, value in data.items(): diff --git a/tests/test_codec.py b/tests/test_codec.py index 7bc94ff..a138f46 100644 --- a/tests/test_codec.py +++ b/tests/test_codec.py @@ -49,12 +49,12 @@ url=u'/orders', title='', content={ - u'admin': [ + u'http://example.com/docs/rels/admin': [ Link(url=u'/admins/2'), Link(url=u'/admins/5') ], u'currentlyProcessing': 14, - u'order': [ + u'http://example.com/docs/rels/order': [ Document( url=u'/orders/123', title='', @@ -62,8 +62,8 @@ u'currency': u'USD', u'status': u'shipped', u'total': 30.0, - u'basket': Link(url=u'/baskets/98712'), - u'customer': Link(url=u'/customers/7809') + u'http://example.com/docs/rels/basket': Link(url=u'/baskets/98712'), + u'http://example.com/docs/rels/customer': Link(url=u'/customers/7809') } ), Document( @@ -73,13 +73,13 @@ u'currency': u'USD', u'status': u'processing', u'total': 20.0, - u'basket': Link(url=u'/baskets/97213'), - u'customer': Link(url=u'/customers/12369') + u'http://example.com/docs/rels/basket': Link(url=u'/baskets/97213'), + u'http://example.com/docs/rels/customer': Link(url=u'/customers/12369') } ) ], u'shippedToday': 20, - u'find': Link(url=u'/orders{?id}', fields=[Field(u'id', location='path')]), + u'http://example.com/docs/rels/find': Link(url=u'/orders{?id}', fields=[Field(u'id', location='path')]), u'next': Link(url=u'/orders?page=2') } ) From 7e9e54c46179511aa8e1613a6d4edd8817ac255c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florent=20Cayr=C3=A9?= Date: Fri, 26 Jan 2018 14:56:51 +0100 Subject: [PATCH 2/2] Bump version to 1.1.0 --- hal_codec/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hal_codec/__init__.py b/hal_codec/__init__.py index 20d8da4..f60d672 100644 --- a/hal_codec/__init__.py +++ b/hal_codec/__init__.py @@ -8,7 +8,7 @@ import uritemplate -__version__ = "1.0.2" +__version__ = "1.1.0" def _get_string(item, key):