cloudos-cli 2.33.0__tar.gz → 2.34.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/PKG-INFO +31 -1
  2. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/README.md +30 -0
  3. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/__main__.py +131 -2
  4. cloudos_cli-2.34.0/cloudos_cli/_version.py +1 -0
  5. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/datasets/datasets.py +45 -1
  6. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli.egg-info/PKG-INFO +31 -1
  7. cloudos_cli-2.33.0/cloudos_cli/_version.py +0 -1
  8. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/LICENSE +0 -0
  9. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/__init__.py +0 -0
  10. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/clos.py +0 -0
  11. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/configure/__init__.py +0 -0
  12. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/configure/configure.py +0 -0
  13. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/datasets/__init__.py +0 -0
  14. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/import_wf/__init__.py +0 -0
  15. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/import_wf/import_wf.py +0 -0
  16. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/jobs/__init__.py +0 -0
  17. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/jobs/job.py +0 -0
  18. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/queue/__init__.py +0 -0
  19. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/queue/queue.py +0 -0
  20. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/utils/__init__.py +0 -0
  21. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/utils/cloud.py +0 -0
  22. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/utils/details.py +0 -0
  23. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/utils/errors.py +0 -0
  24. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/utils/requests.py +0 -0
  25. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli/utils/resources.py +0 -0
  26. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli.egg-info/SOURCES.txt +0 -0
  27. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli.egg-info/dependency_links.txt +0 -0
  28. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli.egg-info/entry_points.txt +0 -0
  29. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli.egg-info/requires.txt +0 -0
  30. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/cloudos_cli.egg-info/top_level.txt +0 -0
  31. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/setup.cfg +0 -0
  32. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/setup.py +0 -0
  33. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/tests/__init__.py +0 -0
  34. {cloudos_cli-2.33.0 → cloudos_cli-2.34.0}/tests/functions_for_pytest.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudos_cli
3
- Version: 2.33.0
3
+ Version: 2.34.0
4
4
  Summary: Python package for interacting with CloudOS
5
5
  Home-page: https://github.com/lifebit-ai/cloudos-cli
6
6
  Author: David Piñeyro
@@ -1014,6 +1014,36 @@ Please, note that in the above example a preconfigured profile has been used. If
1014
1014
  --project-name $PROJEC_NAME
1015
1015
  ```
1016
1016
 
1017
+ #### Copying files and folders
1018
+
1019
+ Files and folders can be copied **from** anywhere in the project **to** `Data` or any of its subfolders programmatically (i.e `Data`, `Data/folder/file.txt`).
1020
+
1021
+ 1. The copy can happen **within the same project** running the following command:
1022
+ ```
1023
+ cloudos datasets cp <souce_path> <destination_path> --profile <profile name>
1024
+ ```
1025
+ where the source project as well as the destination one is the one defined in the profile.
1026
+
1027
+ 2. The move can also happen **across different projects** within the same workspace by running the following command
1028
+ ```
1029
+ cloudos datasets cp <source_path> <destiantion_path> --profile <profile_name> --destination-project-name <project_name>
1030
+ ```
1031
+ In this case, only the source project is the one specified in the profile.
1032
+
1033
+ Any of the `source_path` must be a full path; any `destination_path` must be a path starting with `Data` and finishing with the folder where to move the file/folder. An example of such command is:
1034
+
1035
+ ```
1036
+ cloudos datasets cp AnalysesResults/my_analysis/results/my_plot.png Data/plots
1037
+ ```
1038
+
1039
+ Please, note that in the above example a preconfigured profile has been used. If no profile is provided and there is no default profile, the user will need to also provide the following flags
1040
+ ```bash
1041
+ --cloudos-url $CLOUDOS \
1042
+ --apikey $MY_API_KEY \
1043
+ --workspace-id $WORKSPACE_ID \
1044
+ --project-name $PROJEC_NAME
1045
+ ```
1046
+
1017
1047
  ### WDL pipeline support
1018
1048
 
1019
1049
  #### Cromwell server managing
@@ -979,6 +979,36 @@ Please, note that in the above example a preconfigured profile has been used. If
979
979
  --project-name $PROJEC_NAME
980
980
  ```
981
981
 
