fix(lab): keep full route result indexable

This commit is contained in:
DCCONSTRUCTIONS
2026-08-29 13:54:40 +03:00
parent 9dec37a8a9
commit 0a0cde7b0e
5 changed files with 189 additions and 23 deletions
@@ -214,6 +214,54 @@ def _build_vegetation_lab_router(
raise HTTPException(status_code=404, detail="Full-route semantic mask not found")
return _zip_mask_response(candidate.joinpath(*relative.parts), sequence)
@router.get("/{result_id}/route-timeline")
def get_full_route_timeline(result_id: str) -> FileResponse:
candidate = _resolve_candidate(root_provider, definition, result_id)
manifest = _read_verified(candidate, definition)
route = manifest.get("route_full_review")
timeline = route.get("timeline") if isinstance(route, dict) else None
relative_text = timeline.get("path") if isinstance(timeline, dict) else None
frame_count = timeline.get("frame_count") if isinstance(timeline, dict) else None
byte_length = timeline.get("byte_length") if isinstance(timeline, dict) else None
sha256 = timeline.get("sha256") if isinstance(timeline, dict) else None
if (
not isinstance(relative_text, str)
or frame_count != route.get("frame_count")
or byte_length != frame_count * 8
or not isinstance(sha256, str)
or len(sha256) != 64
):
raise HTTPException(status_code=404, detail="Full-route timeline not found")
relative = PurePosixPath(relative_text)
artifacts = manifest.get("artifacts")
if (
relative.is_absolute()
or str(relative) != relative_text
or any(part in {"", ".", ".."} for part in relative.parts)
or not isinstance(artifacts, list)
or not any(
isinstance(item, dict)
and item.get("path") == relative_text
and item.get("byte_length") == byte_length
and item.get("sha256") == sha256
and item.get("media_type") == "application/octet-stream"
for item in artifacts
)
):
raise HTTPException(status_code=404, detail="Full-route timeline not found")
path = candidate.joinpath(*relative.parts)
if not path.is_file() or path.is_symlink() or path.stat().st_size != byte_length:
raise HTTPException(status_code=404, detail="Full-route timeline not found")
return FileResponse(
path,
media_type="application/octet-stream",
headers={
"Cache-Control": "private, max-age=31536000, immutable",
"ETag": f'"{sha256}"',
"X-Content-Type-Options": "nosniff",
},
)
return router