diff --git a/coreapi/client.py b/coreapi/client.py index 00b0057..b005eae 100644 --- a/coreapi/client.py +++ b/coreapi/client.py @@ -1,19 +1,15 @@ from coreapi import codecs, exceptions, transports from coreapi.compat import string_types -from coreapi.document import Document, Link +from coreapi.document import Link from coreapi.utils import determine_transport, get_installed_codecs -import collections import itypes -LinkAncestor = collections.namedtuple('LinkAncestor', ['document', 'keys']) - - def _lookup_link(document, keys): """ Validates that keys looking up a link are correct. - Returns a two-tuple of (link, link_ancestors). + Returns the Link. """ if not isinstance(keys, (list, tuple)): msg = "'keys' must be a list of strings or ints." @@ -28,7 +24,6 @@ def _lookup_link(document, keys): # 'node' is the link we're calling the action for. # 'document_keys' is the list of keys to the link's parent document. node = document - link_ancestors = [LinkAncestor(document=document, keys=[])] for idx, key in enumerate(keys): try: node = node[key] @@ -36,9 +31,6 @@ def _lookup_link(document, keys): index_string = ''.join('[%s]' % repr(key).strip('u') for key in keys) msg = 'Index %s did not reference a link. Key %s was not found.' raise exceptions.LinkLookupError(msg % (index_string, repr(key).strip('u'))) - if isinstance(node, Document): - ancestor = LinkAncestor(document=node, keys=keys[:idx + 1]) - link_ancestors.append(ancestor) # Ensure that we've correctly indexed into a link. if not isinstance(node, Link): @@ -48,7 +40,7 @@ def _lookup_link(document, keys): msg % (index_string, type(node).__name__) ) - return (node, link_ancestors) + return node def _validate_parameters(link, parameters): @@ -140,8 +132,8 @@ def reload(self, document, format=None, force_codec=False): return self.get(document.url, format=format, force_codec=force_codec) def action(self, document, keys, params=None, validate=True, overrides=None, - action=None, encoding=None, transform=None): - if (action is not None) or (encoding is not None) or (transform is not None): + action=None, encoding=None): + if (action is not None) or (encoding is not None): # Fallback for v1.x overrides. # Will be removed at some point, most likely in a 2.1 release. if overrides is None: @@ -150,8 +142,6 @@ def action(self, document, keys, params=None, validate=True, overrides=None, overrides['action'] = action if encoding is not None: overrides['encoding'] = encoding - if transform is not None: - overrides['transform'] = transform if isinstance(keys, string_types): keys = [keys] @@ -160,7 +150,7 @@ def action(self, document, keys, params=None, validate=True, overrides=None, params = {} # Validate the keys and link parameters. - link, link_ancestors = _lookup_link(document, keys) + link = _lookup_link(document, keys) if validate: _validate_parameters(link, params) @@ -169,10 +159,9 @@ def action(self, document, keys, params=None, validate=True, overrides=None, url = overrides.get('url', link.url) action = overrides.get('action', link.action) encoding = overrides.get('encoding', link.encoding) - transform = overrides.get('transform', link.transform) fields = overrides.get('fields', link.fields) - link = Link(url, action=action, encoding=encoding, transform=transform, fields=fields) + link = Link(url, action=action, encoding=encoding, fields=fields) # Perform the action, and return a new document. transport = determine_transport(self.transports, link.url) - return transport.transition(link, self.decoders, params=params, link_ancestors=link_ancestors) + return transport.transition(link, self.decoders, params=params) diff --git a/coreapi/codecs/corejson.py b/coreapi/codecs/corejson.py index f025533..92facc4 100644 --- a/coreapi/codecs/corejson.py +++ b/coreapi/codecs/corejson.py @@ -196,8 +196,6 @@ def _document_to_primitive(node, base_url=None): ret['action'] = node.action if node.encoding: ret['encoding'] = node.encoding - if node.transform: - ret['transform'] = node.transform if node.title: ret['title'] = node.title if node.description: @@ -264,7 +262,6 @@ def _primitive_to_document(data, base_url=None): url = urlparse.urljoin(base_url, url) action = _get_string(data, 'action') encoding = _get_string(data, 'encoding') - transform = _get_string(data, 'transform') title = _get_string(data, 'title') description = _get_string(data, 'description') fields = _get_list(data, 'fields') @@ -278,7 +275,7 @@ def _primitive_to_document(data, base_url=None): for item in fields if isinstance(item, dict) ] return Link( - url=url, action=action, encoding=encoding, transform=transform, + url=url, action=action, encoding=encoding, title=title, description=description, fields=fields ) diff --git a/coreapi/codecs/python.py b/coreapi/codecs/python.py index 6265a28..6feec4e 100644 --- a/coreapi/codecs/python.py +++ b/coreapi/codecs/python.py @@ -42,8 +42,6 @@ def _to_repr(node): args += ", action=%s" % repr(node.action) if node.encoding: args += ", encoding=%s" % repr(node.encoding) - if node.transform: - args += ", transform=%s" % repr(node.transform) if node.description: args += ", description=%s" % repr(node.description) if node.fields: diff --git a/coreapi/document.py b/coreapi/document.py index c6c9ceb..dd498dc 100644 --- a/coreapi/document.py +++ b/coreapi/document.py @@ -187,15 +187,13 @@ class Link(itypes.Object): """ Links represent the actions that a client may perform. """ - def __init__(self, url=None, action=None, encoding=None, transform=None, title=None, description=None, fields=None): + def __init__(self, url=None, action=None, encoding=None, title=None, description=None, fields=None): if (url is not None) and (not isinstance(url, string_types)): raise TypeError("Argument 'url' must be a string.") if (action is not None) and (not isinstance(action, string_types)): raise TypeError("Argument 'action' must be a string.") if (encoding is not None) and (not isinstance(encoding, string_types)): raise TypeError("Argument 'encoding' must be a string.") - if (transform is not None) and (not isinstance(transform, string_types)): - raise TypeError("Argument 'transform' must be a string.") if (title is not None) and (not isinstance(title, string_types)): raise TypeError("Argument 'title' must be a string.") if (description is not None) and (not isinstance(description, string_types)): @@ -211,7 +209,6 @@ def __init__(self, url=None, action=None, encoding=None, transform=None, title=N self._url = '' if (url is None) else url self._action = '' if (action is None) else action self._encoding = '' if (encoding is None) else encoding - self._transform = '' if (transform is None) else transform self._title = '' if (title is None) else title self._description = '' if (description is None) else description self._fields = () if (fields is None) else tuple([ @@ -231,10 +228,6 @@ def action(self): def encoding(self): return self._encoding - @property - def transform(self): - return self._transform - @property def title(self): return self._title @@ -253,7 +246,6 @@ def __eq__(self, other): self.url == other.url and self.action == other.action and self.encoding == other.encoding and - self.transform == other.transform and self.description == other.description and sorted(self.fields, key=lambda f: f.name) == sorted(other.fields, key=lambda f: f.name) ) diff --git a/coreapi/transports/http.py b/coreapi/transports/http.py index 7338e61..5b78fc7 100644 --- a/coreapi/transports/http.py +++ b/coreapi/transports/http.py @@ -305,32 +305,6 @@ def _decode_result(response, decoders, force_codec=False): return result -def _handle_inplace_replacements(document, link, link_ancestors): - """ - Given a new document, and the link/ancestors it was created, - determine if we should: - - * Make an inline replacement and then return the modified document tree. - * Return the new document as-is. - """ - if not link.transform: - if link.action.lower() in ('put', 'patch', 'delete'): - transform = 'inplace' - else: - transform = 'new' - else: - transform = link.transform - - if transform == 'inplace': - root = link_ancestors[0].document - keys_to_link_parent = link_ancestors[-1].keys - if document is None: - return root.delete_in(keys_to_link_parent) - return root.set_in(keys_to_link_parent, document) - - return document - - class HTTPTransport(BaseTransport): schemes = ['http', 'https'] @@ -366,7 +340,7 @@ def __init__(self, credentials=None, headers=None, auth=None, session=None, requ def headers(self): return self._headers - def transition(self, link, decoders, params=None, link_ancestors=None, force_codec=False): + def transition(self, link, decoders, params=None, force_codec=False): session = self._session method = _get_method(link.action) encoding = _get_encoding(link.encoding) @@ -380,9 +354,6 @@ def transition(self, link, decoders, params=None, link_ancestors=None, force_cod response = session.send(request, **settings) result = _decode_result(response, decoders, force_codec) - if isinstance(result, Document) and link_ancestors: - result = _handle_inplace_replacements(result, link, link_ancestors) - if isinstance(result, Error): raise exceptions.ErrorMessage(result) diff --git a/tests/test_codecs.py b/tests/test_codecs.py index 32458cd..2475293 100644 --- a/tests/test_codecs.py +++ b/tests/test_codecs.py @@ -194,7 +194,6 @@ def test_link_encodings(json_codec): doc = Document(content={ 'link': Link( action='post', - transform='inplace', fields=['optional', Field('required', required=True, location='path')] ) }) @@ -204,7 +203,6 @@ def test_link_encodings(json_codec): "link": { "_type": "link", "action": "post", - "transform": "inplace", "fields": [ { "name": "optional" diff --git a/tests/test_document.py b/tests/test_document.py index 6b06de7..c985fa9 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -17,7 +17,6 @@ def doc(): 'link': Link( url='/', action='post', - transform='inplace', fields=['optional', Field('required', required=True, location='path')] ), 'nested': {'child': Link(url='/123')} @@ -224,7 +223,7 @@ def test_document_repr(doc): "'integer': 123, " "'list': [1, 2, 3], " "'nested': {'child': Link(url='/123')}, " - "'link': Link(url='/', action='post', transform='inplace', " + "'link': Link(url='/', action='post', " "fields=['optional', Field('required', required=True, location='path')])" "})" ) @@ -345,7 +344,6 @@ def test_document_equality(doc): 'link': Link( url='/', action='post', - transform='inplace', fields=['optional', Field('required', required=True, location='path')] ), 'nested': {'child': Link(url='/123')} @@ -424,11 +422,6 @@ def test_link_action_must_be_string(): Link(action=123) -def test_link_transform_must_be_string(): - with pytest.raises(TypeError): - Link(transform=123) - - def test_link_fields_must_be_list(): with pytest.raises(TypeError): Link(fields=123) diff --git a/tests/test_transitions.py b/tests/test_transitions.py index a31ba13..28e2ad0 100644 --- a/tests/test_transitions.py +++ b/tests/test_transitions.py @@ -1,24 +1,14 @@ # coding: utf-8 from coreapi import Document, Link, Client from coreapi.transports import HTTPTransport -from coreapi.transports.http import _handle_inplace_replacements import pytest class MockTransport(HTTPTransport): schemes = ['mock'] - def transition(self, link, decoders, params=None, link_ancestors=None): - if link.action == 'get': - document = Document(title='new', content={'new': 123}) - elif link.action in ('put', 'post'): - if params is None: - params = {} - document = Document(title='new', content={'new': 123, 'foo': params.get('foo')}) - else: - document = None - - return _handle_inplace_replacements(document, link, link_ancestors) + def transition(self, link, decoders, params=None): + return {'action': link.action, 'params': params} client = Client(transports=[MockTransport()]) @@ -29,7 +19,6 @@ def doc(): return Document(title='original', content={ 'nested': Document(content={ 'follow': Link(url='mock://example.com', action='get'), - 'action': Link(url='mock://example.com', action='post', transform='inplace', fields=['foo']), 'create': Link(url='mock://example.com', action='post', fields=['foo']), 'update': Link(url='mock://example.com', action='put', fields=['foo']), 'delete': Link(url='mock://example.com', action='delete') @@ -40,44 +29,27 @@ def doc(): # Test valid transitions. def test_get(doc): - new = client.action(doc, ['nested', 'follow']) - assert new == {'new': 123} - assert new.title == 'new' - - -def test_inline_post(doc): - new = client.action(doc, ['nested', 'action'], params={'foo': 123}) - assert new == {'nested': {'new': 123, 'foo': 123}} - assert new.title == 'original' + data = client.action(doc, ['nested', 'follow']) + assert data == {'action': 'get', 'params': {}} def test_post(doc): - new = client.action(doc, ['nested', 'create'], params={'foo': 456}) - assert new == {'new': 123, 'foo': 456} - assert new.title == 'new' + data = client.action(doc, ['nested', 'create'], params={'foo': 456}) + assert data == {'action': 'post', 'params': {'foo': 456}} def test_put(doc): - new = client.action(doc, ['nested', 'update'], params={'foo': 789}) - assert new == {'nested': {'new': 123, 'foo': 789}} - assert new.title == 'original' + data = client.action(doc, ['nested', 'update'], params={'foo': 789}) + assert data == {'action': 'put', 'params': {'foo': 789}} def test_delete(doc): - new = client.action(doc, ['nested', 'delete']) - assert new == {} - assert new.title == 'original' + data = client.action(doc, ['nested', 'delete']) + assert data == {'action': 'delete', 'params': {}} # Test overrides def test_override_action(doc): - new = client.action(doc, ['nested', 'follow'], overrides={'action': 'put'}) - assert new == {'nested': {'new': 123, 'foo': None}} - assert new.title == 'original' - - -def test_override_transform(doc): - new = client.action(doc, ['nested', 'update'], params={'foo': 456}, overrides={'transform': 'new'}) - assert new == {'new': 123, 'foo': 456} - assert new.title == 'new' + data = client.action(doc, ['nested', 'follow'], overrides={'action': 'put'}) + assert data == {'action': 'put', 'params': {}}
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: