Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions chatkit/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1098,22 +1098,22 @@ class DynamicWidgetComponent(WidgetComponentBase):
]


class BasicRoot(DynamicWidgetComponent):
"""Layout root capable of nesting components or other roots."""

type: Literal["Basic"] = Field(default="Basic", frozen=True) # pyright: ignore


StrictWidgetRoot = Annotated[
Card | ListView,
Card | ListView | BasicRoot,
Field(discriminator="type"),
]


class DynamicWidgetRoot(DynamicWidgetComponent):
"""Dynamic root widget restricted to root types."""

type: Literal["Card", "ListView"] # pyright: ignore


class BasicRoot(DynamicWidgetComponent):
"""Layout root capable of nesting components or other roots."""

type: Literal["Basic"] = Field(default="Basic", frozen=True) # pyright: ignore
type: Literal["Card", "ListView", "Basic"] # pyright: ignore


WidgetComponent = StrictWidgetComponent | DynamicWidgetComponent
Expand Down Expand Up @@ -1178,8 +1178,9 @@ def build(
widget_dict = json.loads(rendered)
return DynamicWidgetRoot.model_validate(widget_dict)

@deprecated("WidgetTemplate.build_basic is deprecated. Use WidgetTemplate.build instead.")
def build_basic(self, data: dict[str, Any] | BaseModel | None = None) -> BasicRoot:
"""Separate method for building basic root widgets until BasicRoot is supported for streamed widgets."""
"""Deprecated alias for building Basic root widgets."""
rendered = self.template.render(**self._normalize_data(data))
widget_dict = json.loads(rendered)
return BasicRoot.model_validate(widget_dict)
Expand Down
31 changes: 29 additions & 2 deletions tests/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,18 +244,45 @@ def test_widget_template_from_file(
assert widget.model_dump(exclude_none=True) == expected_widget_dict


def test_widget_template_with_basic_root():
def test_widget_template_build_with_basic_root():
template = WidgetTemplate.from_file("assets/widgets/basic_root.widget")

with open("tests/assets/widgets/basic_root.json", "r") as file:
expected_widget_dict = json.load(file)

widget = template.build_basic(
widget = template.build(
{
"name": "Harry Potter",
"bio": "The boy who lived",
},
)

assert isinstance(widget, DynamicWidgetRoot)
assert widget.type == "Basic"
assert widget.model_dump(exclude_none=True) == expected_widget_dict

widget_item = WidgetItem(
thread_id="1", widget=widget, id="1", created_at=datetime.now()
)
assert widget_item.widget.type == "Basic"


def test_widget_template_build_basic_is_deprecated():
template = WidgetTemplate.from_file("assets/widgets/basic_root.widget")

with open("tests/assets/widgets/basic_root.json", "r") as file:
expected_widget_dict = json.load(file)

with pytest.warns(
DeprecationWarning,
match="WidgetTemplate.build_basic is deprecated. Use WidgetTemplate.build instead.",
):
widget = template.build_basic(
{
"name": "Harry Potter",
"bio": "The boy who lived",
},
)

assert isinstance(widget, BasicRoot)
assert widget.model_dump(exclude_none=True) == expected_widget_dict