982
+ #### Copying files and folders
983
+
984
+ Files and folders can be copied **from** anywhere in the project **to** `Data` or any of its subfolders programmatically (i.e `Data`, `Data/folder/file.txt`).
985
+
986
+ 1. The copy can happen **within the same project** running the following command:
987
+ ```
988
+ cloudos datasets cp <souce_path> <destination_path> --profile <profile name>
989
+ ```
990
+ where the source project as well as the destination one is the one defined in the profile.
991
+
992
+ 2. The move can also happen **across different projects** within the same workspace by running the following command
993
+ ```
994
+ cloudos datasets cp <source_path> <destiantion_path> --profile <profile_name> --destination-project-name <project_name>
995
+ ```
996
+ In this case, only the source project is the one specified in the profile.
997
+
998
+ Any of the `source_path` must be a full path; any `destination_path` must be a path starting with `Data` and finishing with the folder where to move the file/folder. An example of such command is:
999
+
1000
+ ```
1001
+ cloudos datasets cp AnalysesResults/my_analysis/results/my_plot.png Data/plots
1002
+ ```
1003
+
1004
+ Please, note that in the above example a preconfigured profile has been used. If no profile is provided and there is no default profile, the user will need to also provide the following flags
1005
+ ```bash
1006
+ --cloudos-url $CLOUDOS \
1007
+ --apikey $MY_API_KEY \
1008
+ --workspace-id $WORKSPACE_ID \
1009
+ --project-name $PROJEC_NAME
1010
+ ```
1011
+
982
1012
  ### WDL pipeline support
983
1013
 
984
1014
  #### Cromwell server managing
@@ -88,7 +88,8 @@ def run_cloudos_cli(ctx):
88
88
  'datasets': {
89
89
  'ls': shared_config,
90
90
  'mv': shared_config,
91
- 'rename': shared_config
91
+ 'rename': shared_config,
92
+ 'cp': shared_config
92
93
  }
93
94
  })
94
95
  else:
@@ -135,7 +136,8 @@ def run_cloudos_cli(ctx):
135
136
  'datasets': {
136
137
  'ls': shared_config,
137
138
  'mv': shared_config,
138
- 'rename': shared_config
139
+ 'rename': shared_config,
140
+ 'cp': shared_config
139
141
  }
140
142
  })
141
143
 
