cloudos-cli 2.94.1__tar.gz → 2.95.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 (80) hide show
  1. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/PKG-INFO +3 -36
  2. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/README.md +2 -35
  3. cloudos_cli-2.95.0/cloudos_cli/_version.py +1 -0
  4. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/datasets/cli.py +13 -53
  5. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/interactive_session/link.py +19 -140
  6. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli.egg-info/PKG-INFO +3 -36
  7. cloudos_cli-2.94.1/cloudos_cli/_version.py +0 -1
  8. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/LICENSE +0 -0
  9. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/__init__.py +0 -0
  10. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/__main__.py +0 -0
  11. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/bash/__init__.py +0 -0
  12. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/bash/cli.py +0 -0
  13. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/clos.py +0 -0
  14. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/configure/__init__.py +0 -0
  15. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/configure/cli.py +0 -0
  16. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/configure/configure.py +0 -0
  17. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/constants.py +0 -0
  18. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/cost/__init__.py +0 -0
  19. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/cost/cost.py +0 -0
  20. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/cromwell/__init__.py +0 -0
  21. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/cromwell/cli.py +0 -0
  22. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/datasets/__init__.py +0 -0
  23. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/datasets/datasets.py +0 -0
  24. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/import_wf/__init__.py +0 -0
  25. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/import_wf/import_wf.py +0 -0
  26. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/interactive_session/__init__.py +0 -0
  27. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/interactive_session/cli.py +0 -0
  28. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/interactive_session/interactive_session.py +0 -0
  29. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/jobs/__init__.py +0 -0
  30. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/jobs/cli.py +0 -0
  31. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/jobs/job.py +0 -0
  32. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/logging/__init__.py +0 -0
  33. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/logging/logger.py +0 -0
  34. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/procurement/__init__.py +0 -0
  35. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/procurement/cli.py +0 -0
  36. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/procurement/images.py +0 -0
  37. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/projects/__init__.py +0 -0
  38. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/projects/cli.py +0 -0
  39. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/queue/__init__.py +0 -0
  40. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/queue/cli.py +0 -0
  41. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/queue/queue.py +0 -0
  42. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/related_analyses/__init__.py +0 -0
  43. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/related_analyses/related_analyses.py +0 -0
  44. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/utils/__init__.py +0 -0
  45. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/utils/array_job.py +0 -0
  46. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/utils/cli_helpers.py +0 -0
  47. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/utils/cloud.py +0 -0
  48. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/utils/details.py +0 -0
  49. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/utils/errors.py +0 -0
  50. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/utils/last_wf.py +0 -0
  51. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/utils/nextflow_version.py +0 -0
  52. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/utils/requests.py +0 -0
  53. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/utils/resources.py +0 -0
  54. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/workflows/__init__.py +0 -0
  55. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli/workflows/cli.py +0 -0
  56. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli.egg-info/SOURCES.txt +0 -0
  57. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli.egg-info/dependency_links.txt +0 -0
  58. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli.egg-info/entry_points.txt +0 -0
  59. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli.egg-info/requires.txt +0 -0
  60. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/cloudos_cli.egg-info/top_level.txt +0 -0
  61. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/setup.cfg +0 -0
  62. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/setup.py +0 -0
  63. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/__init__.py +0 -0
  64. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/functions_for_pytest.py +0 -0
  65. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_cli_project_create.py +0 -0
  66. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_cost/__init__.py +0 -0
  67. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_cost/test_job_cost.py +0 -0
  68. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_details.py +0 -0
  69. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_error_messages.py +0 -0
  70. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_interactive_session/__init__.py +0 -0
  71. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_interactive_session/test_create_session.py +0 -0
  72. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_interactive_session/test_link_error_handling.py +0 -0
  73. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_interactive_session/test_link_session.py +0 -0
  74. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_interactive_session/test_list_sessions.py +0 -0
  75. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_interactive_session/test_normalize_path.py +0 -0
  76. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_logging/__init__.py +0 -0
  77. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_logging/test_logger.py +0 -0
  78. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_nextflow_version.py +0 -0
  79. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_related_analyses/__init__.py +0 -0
  80. {cloudos_cli-2.94.1 → cloudos_cli-2.95.0}/tests/test_related_analyses/test_related_analyses.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudos_cli
3
- Version: 2.94.1
3
+ Version: 2.95.0
4
4
  Summary: Python package for interacting with the Lifebit Platform
