MediaRouter / app /templates /models.py
basyx's picture
Upload 142 files
fba6023 verified
Raw
History Blame Contribute Delete
1.6 kB
from __future__ import annotations
import re
from dataclasses import dataclass
from typing import Any
from pydantic import BaseModel, ConfigDict, Field
from app.core.exceptions import TemplateValidationError
from app.templates.schema import OutputDefinition, TemplateDefinition
@dataclass(frozen=True, slots=True)
class TemplateReference:
"""Parsed `template_id@version` or `template_id@latest` reference."""
template_id: str
version: int | None
@classmethod
def parse(cls, value: str) -> TemplateReference:
normalized = value.strip().lower()
match = re.fullmatch(r"([a-z][a-z0-9_]*)(?:@([1-9][0-9]*|latest))?", normalized)
if not match:
raise TemplateValidationError(
"Template reference must use id, id@version, or id@latest"
)
version_text = match.group(2)
version = None if version_text in {None, "latest"} else int(version_text)
return cls(template_id=match.group(1), version=version)
class ResolvedPipelineStep(BaseModel):
"""Pipeline step after safe parameter substitution."""
model_config = ConfigDict(extra="forbid")
operation: str
parameters: dict[str, Any] = Field(default_factory=dict)
enabled: bool = True
inputs: list[str] | None = None
save_as: str | None = None
@dataclass(frozen=True, slots=True)
class PreparedTemplate:
"""Immutable runtime-ready template and resolved parameter values."""
definition: TemplateDefinition
parameters: dict[str, Any]
pipeline: tuple[ResolvedPipelineStep, ...]
output: OutputDefinition