def list(self, path): """ Returns node meta data for the specific path. The object returned depends on the type of node pointed to by the path. If the path identifies a branch node, a BranchReport object is returned. For leaf nodes, a LeafReport object is returned. :param path: A valid node path. :return: A :class:`~sal.core.object.BranchReport` or :class:`~sal.core.object.LeafReport` object. :raises InvalidPath: If the supplied path is invalid. :raises NodeNotFound: If the path does not point ot a node. :raises PermissionDenied: If the group does not have permission to access the node. """ # check path is valid and dismantle segments, revision, is_absolute = decompose(path) if not is_absolute: raise ValueError("The supplied path must be an absolute path.") # make request url = _LIST_URL.format(host=self.host, path='/'.join(segments), revision=revision) response = self._make_get_request(url) # de-serialise content content = response.json() return deserialise(content)
def test_decompose(self): # test invalid paths for path in self.invalid_paths: with self.assertRaises(ValueError, msg="Invalid path " + path + " did not raise a ValueError Exception"): pth.decompose(path) # test path decomposition, default (normalised) for path, parts in self.decomposed_paths_normalised: self.assertEqual(parts, pth.decompose(path), "Path " + path + " incorrectly decomposed.") # test path decomposition, normalised for path, parts in self.decomposed_paths_normalised: self.assertEqual(parts, pth.decompose(path, normalise=True), "Path " + path + " incorrectly decomposed.") # test path decomposition, unnormalised for path, parts in self.decomposed_paths_unnormalised: self.assertEqual(parts, pth.decompose(path, normalise=False), "Path " + path + " incorrectly decomposed.")
def copy(self, target, source): """ Copy the node specified by the source path to the target path location. Copy will not create any missing intermediate nodes to the target path, these must be created manually before the copy operation is performed. These cannot be created automatically as the branch metadata, such as the description, cannot be automatically populated. :param target: A target node path. :param source: A source node path. :raises InvalidPath: If the supplied path is invalid. :raises NodeNotFound: If the path does not point ot a node. :raises PermissionDenied: If the group does not have permission to access the node. """ # check source path is valid and dismantle source_segments, source_revision, is_absolute = decompose(source) if not is_absolute: raise ValueError( "The supplied source path must be an absolute path.") # check target path is valid and dismantle target_segments, target_revision, is_absolute = decompose(target) if not is_absolute: raise ValueError( "The supplied target path must be an absolute path.") if target_revision > 0: raise ValueError( "Put operations may only be performed on the head revision.") # make request url = _COPY_URL.format(host=self.host, path='/'.join(target_segments), source_path='/' + '/'.join(target_segments), source_revision=source_revision) self._make_post_request(url)
def put(self, path, content): """ Creates/updates node data at the specific path. Put may be used to create or update branch and leaf nodes. Overwriting an existing node with new content will update the existing node. In the case of a branch node this will update the branch metadata without affecting the descendant nodes. Writing a new data object to a leaf node will replace the existing data object. To create a branch node, a Branch object must be supplied as the put content. To create a leaf node, a suitable DataObject subclass must be provided. A leaf node will be created to encapsulate the DataObject. Put will not create any missing intermediate nodes to the target path, these must be created manually before the put operation is performed. These cannot be created automatically as the branch metadata, such as the description, can not be automatically populated. :param path: A valid node path. :param content: A :class:`~sal.core.object.Branch` or :class:`~sal.core.object.DataObject` instance. :raises InvalidPath: If the supplied path is invalid. :raises NodeNotFound: If the path does not point ot a node. :raises PermissionDenied: If the group does not have permission to access the node. """ # check path is valid and dismantle segments, revision, is_absolute = decompose(path) if not is_absolute: raise ValueError("The supplied path must be an absolute path.") if revision > 0: raise ValueError( "Put operations may only be performed on the head revision.") # check content - fail early if not isinstance(content, (Branch, DataObject)): raise TypeError( "The put content must be a DataClass or Branch instance.") # TODO: check write permissions before sending content (fail early) # make request url = _PUT_URL.format(host=self.host, path='/'.join(segments)) payload = serialise(content) self._make_post_request(url, payload=payload)
def get(self, path, summary=False): """ Returns node data for the specific path. The object returned depends on the type of node pointed to by the path. If the path identifies a branch node, a Branch object is returned. Leaf nodes return the data object stored on that node. For leaf nodes, users can request the full data object or a reduced summary object (containing only the object meta data). If the summary argument is set to false (the default) the full data object is returned, if true a data summary is returned. The summary argument has no effect for branch nodes. :param path: A valid node path. :param summary: Return a summary object (default: False). :return: A :class:`~sal.core.object.Branch`, :class:`~sal.core.object.DataObject` or :class:`~sal.core.object.DataSummary` object. :raises InvalidPath: If the supplied path is invalid. :raises NodeNotFound: If the path does not point ot a node. :raises PermissionDenied: If the group does not have permission to access the node. """ # check path is valid and dismantle segments, revision, is_absolute = decompose(path) if not is_absolute: raise ValueError("The supplied path must be an absolute path.") # make request obj_type = 'summary' if summary else 'full' url = _GET_URL.format(host=self.host, path='/'.join(segments), object=obj_type, revision=revision) response = self._make_get_request(url) # de-serialise content content = response.json() return deserialise(content)
def delete(self, path): """ Delete the node specified by the path. If a branch node is deleted, all its descendants are also deleted. :param path: A valid node path. :raises InvalidPath: If the supplied path is invalid. :raises NodeNotFound: If the path does not point ot a node. :raises PermissionDenied: If the group does not have permission to access the node. """ # check path is valid and dismantle segments, revision, is_absolute = decompose(path) if not is_absolute: raise ValueError("The supplied path must be an absolute path.") if revision > 0: raise ValueError( "Put operations may only be performed on the head revision.") # make request url = _DELETE_URL.format(host=self.host, path='/'.join(segments)) self._make_delete_request(url)