5
5
  Home-page: https://github.com/lifebit-ai/cloudos-cli
6
6
  Author: David Piñeyro
@@ -2648,7 +2648,7 @@ All configuration parameters are optional. If not specified, the session resumes
2648
2648
 
2649
2649
  ### Link
2650
2650
 
2651
- The `cloudos interactive-session link` command provides a unified interface for linking files and folders to interactive analysis sessions. It consolidates functionality previously available through separate commands (`cloudos job results --link`, `cloudos job workdir --link`, `cloudos job logs --link`, and `cloudos datasets link`) into a single, intuitive interface.
2651
+ The `cloudos interactive-session link` command provides a unified interface for linking files and folders to interactive analysis sessions. It consolidates functionality previously available through separate commands (`cloudos job results --link`, `cloudos job workdir --link`, and `cloudos job logs --link`) into a single, intuitive interface.
2652
2652
 
2653
2653
  #### Link Files and Folders to Interactive Analysis
2654
2654
 
@@ -2880,41 +2880,8 @@ cloudos datasets cp AnalysesResults/my_analysis/results/my_plot.png Data/plots
2880
2880
  ```
2881
2881
 
2882
2882
 
2883
- #### Link Files and Folders to Interactive Analysis
2884
-
2885
- Connect external S3 buckets, S3 files, or File Explorer files/folders to your interactive analysis sessions. This provides direct access to data without needing to copy files.
2886
-
2887
- This subcommand uses the `--session-id` option to access the correct interactive session. This option can be added to the CLI or defined in a profile, for convenience.
2888
-
2889
- ```bash
2890
- cloudos datasets link <PATH> --profile <profile> --session-id <SESSION_ID>
2891
- ```
2892
-
2893
- Link an S3 folder:
2894
- ```console
2895
- cloudos datasets link s3://bucket/path/folder --profile test --session-id 1234
2896
- ```
2897
-
2898
- Link an S3 file:
2899
- ```console
2900
- cloudos datasets link s3://bucket/path/data.csv --profile test --session-id 1234
2901
- ```
2902
-
2903
- Link a File Explorer folder (requires `--project-name`):
2904
- ```console
2905
- cloudos datasets link "Data/HLA" --project-name my-project --session-id 1234
2906
- ```
2907
-
2908
- Link a File Explorer file (requires `--project-name`):
2909
- ```console
2910
- cloudos datasets link "Data/observations.csv" --project-name my-project --session-id 1234
2911
- ```
2912
-
2913
- > [!NOTE]
2914
- > If running the CLI inside a jupyter session, the pre-configured CLI installation will have the session ID already installed and only the `--apikey` needs to be added.
2915
-
2916
2883
  > [!NOTE]
2917
- > Virtual folders in File Explorer (folders created in File Explorer that are not actual storage locations) cannot be linked.
2884
+ > To link files or folders (S3 or File Explorer) to an interactive analysis session, use `cloudos interactive-session link` or the `--link` option of `cloudos interactive-session create`. Virtual folders in File Explorer cannot be linked.
2918
2885
 
2919
2886
  > [!NOTE]
2920
2887
  > A maximum of 100 items can be linked per session. If the new items combined with already-linked items exceed this limit, the entire request is rejected.
@@ -2613,7 +2613,7 @@ All configuration parameters are optional. If not specified, the session resumes
2613
2613
 
2614
2614
  ### Link
2615
2615
 
2616
- The `cloudos interactive-session link` command provides a unified interface for linking files and folders to interactive analysis sessions. It consolidates functionality previously available through separate commands (`cloudos job results --link`, `cloudos job workdir --link`, `cloudos job logs --link`, and `cloudos datasets link`) into a single, intuitive interface.
2616
+ The `cloudos interactive-session link` command provides a unified interface for linking files and folders to interactive analysis sessions. It consolidates functionality previously available through separate commands (`cloudos job results --link`, `cloudos job workdir --link`, and `cloudos job logs --link`) into a single, intuitive interface.
2617
2617
 
2618
2618
  #### Link Files and Folders to Interactive Analysis
2619
2619
 
@@ -2845,41 +2845,8 @@ cloudos datasets cp AnalysesResults/my_analysis/results/my_plot.png Data/plots
2845
2845
  ```
2846
2846
 
2847
2847
 
