CMVR-AI-ANALYSIS/app/profile_store.py

71 lines
2.3 KiB
Python

import json
from dataclasses import dataclass
from pathlib import Path
from typing import Any
from app.config import settings
@dataclass(frozen=True)
class Profile:
code: str
analysis_type: str
directory: Path
config: dict[str, Any]
class ProfileStore:
def __init__(self) -> None:
self._profiles: dict[str, Profile] = {}
def reload(self) -> None:
profiles: dict[str, Profile] = {}
if settings.profiles_dir.exists():
for path in settings.profiles_dir.rglob("profile.json"):
data = json.loads(path.read_text(encoding="utf-8"))
code = str(data.get("code", "")).strip()
analysis_type = str(data.get("analysisType", "")).strip()
if not code or not analysis_type:
raise ValueError(f"Invalid profile: {path}")
if code in profiles:
raise ValueError(f"Duplicate profile code: {code}")
profiles[code] = Profile(code, analysis_type, path.parent, data)
self._profiles = profiles
def get(self, code: str, analysis_type: str) -> Profile:
profile = self._profiles.get(code)
if profile is None:
raise KeyError(f"Analysis profile does not exist: {code}")
if profile.analysis_type != analysis_type:
raise ValueError(
f"Profile {code} is for {profile.analysis_type}, not {analysis_type}"
)
return profile
def status(self) -> list[dict[str, Any]]:
result = []
for profile in self._profiles.values():
ready = True
detail = "READY"
if profile.analysis_type == "AUDIO_CLASSIFICATION":
artifact = artifact_path(profile)
ready = artifact.exists()
detail = "READY" if ready else "WAITING_FOR_REFERENCE_AUDIO"
result.append(
{
"code": profile.code,
"analysisType": profile.analysis_type,
"ready": ready,
"detail": detail,
}
)
return result
def artifact_path(profile: Profile) -> Path:
relative = profile.directory.relative_to(settings.profiles_dir)
return settings.artifacts_dir / relative / "audio_features.npz"
profile_store = ProfileStore()