diff --git a/app-openbis-command-line/src/python/obis/dm/commands/upload.py b/app-openbis-command-line/src/python/obis/dm/commands/upload.py new file mode 100644 index 0000000000000000000000000000000000000000..d9ee708b584e2d329a364ed97b320948ac29f63c --- /dev/null +++ b/app-openbis-command-line/src/python/obis/dm/commands/upload.py @@ -0,0 +1,46 @@ +# Copyright ETH 2023 Zürich, Scientific IT Services +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from .openbis_command import OpenbisCommand +from ..command_result import CommandResult +from ..utils import cd +from ...scripts.click_util import click_echo + + +class Upload(OpenbisCommand): + """ + Command to upload physical files to form a data set. + """ + + def __init__(self, dm, sample_id, data_set_type, files): + """ + :param dm: data management + :param sample_id: permId or sample path of the parent sample + :param data_set_type: type of newly created data set. + :param files: list of files/directories to upload + """ + self.data_set_type = data_set_type + self.files = files + self.sample_id = sample_id + self.load_global_config(dm) + super(Upload, self).__init__(dm) + + def run(self): + with cd(self.data_mgmt.invocation_path): + click_echo(f"Uploading files {self.files} under {self.sample_id}") + ds = self.openbis.new_dataset(type=self.data_set_type, sample=self.sample_id, + files=self.files) + result = ds.save() + return CommandResult(returncode=0, output=f"Upload finished. New dataset: {result}") diff --git a/app-openbis-command-line/src/python/obis/dm/data_mgmt.py b/app-openbis-command-line/src/python/obis/dm/data_mgmt.py index 93ed3746e1cb39b894cfc25787efd8d253ed868b..326d8bda283081d2c275b36b00711f093e7e64bb 100644 --- a/app-openbis-command-line/src/python/obis/dm/data_mgmt.py +++ b/app-openbis-command-line/src/python/obis/dm/data_mgmt.py @@ -35,6 +35,7 @@ from .commands.move import Move from .commands.openbis_sync import OpenbisSync from .commands.removeref import Removeref from .commands.search import Search +from .commands.upload import Upload from .git import GitWrapper from .utils import Type from .utils import cd @@ -217,6 +218,15 @@ class AbstractDataMgmt(metaclass=abc.ABCMeta): """ return + @abc.abstractmethod + def upload(self, sample_id, data_set_type, files): + """Upload files/directories into a new data set. + :param sample_id: permId or sample path of the parent sample + :param data_set_type: type of created data set + :param files: list of files/directories to upload + """ + return + @abc.abstractmethod def search_object(self, type_code, space, project, experiment, property_code, property_value, save): @@ -231,6 +241,7 @@ class AbstractDataMgmt(metaclass=abc.ABCMeta): """ return + @abc.abstractmethod def search_data_set(self, type_code, space, project, experiment, property_code, property_value, save): """Search for datasets in openBIS using filtering criteria. @@ -290,6 +301,9 @@ class NoGitDataMgmt(AbstractDataMgmt): def search_data_set(self, *_): self.error_raise("search", "No git command found.") + def upload(self, *_): + self.error_raise("upload", "No git command found.") + def restore_signal_handler(data_mgmt): data_mgmt.restore() @@ -575,6 +589,9 @@ class GitDataMgmt(AbstractDataMgmt): def search_data_set(self, *_): self.error_raise("search", "This functionality is not implemented for data of LINK type.") + def upload(self, *_): + self.error_raise("upload", "This functionality is not implemented for data of LINK type.") + class PhysicalDataMgmt(AbstractDataMgmt): """DataMgmt operations for DSS-stored data.""" @@ -624,6 +641,10 @@ class PhysicalDataMgmt(AbstractDataMgmt): cmd = DownloadPhysical(self, data_set_id, file) return cmd.run() + def upload(self, sample_id, data_set_type, files): + cmd = Upload(self, sample_id, data_set_type, files) + return cmd.run() + def search_object(self, type_code, space, project, experiment, property_code, property_value, save): cmd = Search(self, type_code, space, project, experiment, property_code, property_value, diff --git a/app-openbis-command-line/src/python/obis/scripts/cli.py b/app-openbis-command-line/src/python/obis/scripts/cli.py index b081071c8e1c2aa65abb1f92babe0c7151a3ee88..db38e2935f458b0b02e5e847d200362cec58ee80 100644 --- a/app-openbis-command-line/src/python/obis/scripts/cli.py +++ b/app-openbis-command-line/src/python/obis/scripts/cli.py @@ -748,7 +748,7 @@ def removeref(ctx, data_set_id, repository): repository=repository) -# data set commands: download / clone +# data set commands: download, upload, clone # download @@ -763,7 +763,7 @@ _download_params = [ ] -@data_set.command("download", short_help="Download files of a linked data set.") +@data_set.command("download", short_help="Download files of a data set.") @add_params(_download_params) @click.pass_context def data_set_download(ctx, content_copy_index, file, data_set_id, skip_integrity_check): @@ -772,7 +772,7 @@ def data_set_download(ctx, content_copy_index, file, data_set_id, skip_integrity skip_integrity_check)) -@cli.command(short_help="Download files of a linked data set.") +@cli.command("download", short_help="Download files of a data set.") @add_params(_download_params) @click.pass_context def download(ctx, content_copy_index, file, data_set_id, skip_integrity_check): @@ -781,6 +781,33 @@ def download(ctx, content_copy_index, file, data_set_id, skip_integrity_check): data_set_id=data_set_id, skip_integrity_check=skip_integrity_check) +# upload + + +_upload_params = [ + click.option( + '-f', '--file', "files", help='file or directory to upload.', required=True, multiple=True), + click.argument('sample_id'), + click.argument('data_set_type'), +] + + +@data_set.command("upload", short_help="Upload files to form a data set.") +@add_params(_upload_params) +@click.pass_context +def data_set_upload(ctx, sample_id, data_set_type, files): + return ctx.obj['runner'].run("upload", + lambda dm: dm.upload(sample_id, data_set_type, files)) + + +@cli.command("upload", short_help="Upload files to form a data set.") +@add_params(_upload_params) +@click.pass_context +def download(ctx, sample_id, data_set_type, files): + ctx.obj['runner'] = DataMgmtRunner(ctx.obj, halt_on_error_log=False) + ctx.invoke(data_set_upload, files=files, sample_id=sample_id, data_set_type=data_set_type) + + # clone