@@ -2960,5 +2962,132 @@ def renaming_item(ctx, source_path, new_name, apikey, cloudos_url,
2960
2962
  sys.exit(1)
2961
2963
 
2962
2964
 
2965
+ @datasets.command(name="cp")
2966
+ @click.argument("source_path", required=True)
2967
+ @click.argument("destination_path", required=True)
2968
+ @click.option('-k', '--apikey', required=True, help='Your CloudOS API key.')
2969
+ @click.option('-c', '--cloudos-url', default=CLOUDOS_URL, required=True, help='The CloudOS URL.')
2970
+ @click.option('--workspace-id', required=True, help='The CloudOS workspace ID.')
2971
+ @click.option('--project-name', required=True, help='The source project name.')
2972
+ @click.option('--destination-project-name', required=False, help='The destination project name. Defaults to the source project.')
2973
+ @click.option('--disable-ssl-verification', is_flag=True, help='Disable SSL certificate verification.')
2974
+ @click.option('--ssl-cert', help='Path to your SSL certificate file.')
2975
+ @click.option('--profile', default=None, help='Profile to use from the config file.')
2976
+ @click.pass_context
2977
+ def copy_item_cli(ctx, source_path, destination_path, apikey, cloudos_url,
2978
+ workspace_id, project_name, destination_project_name,
2979
+ disable_ssl_verification, ssl_cert, profile):
2980
+ """
2981
+ Copy a file or folder (S3 or virtual) from SOURCE_PATH to DESTINATION_PATH.
2982
+
2983
+ SOURCE_PATH [path]: the full path to the file or folder to copy.
2984
+ E.g.: AnalysesResults/my_analysis/results/my_plot.png\n
2985
+ DESTINATION_PATH [path]: the full path to the destination folder. It must be a 'Data' folder path.
2986
+ E.g.: Data/plots
2987
+ """
2988
+ click.echo("Loading configuration profile...")
2989
+ config_manager = ConfigurationProfile()
2990
+ required_dict = {
2991
+ 'apikey': True,
2992
+ 'workspace_id': True,
2993
+ 'workflow_name': False,
2994
+ 'project_name': True
2995
+ }
2996
+ apikey, cloudos_url, workspace_id, workflow_name, _, _, project_name = config_manager.load_profile_and_validate_data(
2997
+ ctx, INIT_PROFILE, CLOUDOS_URL, profile=profile,
2998
+ required_dict=required_dict,
2999
+ apikey=apikey,
3000
+ cloudos_url=cloudos_url,
3001
+ workspace_id=workspace_id,
3002
+ workflow_name=None,
3003
+ repository_platform=None,
3004
+ execution_platform=None,
3005
+ project_name=project_name
3006
+ )
3007
+ destination_project_name = destination_project_name or project_name
3008
+ verify_ssl = ssl_selector(disable_ssl_verification, ssl_cert)
3009
+ # Initialize clients
3010
+ source_client = Datasets(
3011
+ cloudos_url=cloudos_url,
3012
+ apikey=apikey,
3013
+ workspace_id=workspace_id,
3014
+ project_name=project_name,
3015
+ verify=verify_ssl,
3016
+ cromwell_token=None
3017
+ )
3018
+ dest_client = Datasets(
3019
+ cloudos_url=cloudos_url,
3020
+ apikey=apikey,
3021
+ workspace_id=workspace_id,
3022
+ project_name=destination_project_name,
3023
+ verify=verify_ssl,
3024
+ cromwell_token=None
3025
+ )
3026
+ # Validate paths
3027
+ dest_parts = destination_path.strip("/").split("/")
3028
+ if not dest_parts or dest_parts[0] != "Data":
3029
+ click.echo("[ERROR] DESTINATION_PATH must start with 'Data/'.", err=True)
3030
+ sys.exit(1)
3031
+ # Parse source and destination
3032
+ source_parts = source_path.strip("/").split("/")
3033
+ source_parent = "/".join(source_parts[:-1]) if len(source_parts) > 1 else ""
3034
+ source_name = source_parts[-1]
3035
+ dest_folder_name = dest_parts[-1]
3036
+ dest_parent = "/".join(dest_parts[:-1]) if len(dest_parts) > 1 else ""
3037
+ try:
3038
+ source_content = source_client.list_folder_content(source_parent)
3039
+ dest_content = dest_client.list_folder_content(dest_parent)
3040
+ except Exception as e:
3041
+ click.echo(f"[ERROR] Could not access paths: {str(e)}", err=True)
3042
+ sys.exit(1)
3043
+ # Find the source item
3044
+ source_item = None
3045
+ for item in source_content.get('files' or 'folders', {}):
3046
+ if item.get("name") == source_name:
3047
+ source_item = item
3048
+ break
3049
+ if not source_item:
3050
+ click.echo(f"[ERROR] Item '{source_name}' not found in '{source_parent or '[project root]'}'", err=True)
3051
+ sys.exit(1)
3052
+ # Find the destination folder
3053
+ destination_folder = None
3054
+ for folder in dest_content.get("folders", []):
3055
+ if folder.get("name") == dest_folder_name:
3056
+ destination_folder = folder
3057
+ break
3058
+ if not destination_folder:
3059
+ click.echo(f"[ERROR] Destination folder '{destination_path}' not found.", err=True)
3060
+ sys.exit(1)
3061
+ try:
3062
+ # Determine item type
3063
+ if "fileType" in source_item:
3064
+ item_type = "file"
3065
+ elif source_item.get("folderType") == "VirtualFolder":
3066
+ item_type = "virtual_folder"
3067
+ elif "s3BucketName" in source_item and source_item.get("folderType") == "S3Folder":
3068
+ item_type = "s3_folder"
3069
+ else:
3070
+ click.echo("[ERROR] Could not determine item type.", err=True)
3071
+ sys.exit(1)
3072
+ click.echo(f"Copying {item_type.replace('_', ' ')} '{source_name}' to '{destination_path}'...")
3073
+ if destination_folder.get("folderType") is True and destination_folder.get("kind") in ("Data", "Cohorts", "AnalysesResults"):
3074
+ destination_kind = "Dataset"
3075
+ else:
3076
+ destination_kind = "Folder"
3077
+ response = source_client.copy_item(
3078
+ item=source_item,
3079
+ destination_id=destination_folder["_id"],
3080
+ destination_kind=destination_kind
3081
+ )
3082
+ if response.ok:
3083
+ click.secho("[SUCCESS] Item copied successfully.", fg="green", bold=True)
3084
+ else:
3085
+ click.echo(f"[ERROR] Copy failed: {response.status_code} - {response.text}", err=True)
3086
+ sys.exit(1)
3087
+ except Exception as e:
3088
+ click.echo(f"[ERROR] Copy operation failed: {str(e)}", err=True)
3089
+ sys.exit(1)
3090
+
3091
+
2963
3092
  if __name__ == "__main__":
2964
3093
  run_cloudos_cli()
@@ -0,0 +1 @@
1
+ __version__ = '2.34.0'
@@ -5,7 +5,7 @@ This is the main class for file explorer (datasets).
5
5
  from dataclasses import dataclass
6
6
  from typing import Union
7
7
  from cloudos_cli.clos import Cloudos
8
- from cloudos_cli.utils.requests import retry_requests_get, retry_requests_put
8
+ from cloudos_cli.utils.requests import retry_requests_get, retry_requests_put, retry_requests_post
9
9
  import json
10
10
 
11
11
  @dataclass
@@ -403,4 +403,48 @@ class Datasets(Cloudos):
403
403
  }
