Skip to content

Commit ffe0f1b

Browse files
committed
Some usage tweaks to the data links CLI
1 parent 509e73b commit ffe0f1b

File tree

2 files changed

+72
-5
lines changed

2 files changed

+72
-5
lines changed

src/seqera/commands/datalinks/__init__.py

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -644,9 +644,9 @@ def update_data_link(
644644

645645
@app.command("browse")
646646
def browse_data_link(
647-
data_link_id: Annotated[
647+
data_link: Annotated[
648648
str,
649-
typer.Option("-i", "--id", help="Data link ID."),
649+
typer.Argument(help="Data link ID or name."),
650650
],
651651
workspace: Annotated[
652652
str | None,
@@ -684,6 +684,9 @@ def browse_data_link(
684684
if credentials:
685685
cred_id = _resolve_credentials_id(client, workspace_id, credentials)
686686

687+
# Resolve data link ID or name to ID
688+
data_link_id = _resolve_data_link_id_or_name(client, workspace_id, data_link, cred_id)
689+
687690
# Build request params for describe
688691
describe_params: dict[str, Any] = {}
689692
if workspace_id:
@@ -693,7 +696,7 @@ def browse_data_link(
693696

694697
# Get data link details
695698
describe_response = client.get(f"/data-links/{data_link_id}", params=describe_params)
696-
data_link = describe_response.get("dataLink", describe_response)
699+
data_link_info = describe_response.get("dataLink", describe_response)
697700

698701
# Build browse params
699702
browse_params: dict[str, Any] = {}
@@ -717,7 +720,7 @@ def browse_data_link(
717720
browse_response = client.get(browse_url, params=browse_params)
718721

719722
result = DataLinkContentList(
720-
data_link=data_link,
723+
data_link=data_link_info,
721724
path=path,
722725
objects=browse_response.get("objects", []),
723726
next_page_token=browse_response.get("nextPageToken"),
@@ -821,6 +824,59 @@ def _explore_data_link_tree(
821824
return response.get("items", [])
822825

823826

827+
def _resolve_data_link_id_or_name(
828+
client: SeqeraClient,
829+
workspace_id: int | None,
830+
id_or_name: str,
831+
credentials_id: str | None = None,
832+
) -> str:
833+
"""Resolve data link ID or name to data link ID.
834+
835+
First tries to use the value as an ID directly, then falls back to exact name match.
836+
"""
837+
# First, try to use it as an ID directly
838+
params: dict[str, Any] = {}
839+
if workspace_id:
840+
params["workspaceId"] = workspace_id
841+
if credentials_id:
842+
params["credentialsId"] = credentials_id
843+
844+
try:
845+
response = client.get(f"/data-links/{id_or_name}", params=params)
846+
data_link = response.get("dataLink", response)
847+
if data_link and data_link.get("id"):
848+
return data_link.get("id")
849+
except Exception:
850+
pass # Not a valid ID, try searching by name
851+
852+
# Search by name
853+
search_params = {**params, "search": id_or_name}
854+
response = client.get("/data-links", params=search_params)
855+
data_links = response.get("dataLinks", [])
856+
857+
# Only accept exact name matches
858+
exact_matches = [dl for dl in data_links if dl.get("name") == id_or_name]
859+
if len(exact_matches) == 1:
860+
return exact_matches[0].get("id")
861+
862+
if len(exact_matches) > 1:
863+
output_error(
864+
f"Multiple data links found with name '{id_or_name}'. "
865+
"Please use the data link ID instead."
866+
)
867+
raise typer.Exit(1)
868+
869+
# No exact match found - suggest partial matches if any
870+
if data_links:
871+
suggestions = [dl.get("name") for dl in data_links[:5]] # Limit to 5 suggestions
872+
suggestion_str = ", ".join(f"'{s}'" for s in suggestions)
873+
output_error(f"Data link '{id_or_name}' not found. " f"Did you mean: {suggestion_str}?")
874+
else:
875+
output_error(f"Data link '{id_or_name}' not found")
876+
877+
raise typer.Exit(1)
878+
879+
824880
def _resolve_data_link_id(
825881
client: SeqeraClient,
826882
workspace_id: int | None,

src/seqera/utils/output.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,22 @@ def output_error(message: str) -> None:
8888
"""
8989
Output error message to stderr.
9090
91+
Formats the error in a panel matching the rich-click/typer style.
92+
9193
Args:
9294
message: Error message
9395
"""
96+
from rich.panel import Panel
97+
9498
error_console = Console(stderr=True)
95-
error_console.print(f"[bold red]Error:[/bold red] {message}")
99+
error_console.print(
100+
Panel(
101+
message,
102+
title="Error",
103+
title_align="left",
104+
border_style="red",
105+
)
106+
)
96107

97108

98109
def format_response(data: Any, format: OutputFormat) -> None:

0 commit comments

Comments
 (0)