2848
- #### Link Files and Folders to Interactive Analysis
2849
-
2850
- Connect external S3 buckets, S3 files, or File Explorer files/folders to your interactive analysis sessions. This provides direct access to data without needing to copy files.
2851
-
2852
- This subcommand uses the `--session-id` option to access the correct interactive session. This option can be added to the CLI or defined in a profile, for convenience.
2853
-
2854
- ```bash
2855
- cloudos datasets link <PATH> --profile <profile> --session-id <SESSION_ID>
2856
- ```
2857
-
2858
- Link an S3 folder:
2859
- ```console
2860
- cloudos datasets link s3://bucket/path/folder --profile test --session-id 1234
2861
- ```
2862
-
2863
- Link an S3 file:
2864
- ```console
2865
- cloudos datasets link s3://bucket/path/data.csv --profile test --session-id 1234
2866
- ```
2867
-
2868
- Link a File Explorer folder (requires `--project-name`):
2869
- ```console
2870
- cloudos datasets link "Data/HLA" --project-name my-project --session-id 1234
2871
- ```
2872
-
2873
- Link a File Explorer file (requires `--project-name`):
2874
- ```console
2875
- cloudos datasets link "Data/observations.csv" --project-name my-project --session-id 1234
2876
- ```
2877
-
2878
- > [!NOTE]
2879
- > If running the CLI inside a jupyter session, the pre-configured CLI installation will have the session ID already installed and only the `--apikey` needs to be added.
2880
-
2881
2848
  > [!NOTE]
2882
- > Virtual folders in File Explorer (folders created in File Explorer that are not actual storage locations) cannot be linked.
2849
+ > To link files or folders (S3 or File Explorer) to an interactive analysis session, use `cloudos interactive-session link` or the `--link` option of `cloudos interactive-session create`. Virtual folders in File Explorer cannot be linked.
2883
2850
 
2884
2851
  > [!NOTE]
2885
2852
  > A maximum of 100 items can be linked per session. If the new items combined with already-linked items exceed this limit, the entire request is rejected.
@@ -0,0 +1 @@
1
+ __version__ = '2.95.0'
@@ -4,7 +4,6 @@ import rich_click as click
4
4
  import csv
5
5
  import sys
6
6
  from cloudos_cli.datasets import Datasets
7
- from cloudos_cli.interactive_session.link import Link
8
7
  from cloudos_cli.utils.resources import ssl_selector, format_bytes
9
8
  from cloudos_cli.configure.configure import with_profile_config, CLOUDOS_URL
10
9
  from cloudos_cli.logging.logger import update_command_context_from_click
