diff --git a/attractsdk/api.py b/attractsdk/api.py index 249f5f9..362765e 100644 --- a/attractsdk/api.py +++ b/attractsdk/api.py @@ -47,7 +47,7 @@ class Api(object): endpoint=kwargs["endpoint"] if kwargs.get("endpoint") else None, username=kwargs["username"] if kwargs.get("username") else None, password=kwargs["password"] if kwargs.get("password") else None, - token = kwargs["token"] if kwargs.get("token") else None) + token=kwargs["token"] if kwargs.get("token") else None) return Api._api_singleton @@ -96,18 +96,16 @@ class Api(object): if http_headers.get('Attract-Request-Id'): logging.info("Attract-Request-Id: {0}".format(http_headers['Attract-Request-Id'])) - try: # Support for Multipart-Encoded file upload if files and method in ['POST', 'PUT', 'PATCH']: return self.http_call( url, method, - data=body, + data={'properties': {}}, files=files, - headers={ - 'Authorization': "Basic {0}".format(self.basic_auth(token=self.get_token()))}, - ) + headers=http_headers) else: + http_headers['Content-Type'] = "application/json" return self.http_call(url, method, data=json.dumps(body), headers=http_headers) @@ -173,7 +171,7 @@ class Api(object): token = self.get_token() headers = { - "Content-Type": "application/json", + #"Content-Type": "application/json", "Accept": "application/json", "User-Agent": self.user_agent } @@ -202,11 +200,11 @@ class Api(object): return self.request(utils.join_url(self.endpoint, action), 'PUT', body=params or {}, headers=headers or {}) - def patch(self, action, params=None, headers=None): + def patch(self, action, params=None, headers=None, files=None): """Make PATCH request """ return self.request(utils.join_url(self.endpoint, action), 'PATCH', - body=params or {}, headers=headers or {}) + body=params or {}, headers=headers or {}, files=files) def delete(self, action, headers=None): """Make DELETE request diff --git a/attractsdk/nodes.py b/attractsdk/nodes.py index f7b01a7..52a57f1 100755 --- a/attractsdk/nodes.py +++ b/attractsdk/nodes.py @@ -4,13 +4,42 @@ from .resource import Create from .resource import Post from .resource import Update from .resource import Delete +from .resource import Replace + +from . import utils -class Node(List, Find, Create, Post, Update, Delete): +class Node(List, Find, Create, Post, Update, Delete, Replace): """Node class wrapping the REST nodes endpoint """ path = "nodes" + def replace_picture(self, picture_file, api=None): + """Replaces the picture field in the node. + :param picture_file: A file object + """ + api = api or self.api + attributes = self.to_dict() + etag = attributes['_etag'] + attributes.pop('_id') + attributes.pop('_etag') + attributes.pop('_created') + attributes.pop('_updated') + attributes.pop('_links') + if 'parent' in attributes: + attributes.pop('parent') + if 'properties' not in attributes: + attributes['properties'] = {} + url = utils.join_url(self.path, str(self['_id'])) + headers = utils.merge_dict( + self.http_headers(), + {'If-Match': str(etag)}) + files = {'picture': picture_file} + new_attributes = api.patch(url, attributes, headers, files) + self.error = None + self.merge(new_attributes) + return self.success() + class NodeType(List, Find, Create, Post, Delete): """NodeType class wrapping the REST node_types endpoint diff --git a/attractsdk/resource.py b/attractsdk/resource.py index 2bdce63..1f02f8b 100644 --- a/attractsdk/resource.py +++ b/attractsdk/resource.py @@ -200,10 +200,22 @@ class Replace(Resource): >>> node.replace([{'op': 'replace', 'path': '/name', 'value': 'Renamed Shot 2' }]) """ - def replace(self, attributes=None): + def replace(self, attributes=None, files=None, api=None): + api = api or self.api attributes = attributes or self.to_dict() - url = utils.join_url(self.path, str(self['id'])) - new_attributes = self.api.patch(url, attributes, self.http_headers()) + etag = attributes['_etag'] + attributes.pop('_id') + attributes.pop('_etag') + attributes.pop('_created') + attributes.pop('_updated') + attributes.pop('_links') + if 'parent' in attributes: + attributes.pop('parent') + url = utils.join_url(self.path, str(self['_id'])) + headers = utils.merge_dict( + self.http_headers(), + {'If-Match': str(etag)}) + new_attributes = api.patch(url, attributes, headers, files) self.error = None self.merge(new_attributes) return self.success()