404
404
 
405
405
  response = retry_requests_put(url, headers=headers, data=json.dumps(payload), verify=self.verify)
406
+ return response
407
+
408
+ def copy_item(self, item, destination_id, destination_kind):
409
+ """Copy a file or folder (S3 or Virtual) to a destination in CloudOS."""
410
+ headers = {
411
+ "accept": "application/json",
412
+ "content-type": "application/json",
413
+ "ApiKey": self.apikey
414
+ }
415
+ parent = {"kind": destination_kind, "id": destination_id}
416
+
417
+ # Virtual folder
418
+ if item.get("folderType") == "VirtualFolder":
419
+ payload = {
420
+ "copyContentsFrom": item["_id"],
421
+ "name": item["name"],
422
+ "parent": parent
423
+ }
424
+ url = f"{self.cloudos_url}/api/v1/folders/virtual?teamId={self.workspace_id}"
425
+ # S3 folder
426
+ elif item.get("folderType") == "S3Folder":
427
+ payload = {
428
+ "s3BucketName": item["s3BucketName"],
429
+ "s3ObjectKey": item.get("s3ObjectKey") or item.get("s3Prefix"),
430
+ "name": item["name"],
431
+ "parent": parent,
432
+ "isManagedByLifebit": item.get("isManagedByLifebit", False)
433
+ }
434
+ url = f"{self.cloudos_url}/api/v1/folders/s3?teamId={self.workspace_id}"
435
+ # S3 file
436
+ elif item.get("fileType") == "S3File":
437
+ payload = {
438
+ "s3BucketName": item["s3BucketName"],
439
+ "s3ObjectKey": item["s3ObjectKey"],
440
+ "name": item["name"],
441
+ "parent": parent,
442
+ "isManagedByLifebit": item.get("isManagedByLifebit", False),
443
+ "sizeInBytes": item.get("sizeInBytes", 0)
444
+ }
445
+ url = f"{self.cloudos_url}/api/v1/files/s3?teamId={self.workspace_id}"
446
+ else:
447
+ raise ValueError(f"Unknown item type for copy: {item.get('name')}")
448
+ response = retry_requests_post(url, headers=headers, json=payload)
449
+
406
450
  return response
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudos_cli
3
- Version: 2.33.0
3
+ Version: 2.34.0
4
4
  Summary: Python package for interacting with CloudOS
5
5
  Home-page: https://github.com/lifebit-ai/cloudos-cli
6
6
  Author: David Piñeyro
@@ -1014,6 +1014,36 @@ Please, note that in the above example a preconfigured profile has been used. If
1014
1014
  --project-name $PROJEC_NAME
1015
1015
  ```
1016
1016
 
1017
+ #### Copying files and folders
1018
+
1019
+ Files and folders can be copied **from** anywhere in the project **to** `Data` or any of its subfolders programmatically (i.e `Data`, `Data/folder/file.txt`).
1020
+
1021
+ 1. The copy can happen **within the same project** running the following command:
1022
+ ```
1023
+ cloudos datasets cp <souce_path> <destination_path> --profile <profile name>
1024
+ ```
1025
+ where the source project as well as the destination one is the one defined in the profile.
1026
+
1027
+ 2. The move can also happen **across different projects** within the same workspace by running the following command
1028
+ ```
1029
+ cloudos datasets cp <source_path> <destiantion_path> --profile <profile_name> --destination-project-name <project_name>
1030
+ ```
1031
+ In this case, only the source project is the one specified in the profile.
1032
+
1033
+ Any of the `source_path` must be a full path; any `destination_path` must be a path starting with `Data` and finishing with the folder where to move the file/folder. An example of such command is:
1034
+
1035
+ ```
1036
+ cloudos datasets cp AnalysesResults/my_analysis/results/my_plot.png Data/plots
1037
+ ```
1038
+
1039
+ Please, note that in the above example a preconfigured profile has been used. If no profile is provided and there is no default profile, the user will need to also provide the following flags
1040
+ ```bash
1041
+ --cloudos-url $CLOUDOS \
1042
+ --apikey $MY_API_KEY \
1043
+ --workspace-id $WORKSPACE_ID \
1044
+ --project-name $PROJEC_NAME
1045
+ ```
1046
+
1017
1047
  ### WDL pipeline support
1018
1048
 
1019
1049
  #### Cromwell server managing
@@ -1 +0,0 @@
1
- __version__ = '2.33.0'
File without changes
File without changes
File without changes