@@ -727,57 +726,18 @@ def rm_item(ctx,
727
726
  raise ValueError(f"Remove operation failed. {str(e)}")
728
727
 
729
728
 
730
- @datasets.command(name="link")
731
- @click.argument("path", required=True)
732
- @click.option('-k', '--apikey', help='Your Lifebit Platform API key', required=True)
733
- @click.option('-c', '--cloudos-url',
734
- help=(f'The Lifebit Platform url you are trying to access to. Default={CLOUDOS_URL}.'),
735
- default=CLOUDOS_URL)
736
- @click.option('--project-name',
737
- help='The name of a Lifebit Platform project.',
738
- required=False)
739
- @click.option('--workspace-id', help='The specific Lifebit Platform workspace id.', required=True)
740
- @click.option('--session-id', help='The specific Lifebit Platform interactive session id.', required=True)
741
- @click.option('--disable-ssl-verification', is_flag=True, help='Disable SSL certificate verification.')
742
- @click.option('--ssl-cert', help='Path to your SSL certificate file.')
743
- @click.option('--profile', help='Profile to use from the config file', default='default')
729
+ @datasets.command(
730
+ name="link",
731
+ hidden=True,
732
+ add_help_option=False,
733
+ context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
734
+ )
744
735
  @click.pass_context
745
- @with_profile_config(required_params=['apikey', 'workspace_id', 'session_id'])
746
- def link(ctx,
747
- path,
748
- apikey,
749
- cloudos_url,
750
- project_name,
751
- workspace_id,
752
- session_id,
753
- disable_ssl_verification,
754
- ssl_cert,
755
- profile):
756
- """
757
- Link a file or folder (S3 or File Explorer) to an active interactive analysis.
758
-
759
- PATH [path]: the full path to the S3 file/folder or relative path in File Explorer
760
- (relative to the project specified by --project-name).
761
- E.g.: 's3://bucket-name/folder/subfolder', 's3://bucket/data/file.csv',
762
- 'Data/Downloads', 'Data', or 'Data/file.csv'.
763
- """
764
- if not path.startswith("s3://") and project_name is None:
765
- raise click.UsageError("When using File Explorer paths '--project-name' needs to be defined")
766
-
767
- verify_ssl = ssl_selector(disable_ssl_verification, ssl_cert)
768
-
769
- link_p = Link(
770
- cloudos_url=cloudos_url,
771
- apikey=apikey,
772
- workspace_id=workspace_id,
773
- cromwell_token=None,
774
- project_name=project_name,
775
- verify=verify_ssl
736
+ def link_deprecated(ctx):
737
+ raise click.ClickException(
738
+ "'cloudos datasets link' has been removed.\n\n"
739
+ "Use one of the supported alternatives:\n"
740
+ " cloudos interactive-session link <PATH> --session-id <SESSION_ID>\n"
741
+ " cloudos interactive-session create --link <PATH> [...]\n\n"
742
+ "Add --profile <my_profile> to either command to use a saved profile."
776
743
  )
777
-
778
- try:
779
- success = link_p.link_folder(path, session_id)
780
- except Exception as e:
781
- raise ValueError(f"Could not link item. {e}")
782
- if not success:
783
- raise click.ClickException("Linking failed: mount verification did not reach 'mounted' status.")
@@ -78,8 +78,7 @@ class Link(Cloudos):
78
78
  committed_count: int = 0) -> bool:
79
79
  """Link multiple folders/files (S3 or File Explorer) to an interactive session in one request.
80
80
 
81
- Attempts to use API v2 (which supports multiple items per request) first,
82
- with automatic fallback to v1 (individual requests) if v2 is not available.
81
+ Uses API v2 which supports multiple items per request.
83
82
 
84
83
  Parameters
85
84
  ----------
@@ -112,17 +111,13 @@ class Link(Cloudos):
112
111
  # Parse and validate all items
113
112
  data_items, folder_info = self._parse_items_to_data_items(folders, existing_mount_names)
114
113
 
115
- # Try v2 API first (supports batch)
114
+ # Mount via v2 API (supports batch)
116
115
  status_code = self._try_mount_v2(data_items, session_id)
117
116
 
118
- if status_code is None:
119
- # v2 failed or not available, fall back to v1
120
- status_code = self._fallback_mount_v1(folder_info, session_id)
121
-
122
117
  # Verify mount completion for all items (any 2xx response means success)
123
- if status_code is not None and 200 <= status_code < 300:
118
+ if 200 <= status_code < 300:
124
119
  return self._verify_all_mounts(folder_info, session_id)
125
- return True
120
+ return False
126
121
 
127
122
  def _parse_items_to_data_items(self, folders: list, existing_mount_names: set = None) -> tuple:
128
123
  """Parse and validate folders/files, extracting data items for API payload.
@@ -206,7 +201,7 @@ class Link(Cloudos):
206
201
  )
207
202
 
208
203
  def _try_mount_v2(self, data_items: list, session_id: str) -> int:
209
- """Attempt to mount folders using API v2.
204
+ """Mount items using API v2.
210
205
 
211
206
  Parameters
212
207
  ----------
@@ -217,151 +212,35 @@ class Link(Cloudos):
217
212
 
218
213
  Returns
219
214
  -------
220
- int or None
221
- Status code if successful, None if v2 unavailable (triggering fallback).
215
+ int
216
+ HTTP status code on success.
222
217
 
223
218
  Raises
224
219
  ------
225
220
  ValueError
