Source code for fluxlit.pages.session_state

"""Typed helpers for ``st.session_state`` backed by Pydantic models."""

from __future__ import annotations

from typing import Any, Literal, TypeVar

from pydantic import BaseModel, ValidationError

ModelT = TypeVar("ModelT", bound=BaseModel)


[docs] class SessionModel: """Read/write a Pydantic model to Streamlit session state keys matching field names.""" def __init__(self, st: Any, *, extra: Literal["ignore", "forbid"] = "ignore") -> None: self._st = st self._extra = extra
[docs] def read_into(self, model_type: type[ModelT]) -> ModelT: """Build *model_type* from ``st.session_state`` (missing keys use defaults).""" ss = getattr(self._st, "session_state", {}) data: dict[str, Any] = {} for name in model_type.model_fields: if hasattr(ss, "__contains__") and name in ss: data[name] = ss[name] try: return model_type.model_validate(data) except ValidationError: raise
[docs] def write_from(self, model: BaseModel) -> None: """Write ``model.model_dump()`` into ``st.session_state``.""" ss = self._st.session_state payload = model.model_dump() allowed = set(model.__class__.model_fields) if self._extra == "forbid": bad = set(payload) - allowed if bad: msg = f"Unexpected session keys: {sorted(bad)}" raise ValueError(msg) for k, v in payload.items(): ss[k] = v
__all__ = ["SessionModel"]