Feat: Move link implementation to the interactive session module#318
Feat: Move link implementation to the interactive session module#318l-mansouri wants to merge 14 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR relocates the legacy cloudos link functionality under the interactive-session module as cloudos interactive-session link, and updates interactive session creation to replace --mount with --link --copy for copying data into sessions.
Changes:
- Introduces
cloudos interactive-session linkwith support for job-based linking and multi-project path inference. - Reworks
cloudos interactive-session createto remove--mountand add--copy(copy via--linkpaths). - Updates documentation, changelog, and tests to reflect the new CLI surface and behaviors.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_interactive_session/test_link_session.py | Adds tests for the new interactive-session link command and FE path normalization helpers. |
| tests/test_interactive_session/test_create_session.py | Updates create-session tests for --copy/--link behavior and removes --mount expectations. |
| tests/test_datasets/test_link.py | Updates datasets link tests to use the relocated Link implementation and adjusts expectations. |
| tests/test_datasets/test_link_files.py | Updates link-files tests for the relocated Link implementation and revised output/messages. |
| README.md | Documents interactive-session link and replaces --mount with --link --copy guidance. |
| cloudos_cli/link/init.py | Removes the legacy cloudos_cli.link package initializer/export. |
| cloudos_cli/jobs/cli.py | Switches imports to use cloudos_cli.interactive_session.link.Link. |
| cloudos_cli/interactive_session/link.py | Hosts the Link implementation; adds multi-batch support and path display updates. |
| cloudos_cli/interactive_session/interactive_session.py | Removes resolve_data_file_id and adjusts session output formatting for copied/link data display. |
| cloudos_cli/interactive_session/cli.py | Adds interactive-session link, removes --mount, introduces --copy, and implements FE path normalization/grouping. |
| cloudos_cli/interactive_session/init.py | Exposes Link from the interactive-session module. |
| cloudos_cli/datasets/cli.py | Updates imports to new Link location and modifies datasets link command docs/behavior. |
| cloudos_cli/_version.py | Bumps version to 2.92.0. |
| cloudos_cli/main.py | Removes the top-level cloudos link command registration. |
| CHANGELOG.md | Adds v2.92.0 entry describing the new command location and --copy change. |
Comments suppressed due to low confidence (3)
cloudos_cli/interactive_session/link.py:647
- _parse_file_explorer_item now calls generate_datasets_for_project(), which can sys.exit(1) on common errors (missing project / Forbidden). That can terminate the whole CLI process (or any caller using Link as a library) instead of surfacing a normal ValueError that link/copy commands can handle and report cleanly.
cloudos_cli/interactive_session/link.py:729 - get_fuse_filesystems_status treats HTTP 401 as "Forbidden". 401 is "Unauthorized" (authentication), while 403 is "Forbidden" (authorization). This makes the error misleading and inconsistent with other handlers in this file.
cloudos_cli/interactive_session/link.py:482 - _handle_mount_error maps "401/unauthorized" to a message starting with "Forbidden". This is incorrect for 401 responses and will confuse users when an API key is invalid/expired.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (3)
cloudos_cli/interactive_session/link.py:621
- _parse_file_explorer_item calls generate_datasets_for_project(), which can sys.exit(1) on project-not-found / forbidden. That makes Link unusable as a library helper (and bypasses the CLI’s structured error handling), and can abruptly terminate tests/callers instead of raising a catchable exception.
cloudos_cli/interactive_session/link.py:702 - 401 responses are labeled as "Forbidden" here, but 401 is Unauthorized. This message is also inconsistent with the v1 mount handler above in this file, which uses "Unauthorized..." for 401.
cloudos_cli/interactive_session/link.py:461 - _handle_mount_error treats 401 as "Forbidden", which is misleading and inconsistent with other 401 handling in this module (e.g., _mount_single_folder_v1 raises "Unauthorized...").
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (4)
cloudos_cli/interactive_session/link.py:125
- link_folders_batch returns True for any non-204 response, which can report success even when the mount request wasn’t accepted or when verification never ran (e.g., v1 success codes other than 204, or future API changes). This breaks the method’s contract (“verified as mounted”) and can cause callers (e.g., datasets link / interactive-session link) to miss failures.
cloudos_cli/interactive_session/link.py:461 - _handle_mount_error maps 401/unauthorized to a "Forbidden" message. That’s both semantically incorrect (401 != 403) and currently contradicts the unit tests expecting an invalid API key/unauthorized message.
cloudos_cli/interactive_session/link.py:702 - get_fuse_filesystems_status raises a "Forbidden" message on HTTP 401. This is misleading (401 is Unauthorized) and inconsistent with other 401 handling in this module (e.g., _mount_single_folder_v1).
cloudos_cli/interactive_session/link.py:621 - _parse_file_explorer_item calls generate_datasets_for_project(), which can sys.exit(1) internally on common errors (missing project / Forbidden). That makes Link hard to use safely from other code paths (and prevents Click from formatting a clean error), since SystemExit bypasses normal exception handling.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (6)
cloudos_cli/interactive_session/link.py:125
link_folders_batchreturnsTruefor any non-204 status code, which can incorrectly report success without verifying mounts (e.g., if the mount endpoint returns 200/202 or an unexpected 2xx). This also contradicts the method docstring that says mounts are verified asmounted.
cloudos_cli/interactive_session/link.py:462- The 401 handling reports "Forbidden" (403) even though this branch is for 401/unauthorized. This makes CLI output misleading and can confuse users troubleshooting API key vs. authorization issues.
cloudos_cli/interactive_session/link.py:703 - This 401 branch raises a "Forbidden" error message. 401 indicates authentication failure (invalid/missing API key), while 403 indicates the key is valid but lacks access. Using the wrong status text makes it harder to debug API issues.
cloudos_cli/interactive_session/link.py:621 generate_datasets_for_project(...)can callsys.exit(1)(seecloudos_cli/utils/array_job.py), which will terminate the CLI abruptly from inside_parse_file_explorer_itemand bypass the normal Click error handling / messaging. Converting that to aValueErrorhere keeps error handling consistent and prevents hard exits from a library-style helper.
cloudos_cli/interactive_session/cli.py:495- When
--copyis used, S3 inputs are treated as files without validating that the provided path is actually a file (e.g. a trailing/would be sent as anS3Fileobject key). This can lead to confusing API failures; it should be rejected early with a clear usage error, and thenameshould be the basename rather than the full key/prefix.
s3_file_item = {
"type": "S3File",
"data": {
"name": parsed["s3_prefix"],
"s3BucketName": parsed["s3_bucket"],
cloudos_cli/datasets/cli.py:766
cloudos datasets linkdocuments File Explorer paths as relative to--project-name, but there is no guard against users passingmy-project/Data/...(which is now encouraged byinteractive-session link). Without a check, the CLI will attempt to resolve a folder namedmy-projectinside projectmy-project, producing a confusing "not found" error.
if not path.startswith("s3://") and project_name is None:
raise click.UsageError("When using File Explorer paths '--project-name' needs to be defined")
Overview
This PR moves the link command implementation to the interactive session module and changes the
--mountoption of cloudos interactive-session to--link --copyJIRA
https://lifebit.atlassian.net/browse/LP-110779
Changes
cloudos linkinto theinteractive-sessionmodule ascloudos interactive-session linkmy-project/Data/folder); standard top-level folder names (Data,AnalysesResults,Analyses_Results,Analyses-Results,Cohorts) are treated as relative to the profile project--mountfromcloudos interactive-session create--copyas an optional flag of--linkincloudos interactive-session createto copy data into the sessionAcceptance Criteria
Scenario 1: cloudos interactive-session link replaces cloudos link with identical functionality
Scenario 2: create --link links a folder or file to the interactive session
Scenario 3: create --link --copy copies data into the interactive session
Scenario 4: Files are linkable via cloudos interactive-session link if supported by the DEV endpoint
Scenario 5: Detailed API error messages are surfaced to the user on failure