226
- If v2 fails for reasons other than unavailability.
221
+ If the mount request fails.
227
222
  """
228
223
  v2_payload = {"dataItems": data_items}
229
224
 
230
225
  try:
231
- status_code = self.mount_fuse_filesystem_v2(
226
+ return self.mount_fuse_filesystem_v2(
232
227
  session_id=session_id,
233
228
  team_id=self.workspace_id,
234
229
  payload=v2_payload,
235
230
  verify=self.verify
236
231
  )
237
- return status_code
238
232
  except Exception as v2_error:
239
- # Check if error indicates v2 endpoint not available (404 only, but not session-not-found)
240
- error_str = str(v2_error)
241
- # Only fall back to v1 if it's a genuine endpoint-not-available 404
242
- # Session-not-found errors should propagate immediately
243
- if "Session not found" in error_str:
244
- raise # Re-raise session-not-found errors immediately
245
-
246
- should_fallback = (
247
- "404" in error_str or "Not Found" in error_str or "not found" in error_str.lower()
248
- )
249
-
250
- if should_fallback:
251
- return None # Trigger v1 fallback
252
- else:
253
- # v2 failed for reasons other than not available
254
- self._handle_mount_error(v2_error, "folder")
255
-
256
- def _fallback_mount_v1(self, folder_info: list, session_id: str) -> int:
257
- """Fall back to v1 API, mounting folders one at a time.
258
-
259
- Parameters
260
- ----------
261
- folder_info : list
262
- List of folder metadata dictionaries.
263
- session_id : str
264
- The interactive session ID.
265
-
266
- Returns
267
- -------
268
- int
269
- Status code from the last successful mount (typically 204).
270
-
271
- Raises
272
- ------
273
- ValueError
274
- If any item is a file (v1 only supports folders), or if any folder
275
- fails to mount. Note: Earlier folders may have successfully mounted
276
- before the failure.
277
- """
278
- for f in folder_info:
279
- item_type = f['data'].get('type', '')
280
- item_kind = f['data'].get('kind', '')
281
- if item_type == 'S3File' or item_kind == 'File':
233
+ if isinstance(v2_error, ValueError):
234
+ raise
235
+ if isinstance(v2_error, BadRequestException) and v2_error.rv.status_code == 404:
282
236
  raise ValueError(
283
- f"File linking requires API v2, which is not available for this session. "
284
- f"Only folder linking is supported via the v1 API fallback."
285
- )
286
-
287
- status_code = None
288
- mounted_folders = []
289
-
290
- for folder_data in folder_info:
291
- try:
292
- status_code = self._mount_single_folder_v1(folder_data, session_id)
293
- mounted_folders.append(folder_data['path'])
294
- except ValueError as e:
295
- # If we've already mounted some folders, inform the user
296
- if mounted_folders:
297
- error_msg = f"{str(e)}\n\nNote: The following folders were successfully mounted before this error: {', '.join(mounted_folders)}"
298
- raise ValueError(error_msg)
299
- else:
300
- raise
301
- return status_code
302
-
303
- def _mount_single_folder_v1(self, folder_data: dict, session_id: str) -> int:
304
- """Mount a single folder using API v1.
305
-
306
- Parameters
307
- ----------
308
- folder_data : dict
309
- Folder metadata including type, path, and data.
310
- session_id : str
311
- The interactive session ID.
312
-
313
- Returns
314
- -------
315
- int
316
- Status code (typically 204 on success).
317
-
318
- Raises
319
- ------
320
- ValueError
321
- If the mount request fails.
322
- """
323
- v1_payload = {"dataItem": folder_data["data"]}
324
-
325
- url = (
326
- f"{self.cloudos_url}/api/v1/"
327
- f"interactive-sessions/{session_id}/fuse-filesystem/mount"
328
- f"?teamId={self.workspace_id}"
329
- )
330
- headers = {
331
- "Content-type": "application/json",
332
- "apikey": self.apikey
333
- }
334
-
335
- try:
336
- r = retry_requests_post(url, headers=headers, json=v1_payload, verify=self.verify)
337
-
338
- if r.status_code >= 400:
339
- # Handle v1 errors using consolidated error handling
340
- if r.status_code == 403:
341
- raise ValueError(f"Provided {folder_data['type']} item already exists with 'mounted' status")
342
- elif r.status_code == 401:
343
- raise ValueError("Unauthorized. Invalid API key or insufficient permissions.")
344
- elif r.status_code == 400:
345
- try:
346
- r_content = json.loads(r.content)
347
- if r_content.get("message") == "Invalid Supported DataItem folderType. Supported values are S3Folder":
348
- raise ValueError(f"Invalid Supported DataItem '{folder_data['type']}' folderType. Virtual folders cannot be linked.")
349
- elif r_content.get("message") == "Request failed with status code 403":
350
- raise ValueError(f"Interactive Analysis session is not active")
351
- else:
352
- raise ValueError(f"Cannot link item")
353
- except json.JSONDecodeError:
354
- raise ValueError(f"Bad request (400): Unable to parse error response")
355
- else:
356
- raise ValueError(f"Failed to mount item: HTTP {r.status_code}")
357
-
358
- return r.status_code
359
-
360
- except ValueError:
361
- # Re-raise ValueError as-is
362
- raise
363
- except Exception as v1_error:
364
- raise ValueError(f"Failed to mount {folder_data['type']} item: {str(v1_error)}")
237
+ "The linking API (v2) is not available on this platform. "
238
+ "Contact your platform administrator."
239
+ ) from v2_error
240
+ all_s3 = all(item.get("type", "").startswith("S3") for item in data_items)
241
+ all_fe = all(not item.get("type", "").startswith("S3") for item in data_items)
242
+ label = "S3" if all_s3 else "File Explorer" if all_fe else "item"
243
+ self._handle_mount_error(v2_error, label)
365
244
 
366
245
  def _verify_all_mounts(self, folder_info: list, session_id: str):
367
246
  """Verify mount completion status for all items (files and folders).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudos_cli
