diff --git a/api_routes.py b/api_routes.py index 40815ab..69d984d 100644 --- a/api_routes.py +++ b/api_routes.py @@ -9,6 +9,7 @@ from pathlib import Path from typing import Any from fastapi import HTTPException, Query +from fastapi.responses import FileResponse from nicegui import app from db import ProjectDB @@ -30,6 +31,7 @@ def register_api_routes(db: ProjectDB) -> None: app.add_api_route("/api/projects/{name}/files/{file_name}/sequences", _list_sequences, methods=["GET"]) app.add_api_route("/api/projects/{name}/files/{file_name}/data", _get_data, methods=["GET"]) app.add_api_route("/api/projects/{name}/files/{file_name}/keys", _get_keys, methods=["GET"]) + app.add_api_route("/api/image-preview", _serve_image, methods=["GET"]) def _get_db() -> ProjectDB: @@ -102,3 +104,10 @@ def _get_keys(name: str, file_name: str, seq: int = Query(default=1)) -> dict[st logger.info("API _get_keys %s/%s seq=%d (%d keys): %.3fs", name, file_name, seq, len(keys), time.perf_counter() - t0) return {"keys": keys, "types": types, "total_sequences": total} + + +def _serve_image(path: str = Query(...)) -> FileResponse: + p = Path(path) + if not p.exists() or not p.is_file(): + raise HTTPException(status_code=404, detail="Image not found") + return FileResponse(str(p)) diff --git a/tab_batch_ng.py b/tab_batch_ng.py index b4a0398..40fc8dd 100644 --- a/tab_batch_ng.py +++ b/tab_batch_ng.py @@ -6,6 +6,7 @@ import math import random import time from pathlib import Path +from urllib.parse import quote from nicegui import ui @@ -571,9 +572,10 @@ def _render_sequence_card(i, seq, batch_list, data, file_path, state, img_path = Path(seq.get(img_key, '')) if seq.get(img_key) else None if (img_path and img_path.exists() and img_path.suffix.lower() in IMAGE_EXTENSIONS): + img_url = f'/api/image-preview?path={quote(str(img_path))}' with ui.dialog() as img_dlg, ui.card().style('max-width:90vw'): - ui.image(str(img_path)).style('max-width:80vw; max-height:80vh') - ui.image(str(img_path)).style( + ui.image(img_url).style('max-width:80vw; max-height:80vh') + ui.image(img_url).style( 'width:36px; height:36px; object-fit:cover;' ' border-radius:4px; cursor:pointer; flex-shrink:0' ).on('click', img_dlg.open)