def copy_object(self, ref, target_ws_id, target_ws_name, target_name, src_info): """ Copies an object from one workspace to another. """ if not target_ws_id and not target_ws_name: raise ValueError("Neither target workspace id nor name is defined") if not src_info: src_info_tuple = self.ws.get_object_info_new({ 'objects': [{ 'ref': ref }], 'includeMetadata': 0 })[0] src_info = ServiceUtils.object_info_to_object(src_info_tuple) if not target_name: target_name = src_info['name'] obj_info_tuple = self.ws.copy_object({ 'from': { 'ref': ref }, 'to': { 'wsid': target_ws_id, 'workspace': target_ws_name, 'name': target_name } }) obj_info = ServiceUtils.object_info_to_object(obj_info_tuple) return {'info': obj_info}
def copy_object(self, ref, target_ws_id, target_ws_name, target_name, src_info): # There should be some logic related to DataPalettes if (not target_ws_id) and (not target_ws_name): raise ValueError("Neither target workspace ID nor name is defined") if not src_info: src_info_tuple = self.ws.get_object_info_new({'objects': [{'ref': ref}], 'includeMetadata': 0})[0] src_info = ServiceUtils.objectInfoToObject(src_info_tuple) type_name = src_info['typeModule'] + '.' + src_info['typeName'] type_config = self.DATA_PALETTES_TYPES.get(type_name) if type_config is not None: # Copy with DataPaletteService if target_name: raise ValueError("'target_name' cannot be defined for DataPalette copy") target_ws_name_or_id = self._get_workspace_name_or_id(target_ws_id, target_ws_name) self.dps_cache.call_method("add_to_palette", [{'workspace': target_ws_name_or_id, 'new_refs': [{'ref': ref}]}], self.token) return {'info': src_info} else: if not target_name: target_name = src_info['name'] obj_info_tuple = self.ws.copy_object({'from': {'ref': ref}, 'to': {'wsid': target_ws_id, 'workspace': target_ws_name, 'name': target_name}}) obj_info = ServiceUtils.objectInfoToObject(obj_info_tuple) return {'info': obj_info}
def _create_temp_narrative(self, cells, parameters, importData, includeIntroCell, title): # Migration to python of JavaScript class from https://github.com/kbase/kbase-ui/blob/4d31151d13de0278765a69b2b09f3bcf0e832409/src/client/modules/plugins/narrativemanager/modules/narrativeManager.js#L414 narr_id = int(round(time.time() * 1000)) workspaceName = self.user_id + ':narrative_' + str(narr_id) narrativeName = "Narrative." + str(narr_id) ws = self.ws ws_info = ws.create_workspace({'workspace': workspaceName, 'description': ''}) [narrativeObject, metadataExternal] = self._fetchNarrativeObjects( workspaceName, cells, parameters, includeIntroCell, title ) is_temporary = 'true' if title is not None and title != 'Untitled': is_temporary = 'false' metadataExternal['is_temporary'] = is_temporary objectInfo = ws.save_objects({'workspace': workspaceName, 'objects': [{'type': 'KBaseNarrative.Narrative', 'data': narrativeObject, 'name': narrativeName, 'meta': metadataExternal, 'provenance': [{'script': 'NarrativeManager.py', 'description': 'Created new ' + 'Workspace/Narrative bundle.'}], 'hidden': 0}]})[0] objectInfo = ServiceUtils.objectInfoToObject(objectInfo) ws_info = self._completeNewNarrative(ws_info[0], objectInfo['id'], importData, is_temporary, title, len(narrativeObject['cells'])) return { 'workspaceInfo': ServiceUtils.workspaceInfoToObject(ws_info), 'narrativeInfo': objectInfo }
def _completeNewNarrative(self, workspaceId, objectId, importData, is_temporary, title, num_cells): """ 'Completes' the new narrative by updating workspace metadata with the required fields and copying in data from the importData list of references. """ new_meta = { 'narrative': str(objectId), 'is_temporary': is_temporary, 'searchtags': 'narrative', 'cell_count': str(num_cells) } if is_temporary == 'false' and title is not None: new_meta['narrative_nice_name'] = title self.ws.alter_workspace_metadata({ 'wsi': { 'id': workspaceId }, 'new': new_meta }) # copy_to_narrative: if importData: objectsToCopy = [{'ref': x} for x in importData] infoList = self.ws.get_object_info_new({ 'objects': objectsToCopy, 'includeMetadata': 0 }) for item in infoList: objectInfo = ServiceUtils.object_info_to_object(item) self.copy_object(objectInfo['ref'], workspaceId, None, None, objectInfo) return self.ws.get_workspace_info({'id': workspaceId})
def find_report_from_object(self, upa): #TODO: # 1. make sure upa's real. # first, fetch object references (without data) ref_list = self.ws_client.list_referencing_objects([{"ref": upa}])[0] # scan it for a report. # if we find at least one, return them # if we find 0, test if it's a copy, and search upstream. if len(ref_list): report_upas = list() for ref_info in ref_list: if "KBaseReport.Report" in ref_info[2]: report_upas.append( ServiceUtils.objectInfoToObject(ref_info)['ref']) if len(report_upas): return self.build_output(upa, report_upas) else: return self.find_report_from_copy_source(upa) else: return self.find_report_from_copy_source(upa)
def _completeNewNarrative(self, workspaceId, objectId, importData): self.ws.alter_workspace_metadata({ 'wsi': { 'id': workspaceId }, 'new': { 'narrative': str(objectId), 'is_temporary': 'true' } }) # copy_to_narrative: if not importData: return objectsToCopy = [{'ref': x} for x in importData] infoList = self.ws.get_object_info_new({ 'objects': objectsToCopy, 'includeMetadata': 0 }) for item in infoList: objectInfo = ServiceUtils.objectInfoToObject(item) self.copy_object(objectInfo['ref'], workspaceId, None, None, objectInfo)
def rename_narrative(self, narrative_ref: str, new_name: str, service_version: str) -> str: """ Renames a Narrative. If the current user (as set by the auth token in self.ws) has admin permission on the workspace, then this does the following steps. 1. Fetch the Narrative object and save it with the name change in the metadata. 2. Update the workspace metadata so that it has the new name as the narrative nice name. 3. Flips the workspace metadata so the the narrative is no longer temporary, if it was. :param narrative_ref: string, format = "###/###" or "###/###/###" (though the latter is very not recommended) :param new_name: string, new name for the narrative :param service_version: NarrativeService version so the provenance can be tracked properly. """ # 1. Validate inputs. if not new_name or not isinstance(new_name, str): raise ValueError("new_name should be a non-empty string") if len(new_name.encode("utf-8")) > MAX_WS_METADATA_VALUE_SIZE: raise ValueError( f"new_name must be less than {MAX_WS_METADATA_VALUE_SIZE} bytes" ) if not narrative_ref or not isinstance(narrative_ref, str): raise ValueError( "narrative_ref must be a string of format ###/###") ref = ServiceUtils.numerical_ref_to_dict(narrative_ref) ws_id = ref.get("ws_id") if not ws_id or not ref["obj_id"]: raise ValueError( "narrative_ref must be a string of format ###/###") # 2. Check permissions perm = ServiceUtils.get_user_workspace_permissions( self.user_id, ws_id, self.ws) if perm != "a": raise ValueError( f"User {self.user_id} must have admin rights to change the name of the narrative in workspace {ws_id}" ) # 3. Get narrative object narr_obj = self.ws.get_objects2({"objects": [{ "ref": narrative_ref }]})["data"][0] # 3a. Rename the right fields there. if narr_obj["data"]["metadata"]["name"] == new_name: # no-op, return the current UPA. return f"{narr_obj['info'][6]}/{narr_obj['info'][1]}/{narr_obj['info'][4]}" narr_obj["data"]["metadata"]["name"] = new_name narr_obj["info"][10]["name"] = new_name # 4. Update workspace metadata updated_metadata = { "is_temporary": "false", "narrative_nice_name": new_name, "searchtags": "narrative" } self.ws.alter_workspace_metadata({ "wsi": { "id": ws_id }, "new": updated_metadata }) # 5. Save the Narrative object. Keep all the things intact, with new provenance saying we renamed with the NarrativeService. ws_save_obj = { "type": NARRATIVE_TYPE, "data": narr_obj["data"], "objid": ref["obj_id"], "meta": narr_obj["info"][10], "provenance": [{ "service": "NarrativeService", "description": "Renamed by Narrative Service", "service_ver": service_version }] } obj_info = self.ws.save_objects({ "id": ws_id, "objects": [ws_save_obj] })[0] return f"{obj_info[6]}/{obj_info[0]}/{obj_info[4]}"