fix(lab): стабилизировать нативный RAV004 replay
This commit is contained in:
@@ -12,10 +12,10 @@ import zipfile
|
||||
from collections.abc import Callable
|
||||
from functools import lru_cache
|
||||
from pathlib import Path, PurePosixPath
|
||||
from typing import Any, Final, Literal
|
||||
from typing import Annotated, Any, Final, Literal
|
||||
|
||||
import numpy as np
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from fastapi import APIRouter, HTTPException, Query
|
||||
from fastapi.concurrency import run_in_threadpool
|
||||
from fastapi.responses import FileResponse, JSONResponse, Response
|
||||
from PIL import Image
|
||||
@@ -298,10 +298,11 @@ def _build_vegetation_lab_router(
|
||||
},
|
||||
)
|
||||
|
||||
@router.post("/{result_id}/canonical-overlay.rrd")
|
||||
async def get_canonical_rerun_overlay(
|
||||
async def canonical_rerun_overlay_response(
|
||||
result_id: str,
|
||||
request: CanonicalLabRerunRequest,
|
||||
*,
|
||||
expected_base_generation_sha256: str | None = None,
|
||||
) -> FileResponse:
|
||||
"""Project LAB-only evidence into the base recording's native clock."""
|
||||
|
||||
@@ -319,6 +320,11 @@ def _build_vegetation_lab_router(
|
||||
if recording is None:
|
||||
raise HTTPException(status_code=409, detail="Canonical spatial recording is not ready")
|
||||
recording_path, generation_sha256 = recording
|
||||
if (
|
||||
expected_base_generation_sha256 is not None
|
||||
and expected_base_generation_sha256 != generation_sha256
|
||||
):
|
||||
raise HTTPException(status_code=412, detail="Canonical recording generation changed")
|
||||
try:
|
||||
expected_recording_id = await run_in_threadpool(
|
||||
canonical_recording_id,
|
||||
@@ -353,6 +359,43 @@ def _build_vegetation_lab_router(
|
||||
},
|
||||
)
|
||||
|
||||
@router.post("/{result_id}/canonical-overlay.rrd")
|
||||
async def get_canonical_rerun_overlay(
|
||||
result_id: str,
|
||||
request: CanonicalLabRerunRequest,
|
||||
) -> FileResponse:
|
||||
"""Resolve the sealed sidecar for bounded non-viewer consumers."""
|
||||
|
||||
return await canonical_rerun_overlay_response(result_id, request)
|
||||
|
||||
@router.get("/{result_id}/canonical-overlay.rrd")
|
||||
async def stream_canonical_rerun_overlay(
|
||||
result_id: str,
|
||||
application_id: Annotated[
|
||||
Literal["nodedc_mission_core_recorded"],
|
||||
Query(),
|
||||
],
|
||||
recording_id: Annotated[
|
||||
str,
|
||||
Query(
|
||||
min_length=1,
|
||||
max_length=128,
|
||||
pattern=r"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$",
|
||||
),
|
||||
],
|
||||
generation: Annotated[str, Query(pattern=r"^[a-f0-9]{64}$")],
|
||||
) -> FileResponse:
|
||||
"""Stream one immutable LAB sidecar through Rerun's native HTTP receiver."""
|
||||
|
||||
return await canonical_rerun_overlay_response(
|
||||
result_id,
|
||||
CanonicalLabRerunRequest(
|
||||
application_id=application_id,
|
||||
recording_id=recording_id,
|
||||
),
|
||||
expected_base_generation_sha256=generation,
|
||||
)
|
||||
|
||||
@router.get("/{result_id}/timeline")
|
||||
def get_canonical_route_timeline(result_id: str) -> dict[str, object]:
|
||||
candidate = _resolve_candidate(root_provider, definition, result_id)
|
||||
|
||||
Reference in New Issue
Block a user