3
- Version: 2.94.1
3
+ Version: 2.95.0
4
4
  Summary: Python package for interacting with the Lifebit Platform
5
5
  Home-page: https://github.com/lifebit-ai/cloudos-cli
6
6
  Author: David Piñeyro
@@ -2648,7 +2648,7 @@ All configuration parameters are optional. If not specified, the session resumes
2648
2648
 
2649
2649
  ### Link
2650
2650
 
2651
- The `cloudos interactive-session link` command provides a unified interface for linking files and folders to interactive analysis sessions. It consolidates functionality previously available through separate commands (`cloudos job results --link`, `cloudos job workdir --link`, `cloudos job logs --link`, and `cloudos datasets link`) into a single, intuitive interface.
2651
+ The `cloudos interactive-session link` command provides a unified interface for linking files and folders to interactive analysis sessions. It consolidates functionality previously available through separate commands (`cloudos job results --link`, `cloudos job workdir --link`, and `cloudos job logs --link`) into a single, intuitive interface.
2652
2652
 
2653
2653
  #### Link Files and Folders to Interactive Analysis
2654
2654
 
@@ -2880,41 +2880,8 @@ cloudos datasets cp AnalysesResults/my_analysis/results/my_plot.png Data/plots
2880
2880
  ```
2881
2881
 
2882
2882
 
2883
- #### Link Files and Folders to Interactive Analysis
2884
-
2885
- Connect external S3 buckets, S3 files, or File Explorer files/folders to your interactive analysis sessions. This provides direct access to data without needing to copy files.
2886
-
2887
- This subcommand uses the `--session-id` option to access the correct interactive session. This option can be added to the CLI or defined in a profile, for convenience.
2888
-
2889
- ```bash
2890
- cloudos datasets link <PATH> --profile <profile> --session-id <SESSION_ID>
2891
- ```
2892
-
2893
- Link an S3 folder:
2894
- ```console
2895
- cloudos datasets link s3://bucket/path/folder --profile test --session-id 1234
2896
- ```
2897
-
2898
- Link an S3 file:
2899
- ```console
2900
- cloudos datasets link s3://bucket/path/data.csv --profile test --session-id 1234
2901
- ```
2902
-
2903
- Link a File Explorer folder (requires `--project-name`):
2904
- ```console
2905
- cloudos datasets link "Data/HLA" --project-name my-project --session-id 1234
2906
- ```
2907
-
2908
- Link a File Explorer file (requires `--project-name`):
2909
- ```console
2910
- cloudos datasets link "Data/observations.csv" --project-name my-project --session-id 1234
2911
- ```
2912
-
2913
- > [!NOTE]
2914
- > If running the CLI inside a jupyter session, the pre-configured CLI installation will have the session ID already installed and only the `--apikey` needs to be added.
2915
-
2916
2883
  > [!NOTE]
2917
- > Virtual folders in File Explorer (folders created in File Explorer that are not actual storage locations) cannot be linked.
2884
+ > To link files or folders (S3 or File Explorer) to an interactive analysis session, use `cloudos interactive-session link` or the `--link` option of `cloudos interactive-session create`. Virtual folders in File Explorer cannot be linked.
2918
2885
 
2919
2886
  > [!NOTE]
2920
2887
  > A maximum of 100 items can be linked per session. If the new items combined with already-linked items exceed this limit, the entire request is rejected.
@@ -1 +0,0 @@
1
- __version__ = '2.94.1'
File without changes
File without changes
File without changes