LTX-2.5-diffusers-mini / ltx /probe_artifacts.py
John6666's picture
Upload 39 files
e8b6587 verified
Raw
History Blame Contribute Delete
5.46 kB
from __future__ import annotations
import json
import os
import zipfile
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Callable, Iterable
@dataclass(frozen=True)
class ProbeMember:
"""One file included in a returned Probe bundle."""
role: str
path: Path
arcname: str | None = None
required: bool = True
def _normalized_members(members: Iterable[ProbeMember]) -> list[ProbeMember]:
out: list[ProbeMember] = []
seen_arcnames: set[str] = set()
for member in members:
path = Path(member.path)
if not path.exists():
if member.required:
raise FileNotFoundError(f"Required Probe member is missing: {path}")
continue
if not path.is_file():
raise ValueError(f"Probe member must be a file: {path}")
arcname = str(member.arcname or path.name).strip()
if not arcname or Path(arcname).is_absolute() or ".." in Path(arcname).parts:
raise ValueError(f"Unsafe Probe archive name: {arcname!r}")
if arcname in seen_arcnames:
raise ValueError(f"Duplicate Probe archive name: {arcname}")
seen_arcnames.add(arcname)
out.append(ProbeMember(role=str(member.role), path=path, arcname=arcname, required=member.required))
return out
def build_probe_zip(
output_path: str | Path,
*,
candidate_id: str,
request_id: str,
status: str,
members: Iterable[ProbeMember],
sha256_file: Callable[[str | Path], str],
metadata: dict[str, Any] | None = None,
) -> Path:
"""Build one self-describing Probe ZIP without leaking absolute runtime paths."""
output = Path(output_path)
output.parent.mkdir(parents=True, exist_ok=True)
normalized = _normalized_members(members)
manifest_files = []
for member in normalized:
assert member.arcname is not None
manifest_files.append(
{
"role": member.role,
"name": member.arcname,
"size_bytes": int(member.path.stat().st_size),
"sha256": sha256_file(member.path),
}
)
manifest = {
"schema_version": "ltx25-probe-bundle-v1",
"candidate_id": str(candidate_id),
"request_id": str(request_id),
"status": str(status).upper(),
"created_utc": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
"files": manifest_files,
"metadata": dict(metadata or {}),
}
tmp = output.with_name(f".{output.name}.{os.getpid()}.tmp")
try:
with zipfile.ZipFile(tmp, mode="w", compression=zipfile.ZIP_DEFLATED, compresslevel=6) as archive:
archive.writestr("probe_manifest.json", json.dumps(manifest, indent=2, sort_keys=True) + "\n")
for member in normalized:
assert member.arcname is not None
archive.write(member.path, arcname=member.arcname)
tmp.replace(output)
finally:
try:
tmp.unlink(missing_ok=True)
except Exception:
pass
return output
def build_request_probe(
paths: Any,
*,
candidate_id: str,
status: str,
sha256_file: Callable[[str | Path], str],
include_run_info: bool = True,
include_diagnostics: bool = True,
include_log: bool = True,
extra_members: Iterable[ProbeMember] = (),
metadata: dict[str, Any] | None = None,
) -> Path:
"""Bundle the ordinary request evidence files owned by one RequestPaths object."""
members: list[ProbeMember] = []
if include_run_info:
members.append(ProbeMember("run_info", Path(paths.run_info), required=False))
if include_diagnostics:
members.append(ProbeMember("diagnostics", Path(paths.diagnostics), required=False))
if include_log:
members.append(ProbeMember("request_log", Path(paths.log), required=False))
members.extend(extra_members)
return build_probe_zip(
paths.probe,
candidate_id=candidate_id,
request_id=paths.request_id,
status=status,
members=members,
sha256_file=sha256_file,
metadata=metadata,
)
def append_probe_path(existing: Any, new_path: str | Path, *, limit: int | None = None) -> list[str]:
"""Append one Probe bundle path while preserving existing gr.File-style history."""
values: list[str] = []
if isinstance(existing, (list, tuple)):
values.extend(str(item) for item in existing if item)
elif existing:
values.append(str(existing))
new_value = str(new_path)
values = [item for item in values if item != new_value]
values.append(new_value)
if limit is not None and int(limit) > 0:
values = values[-int(limit) :]
return values
def list_session_probe_paths(worker_root: str | Path, session_id: str, *, limit: int | None = None) -> list[str]:
"""Return existing request Probe ZIPs for one UUID session, oldest-to-newest."""
session_root = Path(worker_root) / str(session_id or "").strip().lower()
if not session_root.is_dir():
return []
found = [path for path in session_root.glob("*/ltx25_probe_*.zip") if path.is_file()]
found.sort(key=lambda path: (path.stat().st_mtime_ns, path.name))
values = [str(path) for path in found]
if limit is not None and int(limit) > 0:
values = values[-int(limit) :]
return values