From d0edc478c3f450209616f23af6154ed7b9f9f4e5 Mon Sep 17 00:00:00 2001 From: Lucas Maciel Vieira <35172605+lmacielvieira@users.noreply.github.com> Date: Wed, 13 Sep 2023 10:49:02 +0200 Subject: [PATCH] Added copy optical image to python client (#1416) * [PythonClient] added copy optical image function * [PyClient] added get transform and get opt image src path * [OpticalImage] added copy src img function --- metaspace/graphql/schemas/dataset.graphql | 2 + .../modules/dataset/controller/Mutation.ts | 20 +++++ .../system/addApiKeyInterceptorToSchema.ts | 1 + metaspace/python-client/metaspace/__init__.py | 2 +- .../metaspace/sm_annotation_utils.py | 77 +++++++++++++++++++ 5 files changed, 101 insertions(+), 1 deletion(-) diff --git a/metaspace/graphql/schemas/dataset.graphql b/metaspace/graphql/schemas/dataset.graphql index df2e5b2f5..357fe08df 100644 --- a/metaspace/graphql/schemas/dataset.graphql +++ b/metaspace/graphql/schemas/dataset.graphql @@ -434,6 +434,8 @@ type Mutation { addOpticalImage(input: AddOpticalImageInput!): String! + copyRawOpticalImage(originDatasetId: String!, destinyDatasetId: String!): String! + addRoi(datasetId: String!, geoJson: GeoJson!): String deleteOpticalImage(datasetId: String!): String! diff --git a/metaspace/graphql/src/modules/dataset/controller/Mutation.ts b/metaspace/graphql/src/modules/dataset/controller/Mutation.ts index 3e0136039..77febdeb5 100644 --- a/metaspace/graphql/src/modules/dataset/controller/Mutation.ts +++ b/metaspace/graphql/src/modules/dataset/controller/Mutation.ts @@ -28,6 +28,8 @@ import { smApiUpdateDataset } from '../../../utils/smApi/datasets' import { validateTiptapJson } from '../../../utils/tiptap' import { isMemberOfGroup } from '../operation/isMemberOfGroup' import { DatasetEnrichment as DatasetEnrichmentModel } from '../../enrichmentdb/model' +import { getS3Client } from '../../../utils/awsClient' +import config from '../../../utils/config' type MetadataSchema = any; type MetadataRoot = any; @@ -479,6 +481,24 @@ const MutationResolvers: FieldResolversFor = { return JSON.stringify(resp) }, + copyRawOpticalImage: async(source, { originDatasetId, destinyDatasetId }, ctx: Context) => { + await esDatasetByID(originDatasetId, ctx.user) // check if user has access to origin dataset + await esDatasetByID(destinyDatasetId, ctx.user) // check if user has access to destiny dataset + + const engineDataset = await ctx.entityManager.getRepository(EngineDataset).findOne(originDatasetId) + + if (engineDataset && engineDataset.opticalImage) { + const s3 = getS3Client() + await s3.copyObject({ + Bucket: `${config.upload.bucket}/raw_optical/${destinyDatasetId}`, + CopySource: `${config.upload.bucket}/raw_optical/${originDatasetId}/${engineDataset.opticalImage}`, + Key: engineDataset.opticalImage, + }).promise() + + return engineDataset.opticalImage + } + }, + addRoi: async(source, { datasetId, geoJson }, ctx: Context) => { const typedJson : any = geoJson diff --git a/metaspace/graphql/src/modules/system/addApiKeyInterceptorToSchema.ts b/metaspace/graphql/src/modules/system/addApiKeyInterceptorToSchema.ts index dc0f622d6..e1993293f 100644 --- a/metaspace/graphql/src/modules/system/addApiKeyInterceptorToSchema.ts +++ b/metaspace/graphql/src/modules/system/addApiKeyInterceptorToSchema.ts @@ -10,6 +10,7 @@ const ALLOWED_MUTATIONS = new Set([ 'deleteDataset', 'reprocessDataset', 'addOpticalImage', + 'copyRawOpticalImage', 'addRoi', 'deleteOpticalImage', 'createProject', diff --git a/metaspace/python-client/metaspace/__init__.py b/metaspace/python-client/metaspace/__init__.py index d400aa305..98f30bbc4 100644 --- a/metaspace/python-client/metaspace/__init__.py +++ b/metaspace/python-client/metaspace/__init__.py @@ -1,4 +1,4 @@ -__version__ = '2.0.4' +__version__ = '2.0.5' from metaspace.sm_annotation_utils import ( SMInstance, diff --git a/metaspace/python-client/metaspace/sm_annotation_utils.py b/metaspace/python-client/metaspace/sm_annotation_utils.py index 563c215ba..283e08c49 100644 --- a/metaspace/python-client/metaspace/sm_annotation_utils.py +++ b/metaspace/python-client/metaspace/sm_annotation_utils.py @@ -2032,6 +2032,83 @@ def add_dataset_external_link( ) return result['addDatasetExternalLink']['externalLinks'] + def get_optical_image_transform(self, dataset_id: str): + """ + Get optical image transform matrix + + matrix3d(${t[0][0]}, ${t[1][0]}, 0, ${t[2][0]}, + ${t[0][1]}, ${t[1][1]}, 0, ${t[2][1]}, + 0, 0, 1, 0, + ${t[0][2]}, ${t[1][2]}, 0, ${t[2][2]}) + + >>> sm.get_optical_image_transform( + >>> dataset_id='2018-11-07_14h15m28s', + >>> ) + + :param dataset_id: + :return: Returns matrix 3d values + """ + return self._gqclient.getRawOpticalImage(dataset_id)['rawOpticalImage']['transform'] + + def get_optical_image_path(self, dataset_id: str): + """ + Get optical image file path + + >>> sm.get_optical_image_path( + >>> dataset_id='2018-11-07_14h15m28s', + >>> ) + + :param dataset_id: + :return: Returns src path + """ + return self._gqclient.getRawOpticalImage(dataset_id)['rawOpticalImage']['url'] + + def copy_optical_image(self, origin_dataset_id: str, destiny_dataset_id: str): + """ + Copies an optical image from a dataset to another + + >>> sm.copy_optical_image( + >>> origin_dataset_id='2018-11-07_14h15m28s', + >>> destiny_dataset_id='2018-11-07_14h15m30s', + >>> ) + + :param origin_dataset_id: + The dataset ID of the origin dataset with the optical image to be copied + :param destiny_dataset_id: + The dataset ID from the dataset to where the optical image will be copied to + :return: The updated list of external links + """ + + copy_file_query = """ + mutation copyRawOpticalImage($originDatasetId: String!, + $destinyDatasetId: String!) { + copyRawOpticalImage(originDatasetId: $originDatasetId, + destinyDatasetId: $destinyDatasetId) + } + """ + copy_variables = { + 'originDatasetId': origin_dataset_id, + 'destinyDatasetId': destiny_dataset_id, + } + + copied_file = self._gqclient.query(copy_file_query, copy_variables)['copyRawOpticalImage'] + + query = """ + mutation addOpticalImage($imageUrl: String!, + $datasetId: String!, $transform: [[Float]]!) { + addOpticalImage(input: {datasetId: $datasetId, + imageUrl: $imageUrl, transform: $transform}) + } + """ + + variables = { + 'datasetId': destiny_dataset_id, + 'imageUrl': copied_file, + 'transform': self.get_optical_image_transform(origin_dataset_id), + } + + return self._gqclient.query(query, variables)['addOpticalImage'] + def remove_dataset_external_link( self, dataset_id: str, provider: str, link: Optional[str] = None ):