|
@@ -32,6 +32,8 @@ from plotly.io import to_json
|
|
|
from rich.console import Console
|
|
|
|
|
|
from pynecone import constants
|
|
|
+from pynecone.base import Base
|
|
|
+
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
from pynecone.components.component import ImportDict
|
|
@@ -49,6 +51,10 @@ console = Console()
|
|
|
# Union of generic types.
|
|
|
GenericType = Union[Type, _GenericAlias]
|
|
|
|
|
|
+# Valid state var types.
|
|
|
+PrimitiveType = Union[int, float, bool, str, list, dict, tuple]
|
|
|
+StateVar = Union[PrimitiveType, Base, None]
|
|
|
+
|
|
|
|
|
|
def get_args(alias: _GenericAlias) -> Tuple[Type, ...]:
|
|
|
"""Get the arguments of a type alias.
|
|
@@ -703,17 +709,33 @@ def format_state(value: Any) -> Dict:
|
|
|
|
|
|
Returns:
|
|
|
The formatted state.
|
|
|
+
|
|
|
+ Raises:
|
|
|
+ TypeError: If the given value is not a valid state.
|
|
|
"""
|
|
|
- if isinstance(value, go.Figure):
|
|
|
+ # Convert plotly figures to JSON.
|
|
|
+ if _isinstance(value, go.Figure):
|
|
|
return json.loads(to_json(value))["data"]
|
|
|
|
|
|
+ # Convert pandas dataframes to JSON.
|
|
|
if is_dataframe(type(value)):
|
|
|
return {
|
|
|
"columns": value.columns.tolist(),
|
|
|
"data": value.values.tolist(),
|
|
|
}
|
|
|
- if isinstance(value, dict):
|
|
|
+
|
|
|
+ # Handle dicts.
|
|
|
+ if _isinstance(value, dict):
|
|
|
return {k: format_state(v) for k, v in value.items()}
|
|
|
+
|
|
|
+ # Make sure the value is JSON serializable.
|
|
|
+ if not _isinstance(value, StateVar):
|
|
|
+ raise TypeError(
|
|
|
+ "State vars must be primitive Python types, "
|
|
|
+ "or subclasses of pc.Base. "
|
|
|
+ f"Got var of type {type(value)}."
|
|
|
+ )
|
|
|
+
|
|
|
return value
|
|
|
|
|
|
|