Skip to content

Commit 3b736f8

Browse files
authored
Revert "chore: Use SAMIA run artifact file endpoint to download artifacts (#507)" (#514)
This reverts commit d552c89.
1 parent d552c89 commit 3b736f8

8 files changed

Lines changed: 59 additions & 1270 deletions

File tree

src/aignostics/application/_download.py

Lines changed: 2 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import requests
1111
from loguru import logger
1212

13-
from aignostics.platform import ItemOutput, ItemState, OutputArtifactElement, Run, generate_signed_url
13+
from aignostics.platform import ItemOutput, ItemState, Run, generate_signed_url
1414
from aignostics.utils import sanitize_path_component
1515

1616
from ._models import DownloadProgress, DownloadProgressState
@@ -146,44 +146,6 @@ def update_progress(
146146
download_progress_queue.put_nowait(progress)
147147

148148

149-
def _resolve_artifact_url(
150-
artifact: OutputArtifactElement,
151-
run_id: str,
152-
get_artifact_download_url: Callable[[str, str], str] | None,
153-
) -> str | None:
154-
"""Resolve the download URL for an artifact.
155-
156-
Tries the new file endpoint first (via get_artifact_download_url), then falls back to
157-
the deprecated download_url field on the artifact if the endpoint fails.
158-
159-
Args:
160-
artifact: The artifact object with optional output_artifact_id and download_url.
161-
run_id: The run ID, passed to get_artifact_download_url.
162-
get_artifact_download_url: Callable for the new endpoint, or None to skip.
163-
164-
Returns:
165-
str | None: The resolved download URL, or None if unavailable.
166-
167-
Raises:
168-
Exception: Re-raises if the new endpoint fails and no fallback download_url exists.
169-
"""
170-
if get_artifact_download_url and artifact.output_artifact_id:
171-
try:
172-
return get_artifact_download_url(run_id, artifact.output_artifact_id)
173-
except Exception as e:
174-
fallback_url: str | None = getattr(artifact, "download_url", None)
175-
if fallback_url:
176-
logger.warning(
177-
"Failed to resolve download URL via file endpoint for artifact {} ({}). "
178-
"Falling back to deprecated download_url field.",
179-
artifact.output_artifact_id,
180-
e,
181-
)
182-
return fallback_url
183-
raise
184-
return getattr(artifact, "download_url", None)
185-
186-
187149
def download_available_items( # noqa: PLR0913, PLR0917
188150
progress: DownloadProgress,
189151
application_run: Run,
@@ -192,7 +154,6 @@ def download_available_items( # noqa: PLR0913, PLR0917
192154
create_subdirectory_per_item: bool = False,
193155
download_progress_queue: Any | None = None, # noqa: ANN401
194156
download_progress_callable: Callable | None = None, # type: ignore[type-arg]
195-
get_artifact_download_url: Callable[[str, str], str] | None = None,
196157
) -> None:
197158
"""Download items that are available and not yet downloaded.
198159
@@ -204,9 +165,6 @@ def download_available_items( # noqa: PLR0913, PLR0917
204165
create_subdirectory_per_item (bool): Whether to create a subdirectory for each item.
205166
download_progress_queue (Queue | None): Queue for GUI progress updates.
206167
download_progress_callable (Callable | None): Callback for CLI progress updates.
207-
get_artifact_download_url (Callable[[str, str], str] | None): Callback that takes
208-
(run_id, artifact_id) and returns a presigned download URL. If None, falls back
209-
to artifact.download_url (deprecated).
210168
"""
211169
items = list(application_run.results())
212170
progress.item_count = len(items)
@@ -243,16 +201,9 @@ def download_available_items( # noqa: PLR0913, PLR0917
243201
progress.artifact = artifact
244202
update_progress(progress, download_progress_callable, download_progress_queue)
245203

246-
# Resolve artifact download URL via the new file endpoint, with fallback
247-
artifact_url = _resolve_artifact_url(artifact, application_run.run_id, get_artifact_download_url)
248-
if not artifact_url:
249-
logger.warning("No download URL available for artifact {}", artifact.output_artifact_id)
250-
continue
251-
252204
download_item_artifact(
253205
progress,
254206
artifact,
255-
artifact_url,
256207
item_directory,
257208
item.external_id if not create_subdirectory_per_item else "",
258209
download_progress_queue,
@@ -265,7 +216,6 @@ def download_available_items( # noqa: PLR0913, PLR0917
265216
def download_item_artifact( # noqa: PLR0913, PLR0917
266217
progress: DownloadProgress,
267218
artifact: Any, # noqa: ANN401
268-
artifact_download_url: str,
269219
destination_directory: Path,
270220
prefix: str = "",
271221
download_progress_queue: Any | None = None, # noqa: ANN401
@@ -276,7 +226,6 @@ def download_item_artifact( # noqa: PLR0913, PLR0917
276226
Args:
277227
progress (DownloadProgress): Progress tracking object for GUI or CLI updates.
278228
artifact (Any): The artifact to download.
279-
artifact_download_url (str): The presigned URL to download the artifact from.
280229
destination_directory (Path): Directory to save the file.
281230
prefix (str): Prefix for the file name, if needed.
282231
download_progress_queue (Queue | None): Queue for GUI progress updates.
@@ -311,7 +260,7 @@ def download_item_artifact( # noqa: PLR0913, PLR0917
311260

312261
download_file_with_progress(
313262
progress,
314-
artifact_download_url,
263+
artifact.download_url,
315264
artifact_path,
316265
metadata_checksum,
317266
download_progress_queue,

src/aignostics/application/_gui/_page_application_run_describe.py

Lines changed: 25 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@
1414
ui, # noq
1515
)
1616
from nicegui import run as nicegui_run
17-
from nicegui.events import ClickEventArguments
1817

19-
from aignostics.platform import ItemOutput, ItemResult, ItemState, Run, RunState
18+
from aignostics.platform import ItemOutput, ItemResult, ItemState, RunState
2019
from aignostics.third_party.showinfm.showinfm import show_in_file_manager
2120
from aignostics.utils import GUILocalFilePicker, get_user_data_directory
2221

@@ -339,9 +338,9 @@ async def start_download() -> None:
339338

340339
# Activate the timer now that download is starting
341340
progress_timer.activate()
342-
download_button.disable()
343-
download_button.props(add="loading")
344341
try:
342+
download_button.disable()
343+
download_button.props(add="loading")
345344
results_folder = await nicegui_run.cpu_bound(
346345
Service.application_run_download_static,
347346
run_id=run.run_id,
@@ -365,24 +364,19 @@ async def start_download() -> None:
365364
else:
366365
ui.notify("Download completed.", type="positive")
367366
show_in_file_manager(str(results_folder))
368-
except Exception as e:
369-
logger.exception(
370-
"Download failed for run {} (qupath_project={}, marimo={}, folder={})",
371-
run.run_id,
372-
current_qupath_project,
373-
current_marimo,
374-
current_folder,
375-
)
367+
except ValueError as e:
376368
ui.notify(f"Download failed: {e}", type="negative", multi_line=True)
377-
finally:
378369
progress_timer.deactivate()
379370
progress_state["queue"] = None
380-
download_button.props(remove="loading")
381-
download_button.enable()
382-
download_item_status.set_visibility(False)
383-
download_item_progress.set_visibility(False)
384-
download_artifact_status.set_visibility(False)
385-
download_artifact_progress.set_visibility(False)
371+
return
372+
progress_timer.deactivate()
373+
progress_state["queue"] = None
374+
download_button.props(remove="loading")
375+
download_button.enable()
376+
download_item_status.set_visibility(False)
377+
download_item_progress.set_visibility(False)
378+
download_artifact_status.set_visibility(False)
379+
download_artifact_progress.set_visibility(False)
386380

387381
ui.separator()
388382
with ui.row(align_items="end").classes("w-full justify-end"):
@@ -787,85 +781,29 @@ def render_item(item: ItemResult) -> None: # noqa: C901, PLR0912, PLR0915
787781
icon=mime_type_to_icon(mime_type),
788782
group="artifacts",
789783
).classes("w-full"):
790-
if artifact.output_artifact_id:
791-
artifact_id = artifact.output_artifact_id
784+
if artifact.download_url:
785+
url = artifact.download_url
792786
title = artifact.name
793787
metadata = artifact.metadata
794-
795788
with ui.button_group():
796789
if mime_type == "image/tiff":
797-
preview_button = ui.button(
790+
ui.button(
798791
"Preview",
799792
icon=mime_type_to_icon(mime_type),
793+
on_click=lambda _, url=url, title=title: tiff_dialog_open(title, url),
800794
)
801-
802-
async def _preview_tiff(
803-
_: ClickEventArguments,
804-
aid: str = artifact_id,
805-
t: str = title,
806-
_run: Run = run,
807-
_btn: ui.button = preview_button,
808-
) -> None:
809-
try:
810-
_btn.props(add="loading")
811-
url = await nicegui_run.io_bound(
812-
_run.get_artifact_download_url, aid
813-
)
814-
tiff_dialog_open(t, url)
815-
except Exception as e:
816-
ui.notify(f"Failed to resolve preview URL: {e}", type="warning")
817-
finally:
818-
_btn.props(remove="loading")
819-
820-
preview_button.on_click(_preview_tiff)
821-
822795
if mime_type == "text/csv":
823-
preview_button = ui.button(
796+
ui.button(
824797
"Preview",
825798
icon=mime_type_to_icon(mime_type),
799+
on_click=lambda _, url=url, title=title: csv_dialog_open(title, url),
800+
)
801+
if url:
802+
ui.button(
803+
text="Download",
804+
icon="cloud_download",
805+
on_click=lambda _, url=url: webbrowser.open(url),
826806
)
827-
828-
async def _preview_csv(
829-
_: ClickEventArguments,
830-
aid: str = artifact_id,
831-
t: str = title,
832-
_run: Run = run,
833-
_btn: ui.button = preview_button,
834-
) -> None:
835-
try:
836-
_btn.props(add="loading")
837-
url = await nicegui_run.io_bound(
838-
_run.get_artifact_download_url, aid
839-
)
840-
csv_dialog_open(t, url)
841-
except Exception as e:
842-
ui.notify(f"Failed to resolve preview URL: {e}", type="warning")
843-
finally:
844-
_btn.props(remove="loading")
845-
846-
preview_button.on_click(_preview_csv)
847-
848-
artifact_dl_button = ui.button(
849-
text="Download",
850-
icon="cloud_download",
851-
)
852-
853-
async def _download_artifact(
854-
_: ClickEventArguments,
855-
aid: str = artifact_id,
856-
_run: Run = run,
857-
_btn: ui.button = artifact_dl_button,
858-
) -> None:
859-
try:
860-
_btn.props(add="loading")
861-
url = await nicegui_run.io_bound(_run.get_artifact_download_url, aid)
862-
webbrowser.open(url)
863-
except Exception as e:
864-
ui.notify(f"Failed to resolve download URL: {e}", type="warning")
865-
finally:
866-
_btn.props(remove="loading")
867-
868-
artifact_dl_button.on_click(_download_artifact)
869807
if metadata:
870808
ui.button(
871809
text="Schema",

src/aignostics/application/_service.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,19 +1483,6 @@ def update_qupath_add_input_progress(qupath_add_input_progress: QuPathAddProgres
14831483
update_progress(progress, download_progress_callable, download_progress_queue)
14841484

14851485
downloaded_items: set[str] = set() # Track downloaded items to avoid re-downloading
1486-
1487-
def _get_artifact_download_url(run_id: str, artifact_id: str) -> str:
1488-
"""Resolve artifact download URL via the new API endpoint.
1489-
1490-
Args:
1491-
run_id (str): The run ID.
1492-
artifact_id (str): The artifact ID.
1493-
1494-
Returns:
1495-
str: The presigned download URL.
1496-
"""
1497-
return self._get_platform_client().run(run_id).get_artifact_download_url(artifact_id)
1498-
14991486
while True:
15001487
run_details = application_run.details() # (Re)load current run details
15011488
progress.run = run_details
@@ -1509,7 +1496,6 @@ def _get_artifact_download_url(run_id: str, artifact_id: str) -> str:
15091496
create_subdirectory_per_item,
15101497
download_progress_queue,
15111498
download_progress_callable,
1512-
get_artifact_download_url=_get_artifact_download_url,
15131499
)
15141500

15151501
if run_details.state == RunState.TERMINATED:

src/aignostics/platform/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
get_mime_type_for_artifact,
9292
mime_type_to_file_ending,
9393
)
94-
from .resources.runs import LIST_APPLICATION_RUNS_MAX_PAGE_SIZE, LIST_APPLICATION_RUNS_MIN_PAGE_SIZE, Artifact, Run
94+
from .resources.runs import LIST_APPLICATION_RUNS_MAX_PAGE_SIZE, LIST_APPLICATION_RUNS_MIN_PAGE_SIZE, Run
9595

9696
__all__ = [
9797
"API_ROOT_DEV",
@@ -146,7 +146,6 @@
146146
"Application",
147147
"ApplicationSummary",
148148
"ApplicationVersion",
149-
"Artifact",
150149
"Client",
151150
"InputArtifact",
152151
"InputArtifactData",

0 commit comments

Comments
 (0)