ai-station/.venv/lib/python3.12/site-packages/chainlit/input_widget.py

317 lines
8.7 KiB
Python

from abc import abstractmethod
from typing import Any, Dict, List, Optional
from pydantic import Field
from pydantic.dataclasses import dataclass
from chainlit.types import InputWidgetType
@dataclass
class InputWidget:
id: str
label: str
initial: Any = None
tooltip: Optional[str] = None
description: Optional[str] = None
disabled: Optional[bool] = False
def __post_init__(
self,
) -> None:
if not self.id or not self.label:
raise ValueError("Must provide key and label to load InputWidget")
@abstractmethod
def to_dict(self) -> Dict[str, Any]:
pass
@dataclass
class Switch(InputWidget):
"""Useful to create a switch input."""
type: InputWidgetType = "switch"
initial: bool = False
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class Slider(InputWidget):
"""Useful to create a slider input."""
type: InputWidgetType = "slider"
initial: float = 0
min: float = 0
max: float = 10
step: float = 1
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"min": self.min,
"max": self.max,
"step": self.step,
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class Select(InputWidget):
"""Useful to create a select input."""
type: InputWidgetType = "select"
initial: Optional[str] = None
initial_index: Optional[int] = None
initial_value: Optional[str] = None
values: List[str] = Field(default_factory=list)
items: Dict[str, str] = Field(default_factory=dict)
def __post_init__(
self,
) -> None:
super().__post_init__()
if not self.values and not self.items:
raise ValueError("Must provide values or items to create a Select")
if self.values and self.items:
raise ValueError(
"You can only provide either values or items to create a Select"
)
if not self.values and self.initial_index is not None:
raise ValueError(
"Initial_index can only be used in combination with values to create a Select"
)
if self.items:
self.initial = self.initial_value
elif self.values:
self.items = {value: value for value in self.values}
self.initial = (
self.values[self.initial_index]
if self.initial_index is not None
else self.initial_value
)
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"items": [
{"label": id, "value": value} for id, value in self.items.items()
],
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class TextInput(InputWidget):
"""Useful to create a text input."""
type: InputWidgetType = "textinput"
initial: Optional[str] = None
placeholder: Optional[str] = None
multiline: bool = False
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"placeholder": self.placeholder,
"tooltip": self.tooltip,
"description": self.description,
"multiline": self.multiline,
"disabled": self.disabled,
}
@dataclass
class NumberInput(InputWidget):
"""Useful to create a number input."""
type: InputWidgetType = "numberinput"
initial: Optional[float] = None
placeholder: Optional[str] = None
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"placeholder": self.placeholder,
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class Tags(InputWidget):
"""Useful to create an input for an array of strings."""
type: InputWidgetType = "tags"
initial: List[str] = Field(default_factory=list)
values: List[str] = Field(default_factory=list)
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class MultiSelect(InputWidget):
"""Useful to create a multi-select input."""
type: InputWidgetType = "multiselect"
initial: List[str] = Field(default_factory=list)
values: List[str] = Field(default_factory=list)
items: Dict[str, str] = Field(default_factory=dict)
def __post_init__(
self,
) -> None:
super().__post_init__()
if not self.values and not self.items:
raise ValueError("Must provide values or items to create a MultiSelect")
if self.values and self.items:
raise ValueError(
"You can only provide either values or items to create a MultiSelect"
)
if self.values:
self.items = {value: value for value in self.values}
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"items": [
{"label": id, "value": value} for id, value in self.items.items()
],
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class Checkbox(InputWidget):
"""Useful to create a checkbox input."""
type: InputWidgetType = "checkbox"
initial: bool = False
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class RadioGroup(InputWidget):
"""Useful to create a radio button input."""
type: InputWidgetType = "radio"
initial: Optional[str] = None
initial_index: Optional[int] = None
initial_value: Optional[str] = None
values: List[str] = Field(default_factory=list)
items: Dict[str, str] = Field(default_factory=dict)
def __post_init__(
self,
) -> None:
super().__post_init__()
if not self.values and not self.items:
raise ValueError("Must provide values or items to create a RadioButton")
if self.values and self.items:
raise ValueError(
"You can only provide either values or items to create a RadioButton"
)
if not self.values and self.initial_index is not None:
raise ValueError(
"Initial_index can only be used in combination with values to create a RadioButton"
)
if self.items:
self.initial = self.initial_value
elif self.values:
self.items = {value: value for value in self.values}
self.initial = (
self.values[self.initial_index]
if self.initial_index is not None
else self.initial_value
)
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"items": [
{"label": id, "value": value} for id, value in self.items.items()
],
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class Tab:
id: str
label: str
inputs: list[InputWidget] = Field(default_factory=list, exclude=True)
def to_dict(self) -> dict[str, Any]:
return {
"id": self.id,
"label": self.label,
"inputs": [input.to_dict() for input in self.inputs],
}