Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
## lifebit-ai/cloudos-cli: changelog

## v2.91.0 (2026-05-28)

### Feat:

- Implements linking of files in interactive session creation
- Implements linking of files in `cloudos link`
- Removes support for linking while resuming a paused interactive session
- Enforces a maximum of 100 linked items per interactive session
- Adds clearer, actionable error messages when mounts fail (e.g. translates "prefix does not exist" / "access denied" into workspace-permission guidance)

### Breaking:

- `cloudos link` and `cloudos datasets link`: File Explorer paths must now be RELATIVE to `--project-name` (do NOT prepend the project name). Previously the leading `<project>/` segment was advertised but produced confusing errors; it is now rejected up front with a clear message pointing to the correct form. `cloudos interactive-session create --link` still uses `<project>/<folder-path>` format — see each command's `--help` for the explicit cross-reference.


## v2.90.2 (2026-05-07)

### Patch
Expand Down
92 changes: 54 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ Python package for interacting with Lifebit Platform
- [Move Files](#move-files)
- [Rename Files](#rename-files)
- [Copy Files](#copy-files)
- [Link S3 Folders to Interactive Analysis](#link-s3-folders-to-interactive-analysis)
- [Link Files and Folders to Interactive Analysis](#link-files-and-folders-to-interactive-analysis)
- [Create Folder](#create-folder)
- [Remove Files or Folders](#remove-files-or-folders)
- [Link](#link)
- [Link Folders to Interactive Analysis](#link-folders-to-interactive-analysis)
- [Link Files and Folders to Interactive Analysis](#link-files-and-folders-to-interactive-analysis-1)
- [Procurement](#procurement)
- [List Procurement Images](#list-procurement-images)
- [Set Procurement Organization Image](#set-procurement-organization-image)
Expand Down Expand Up @@ -2148,7 +2148,7 @@ cloudos interactive-session create \

**Data & Storage Management:**
- `--mount`: Mount a data file into the session. Supports both Lifebit Platform datasets and S3 files (AWS only). Format: `project_name/dataset_path` (e.g., `leila-test/Data/file.csv`) or `s3://bucket/path/to/file` (e.g., `s3://my-bucket/data/file.csv`). Can be used multiple times.
- `--link`: Link a folder into the session for read/write access (AWS only). Supports S3 folders (e.g., `s3://my-bucket/data/`) and File Explorer folders (e.g., `my-project/Data/results`). Multiple folders can be specified using multiple `--link` flags or as comma-separated paths in a single `--link` argument.
- `--link`: Link a file or folder into the session for read access (AWS only). Supports S3 files/folders (e.g., `s3://my-bucket/data/file.csv`, `s3://my-bucket/data/`) and File Explorer files/folders (e.g., `my-project/Data/file.csv`, `my-project/Data/results`). S3 paths whose last segment contains a `.` are treated as files; paths ending with `/` or without an extension are treated as folders. Multiple items can be specified using multiple `--link` flags or as comma-separated paths in a single `--link` argument.
**Note:** Linking is not supported on Azure. Use Lifebit Platform File Explorer for data access.

**Backend-Specific:**
Expand All @@ -2163,7 +2163,7 @@ cloudos interactive-session create \

CloudOS CLI supports multiple ways to access data in interactive sessions, depending on your execution platform:
- **Mount files** (`--mount`): Files are copied into the session's mounted-data volume. Supports CloudOS File Explorer files and S3 files (AWS only).
- **Link folders** (`--link`): Folders are mounted as read/write accessible directories in the session (AWS only). Supports both S3 folders and Lifebit Platform File Explorer folders. Linked folders appear with unique mount names based on the folder path.
- **Link files/folders** (`--link`): Files and folders are mounted as read-accessible items in the session (AWS only). Supports S3 files, S3 folders, and Lifebit Platform File Explorer files and folders. Linked items appear with unique mount names based on the item name. Maximum 100 items per session.


**Data Mounting Examples**
Expand Down Expand Up @@ -2537,7 +2537,7 @@ The command automatically loads from profile (via `@with_profile_config` decorat

#### Resume Interactive Session

Resume a paused interactive session with optional configuration updates. You can change instance type, storage, cost limit, auto-shutdown time, and mount additional data files or folders when resuming.
Resume a paused interactive session with optional configuration updates. You can change instance type, storage, cost limit, and auto-shutdown time when resuming.


**Basic Usage**
Expand Down Expand Up @@ -2569,19 +2569,6 @@ cloudos interactive-session resume \
--shutdown-in 12h
```

**Mount Additional Data**

Resume and mount additional files:

```bash
cloudos interactive-session resume \
--session-id <SESSION_ID> \
--profile my_profile \
--mount my-project/Data/new-dataset.csv \
--mount s3://my-bucket/data/file.txt
```


**Configuration Updates**

All configuration parameters are optional. If not specified, the session resumes with its previous configuration.
Expand All @@ -2591,6 +2578,8 @@ All configuration parameters are optional. If not specified, the session resumes
- `--cost-limit <USD>` - Update compute cost limit (-1 for unlimited)
- `--shutdown-in <DURATION>` - Update auto-shutdown time (e.g., 8h, 2d)

> To link or mount data to a running session, use `cloudos link` or `cloudos datasets link` after the session has resumed.

### Datasets

Manage files and folders within your Lifebit Platform File Explorer programmatically. These commands provide comprehensive file management capabilities for organizing research data and results.
Expand Down Expand Up @@ -2718,31 +2707,44 @@ cloudos datasets cp AnalysesResults/my_analysis/results/my_plot.png Data/plots
```


#### Link S3 Folders to Interactive Analysis
#### Link Files and Folders to Interactive Analysis

Connect external S3 buckets or internal File Explorer folders to your interactive analysis sessions. This provides direct access to data without needing to copy files.
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.

This subcommand is using the option `--session-id` to access the correct interactive session. This option can be added to the CLI or defined in a profile, for convenience.
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.

```bash
cloudos datasets link <S3_FOLDER_COMPLETE_PATH_OR_VIRTUAL_FOLDER_PATH> --profile <profile> --session-id <SESSION_ID>
cloudos datasets link <PATH> --profile <profile> --session-id <SESSION_ID>
```

For example, an s3 folder can be linked like follows
Link an S3 folder:
```console
cloudos datasets link s3://bucket/path/folder --profile test --session-id 1234
```

A virtual folder can be linked like
``` concole
cloudos datasets link "Analyses Results/HLA" --session-id 1234
Link an S3 file:
```console
cloudos datasets link s3://bucket/path/data.csv --profile test --session-id 1234
```

Link a File Explorer folder (requires `--project-name`):
```console
cloudos datasets link "Data/HLA" --project-name my-project --session-id 1234
```

Link a File Explorer file (requires `--project-name`):
```console
cloudos datasets link "Data/observations.csv" --project-name my-project --session-id 1234
```

> [!NOTE]
> 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.

> [!NOTE]
> Virtual folders in File Explorer, the ones a user has created in File explorer and are not actual storage locations, cannot be linked.
> Virtual folders in File Explorer (folders created in File Explorer that are not actual storage locations) cannot be linked.

> [!NOTE]
> 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.

#### Create Folder

Expand Down Expand Up @@ -2772,20 +2774,22 @@ cloudos datasets rm <path> --profile my_profile

### Link

The `cloudos link` command provides a unified interface for linking folders to interactive analysis sessions. This command 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.
The `cloudos link` command provides a unified interface for linking files and folders to interactive analysis sessions. This command 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.

#### Link Folders to Interactive Analysis
#### Link Files and Folders to Interactive Analysis

Link job-related folders or custom S3 paths to your interactive analysis sessions for direct access to data without needing to copy files.
Link job-related folders or custom S3/File Explorer paths (files and folders) to your interactive analysis sessions for direct access to data without needing to copy files.

**Two modes of operation:**

1. **Job-based linking** (`--job-id`): Links folders from a completed or running job
- By default, links results, workdir, and logs folders
- Use `--results`, `--workdir`, or `--logs` flags to link only specific folders

2. **Direct path linking** (PATH argument): Links specific S3 or File Explorer paths. It supports a single path or comma-separated multiple paths.

2. **Direct path linking** (PATH argument): Links specific S3 or File Explorer paths (files or folders). Supports a single path or comma-separated multiple paths.
- S3 paths whose last segment contains a `.` are treated as files (e.g., `s3://bucket/data/file.csv`)
- S3 paths ending with `/` or without an extension are treated as folders
- File Explorer paths can point to either files or folders — the CLI detects the type automatically

**Basic usage:**

Expand All @@ -2797,16 +2801,28 @@ cloudos link --job-id <JOB_ID> --session-id <SESSION_ID> --profile my_profile
cloudos link --job-id <JOB_ID> --session-id <SESSION_ID> --results --profile my_profile
cloudos link --job-id <JOB_ID> --session-id <SESSION_ID> --workdir --logs --profile my_profile

# Link a single S3 path
cloudos link s3://bucket/folder --session-id <SESSION_ID> --profile my_profile
# Link a single S3 folder
cloudos link s3://bucket/folder/ --session-id <SESSION_ID> --profile my_profile

# Link a single S3 file
cloudos link s3://bucket/data/file.csv --session-id <SESSION_ID> --profile my_profile

# Link multiple S3 paths (comma-separated)
cloudos link s3://bucket1/data,s3://bucket2/results,s3://bucket3/output --session-id <SESSION_ID> --profile my_profile
# Link multiple S3 paths (comma-separated, files and folders mixed)
cloudos link s3://bucket1/data/,s3://bucket2/results/file.csv --session-id <SESSION_ID> --profile my_profile

# Link a File Explorer path (requires project name)
# Link a File Explorer folder (path is RELATIVE to --project-name; do NOT prepend the project)
cloudos link "Data/MyFolder" --project-name my-project --session-id <SESSION_ID> --profile my_profile

# Link a File Explorer file (path is RELATIVE to --project-name)
cloudos link "Data/file.csv" --project-name my-project --session-id <SESSION_ID> --profile my_profile

# Link several File Explorer items at once (all in the same project)
cloudos link "Data/MyFolder,Data/file.csv,Results/run-1" --project-name my-project --session-id <SESSION_ID> --profile my_profile
```

> [!IMPORTANT]
> **`cloudos link` is single-project for File Explorer paths.** All File Explorer items linked in one invocation must belong to the project named in `--project-name`. The path must be relative to that project — prepending the project name to the path (e.g. `my-project/Data/file.csv`) is rejected. To link items from a different project, run `cloudos link` again with a different `--project-name`.

**Command options:**


Expand All @@ -2816,7 +2832,7 @@ cloudos link "Data/MyFolder" --project-name my-project --session-id <SESSION_ID>
- `--workspace-id`: The specific Lifebit Platform workspace ID (required)
- `--session-id`: The specific Lifebit Platform interactive session ID (required)
- `--job-id`: The job ID in Lifebit Platform (links results, workdir, and logs by default)
- `--project-name`: Lifebit Platform project name (required for File Explorer paths)
- `--project-name`: Lifebit Platform project name. Required when any PATH is a File Explorer path. All FE paths in one invocation must belong to this project and must be RELATIVE to it (do not prepend the project name)
- `--results`: Link only results folder (only works with `--job-id`)
- `--workdir`: Link only working directory (only works with `--job-id`)
- `--logs`: Link only logs folder (only works with `--job-id`)
Expand Down
2 changes: 1 addition & 1 deletion cloudos_cli/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.90.2'
__version__ = '2.91.0'
89 changes: 15 additions & 74 deletions cloudos_cli/datasets/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,13 +754,15 @@ def link(ctx,
ssl_cert,
profile):
"""
Link a folder (S3 or File Explorer) to an active interactive analysis.
Link a file or folder (S3 or File Explorer) to an active interactive analysis.

PATH [path]: the full path to the S3 folder to link or relative to File Explorer.
E.g.: 's3://bucket-name/folder/subfolder', 'Data/Downloads' or 'Data'.
PATH [path]: the full path to the S3 file/folder, or a path RELATIVE to
the project named in --project-name for File Explorer items. Do NOT
prepend the project name to File Explorer paths.
E.g.: 's3://bucket-name/folder/subfolder', 's3://bucket/data/file.csv',
'Data/Downloads', 'Data/file.csv'.
"""
if not path.startswith("s3://") and project_name is None:
# for non-s3 paths we need the project, for S3 we don't
raise click.UsageError("When using File Explorer paths '--project-name' needs to be defined")

verify_ssl = ssl_selector(disable_ssl_verification, ssl_cert)
Expand All @@ -774,75 +776,14 @@ def link(ctx,
verify=verify_ssl
)

# Minimal folder validation and improved error messages
is_s3 = path.startswith("s3://")
is_folder = True
if is_s3:
# S3 path validation - use heuristics to determine if it's likely a folder
try:
# If path ends with '/', it's likely a folder
if path.endswith('/'):
is_folder = True
else:
# Check the last part of the path
path_parts = path.rstrip("/").split("/")
if path_parts:
last_part = path_parts[-1]
# If the last part has no dot, it's likely a folder
if '.' not in last_part:
is_folder = True
else:
# If it has a dot, it might be a file - set to None for warning
is_folder = None
else:
# Empty path parts, set to None for uncertainty
is_folder = None
except Exception:
# If we can't parse the S3 path, set to None for uncertainty
is_folder = None
else:
# File Explorer path validation (existing logic)
try:
datasets = Datasets(
cloudos_url=cloudos_url,
apikey=apikey,
workspace_id=workspace_id,
project_name=project_name,
verify=verify_ssl,
cromwell_token=None
)
parts = path.strip("/").split("/")
parent_path = "/".join(parts[:-1]) if len(parts) > 1 else ""
item_name = parts[-1]
contents = datasets.list_folder_content(parent_path)
found = None
for item in contents.get("folders", []):
if item.get("name") == item_name:
found = item
break
if not found:
for item in contents.get("files", []):
if item.get("name") == item_name:
found = item
break
if found and ("folderType" not in found):
is_folder = False
except Exception:
is_folder = None

if is_folder is False:
if is_s3:
raise ValueError("The S3 path appears to point to a file, not a folder. You can only link folders. Please link the parent folder instead.")
else:
raise ValueError("Linking files or virtual folders is not supported. Link the S3 parent folder instead.", err=True)
return
elif is_folder is None and is_s3:
click.secho("Unable to verify whether the S3 path is a folder. Proceeding with linking; " +
"however, if the operation fails, please confirm that you are linking a folder rather than a file.", fg='yellow', bold=True)

try:
link_p.link_folder(path, session_id)
succeeded = link_p.link_folder(path, session_id)
except Exception as e:
if is_s3:
print("If you are linking an S3 path, please ensure it is a folder.")
raise ValueError(f"Could not link folder. {e}")
raise ValueError(f"Could not link item. {e}")
Comment thread
dapineyro marked this conversation as resolved.

if not succeeded:
click.secho(
"Linking did not complete successfully. See errors above.",
fg='red', err=True,
)
raise SystemExit(1)
Loading
Loading