|
4 | 4 | from typing import Dict, List, Optional |
5 | 5 |
|
6 | 6 | from fastapi import APIRouter, Depends, Request |
| 7 | +from fastapi.responses import FileResponse, HTMLResponse |
7 | 8 | from pydantic import BaseModel |
8 | 9 | from sqlalchemy import func |
9 | 10 | from sqlmodel import select |
| 11 | +from werkzeug.utils import secure_filename |
10 | 12 |
|
11 | 13 | import murfey.server.ispyb |
12 | | -from murfey.server import sanitise, templates |
| 14 | +import murfey.server.websocket as ws |
| 15 | +from murfey.server import ( |
| 16 | + _transport_object, |
| 17 | + get_hostname, |
| 18 | + get_microscope, |
| 19 | + sanitise, |
| 20 | + templates, |
| 21 | +) |
13 | 22 | from murfey.server.api.auth import MurfeySessionID, validate_token |
14 | 23 | from murfey.server.api.shared import get_foil_hole as _get_foil_hole |
15 | 24 | from murfey.server.api.shared import ( |
|
51 | 60 | ) |
52 | 61 |
|
53 | 62 |
|
| 63 | +# This will be the homepage for a given microscope. |
| 64 | +@router.get("/", response_class=HTMLResponse) |
| 65 | +async def root(request: Request): |
| 66 | + return templates.TemplateResponse( |
| 67 | + request=request, |
| 68 | + name="home.html", |
| 69 | + context={ |
| 70 | + "hostname": get_hostname(), |
| 71 | + "microscope": get_microscope(), |
| 72 | + "version": murfey.__version__, |
| 73 | + }, |
| 74 | + ) |
| 75 | + |
| 76 | + |
| 77 | +@router.get("/health/") |
| 78 | +def health_check(db=murfey.server.ispyb.DB): |
| 79 | + conn = db.connection() |
| 80 | + conn.close() |
| 81 | + return { |
| 82 | + "ispyb_connection": True, |
| 83 | + "rabbitmq_connection": _transport_object.transport.is_connected(), |
| 84 | + } |
| 85 | + |
| 86 | + |
| 87 | +@router.get("/connections/") |
| 88 | +def connections_check(): |
| 89 | + return {"connections": list(ws.manager.active_connections.keys())} |
| 90 | + |
| 91 | + |
54 | 92 | @router.get("/instruments/{instrument_name}/machine") |
55 | 93 | def machine_info_by_instrument(instrument_name: str) -> Optional[MachineConfig]: |
56 | 94 | return get_machine_config_for_instrument(instrument_name) |
@@ -153,23 +191,6 @@ def remove_session(session_id: MurfeySessionID, db=murfey_db): |
153 | 191 | remove_session_by_id(session_id, db) |
154 | 192 |
|
155 | 193 |
|
156 | | -@router.get("/sessions/{session_id}/upstream_visits") |
157 | | -async def find_upstream_visits(session_id: MurfeySessionID, db=murfey_db): |
158 | | - murfey_session = db.exec(select(Session).where(Session.id == session_id)).one() |
159 | | - visit_name = murfey_session.visit |
160 | | - instrument_name = murfey_session.instrument_name |
161 | | - machine_config = get_machine_config(instrument_name=instrument_name)[ |
162 | | - instrument_name |
163 | | - ] |
164 | | - upstream_visits = {} |
165 | | - # Iterates through provided upstream directories |
166 | | - for p in machine_config.upstream_data_directories: |
167 | | - # Looks for visit name in file path |
168 | | - for v in Path(p).glob(f"{visit_name.split('-')[0]}-*"): |
169 | | - upstream_visits[v.name] = v / machine_config.processed_directory_name |
170 | | - return upstream_visits |
171 | | - |
172 | | - |
173 | 194 | @router.get("/instruments/{instrument_name}/visits/{visit_name}/sessions") |
174 | 195 | def get_sessions_with_visit( |
175 | 196 | instrument_name: str, visit_name: str, db=murfey_db |
@@ -373,3 +394,89 @@ def get_tilts( |
373 | 394 | else: |
374 | 395 | tilts[el[1].rsync_source] = [el[2].movie_path] |
375 | 396 | return tilts |
| 397 | + |
| 398 | + |
| 399 | +correlative_router = APIRouter( |
| 400 | + prefix="/session_info/correlative", |
| 401 | + dependencies=[Depends(validate_token)], |
| 402 | + tags=["session info for correlative imaging"], |
| 403 | +) |
| 404 | + |
| 405 | + |
| 406 | +@correlative_router.get("/sessions/{session_id}/upstream_visits") |
| 407 | +async def find_upstream_visits(session_id: MurfeySessionID, db=murfey_db): |
| 408 | + murfey_session = db.exec(select(Session).where(Session.id == session_id)).one() |
| 409 | + visit_name = murfey_session.visit |
| 410 | + instrument_name = murfey_session.instrument_name |
| 411 | + machine_config = get_machine_config(instrument_name=instrument_name)[ |
| 412 | + instrument_name |
| 413 | + ] |
| 414 | + upstream_visits = {} |
| 415 | + # Iterates through provided upstream directories |
| 416 | + for p in machine_config.upstream_data_directories: |
| 417 | + # Looks for visit name in file path |
| 418 | + for v in Path(p).glob(f"{visit_name.split('-')[0]}-*"): |
| 419 | + upstream_visits[v.name] = v / machine_config.processed_directory_name |
| 420 | + return upstream_visits |
| 421 | + |
| 422 | + |
| 423 | +def _get_upstream_tiff_dirs(visit_name: str, instrument_name: str) -> List[Path]: |
| 424 | + tiff_dirs = [] |
| 425 | + machine_config = get_machine_config(instrument_name=instrument_name)[ |
| 426 | + instrument_name |
| 427 | + ] |
| 428 | + for directory_name in machine_config.upstream_data_tiff_locations: |
| 429 | + for p in machine_config.upstream_data_directories: |
| 430 | + if (Path(p) / secure_filename(visit_name)).is_dir(): |
| 431 | + processed_dir = Path(p) / secure_filename(visit_name) / directory_name |
| 432 | + tiff_dirs.append(processed_dir) |
| 433 | + break |
| 434 | + if not tiff_dirs: |
| 435 | + logger.warning( |
| 436 | + f"No candidate directory found for upstream download from visit {sanitise(visit_name)}" |
| 437 | + ) |
| 438 | + return tiff_dirs |
| 439 | + |
| 440 | + |
| 441 | +@correlative_router.get("/visits/{visit_name}/{session_id}/upstream_tiff_paths") |
| 442 | +async def gather_upstream_tiffs(visit_name: str, session_id: int, db=murfey_db): |
| 443 | + """ |
| 444 | + Looks for TIFF files associated with the current session in the permitted storage |
| 445 | + servers, and returns their relative file paths as a list. |
| 446 | + """ |
| 447 | + instrument_name = ( |
| 448 | + db.exec(select(Session).where(Session.id == session_id)).one().instrument_name |
| 449 | + ) |
| 450 | + upstream_tiff_paths = [] |
| 451 | + tiff_dirs = _get_upstream_tiff_dirs(visit_name, instrument_name) |
| 452 | + if not tiff_dirs: |
| 453 | + return None |
| 454 | + for tiff_dir in tiff_dirs: |
| 455 | + for f in tiff_dir.glob("**/*.tiff"): |
| 456 | + upstream_tiff_paths.append(str(f.relative_to(tiff_dir))) |
| 457 | + for f in tiff_dir.glob("**/*.tif"): |
| 458 | + upstream_tiff_paths.append(str(f.relative_to(tiff_dir))) |
| 459 | + return upstream_tiff_paths |
| 460 | + |
| 461 | + |
| 462 | +@correlative_router.get( |
| 463 | + "/visits/{visit_name}/{session_id}/upstream_tiff/{tiff_path:path}" |
| 464 | +) |
| 465 | +async def get_tiff(visit_name: str, session_id: int, tiff_path: str, db=murfey_db): |
| 466 | + instrument_name = ( |
| 467 | + db.exec(select(Session).where(Session.id == session_id)).one().instrument_name |
| 468 | + ) |
| 469 | + tiff_dirs = _get_upstream_tiff_dirs(visit_name, instrument_name) |
| 470 | + if not tiff_dirs: |
| 471 | + return None |
| 472 | + |
| 473 | + tiff_path = "/".join(secure_filename(p) for p in tiff_path.split("/")) |
| 474 | + for tiff_dir in tiff_dirs: |
| 475 | + test_path = tiff_dir / tiff_path |
| 476 | + if test_path.is_file(): |
| 477 | + break |
| 478 | + else: |
| 479 | + logger.warning(f"TIFF {tiff_path} not found") |
| 480 | + return None |
| 481 | + |
| 482 | + return FileResponse(path=test_path) |
0 commit comments