def setUp(self): wstates = WStates() self.wstates = wstates widget_state = WidgetStateProto() widget_state.id = "widget_id_1" widget_state.int_value = 5 wstates.set_widget_from_proto(widget_state) wstates.set_widget_metadata( WidgetMetadata( id="widget_id_1", deserializer=lambda x, s: str(x), serializer=lambda x: int(x), value_type="int_value", ) ) wstates.set_from_value("widget_id_2", 5) wstates.set_widget_metadata( WidgetMetadata( id="widget_id_2", deserializer=lambda x, s: x, serializer=identity, value_type="int_value", ) )
def get_serialized(self, k: str, default: Optional[WidgetStateProto] = None ) -> Optional[WidgetStateProto]: widget = WidgetStateProto() widget.id = k item = self.states.get(k) if item is not None: if isinstance(item, Value): metadata = self.widget_metadata.get(k) if metadata is None: return default else: field = metadata.value_type serialized = metadata.serializer(item.value) if field in ( "double_array_value", "int_array_value", "string_array_value", ): arr = getattr(widget, field) arr.data.extend(serialized) elif field == "json_value": setattr(widget, field, json.dumps(serialized)) elif field == "file_uploader_state_value": widget.file_uploader_state_value.CopyFrom(serialized) else: setattr(widget, field, serialized) return widget else: return item.value else: return default
def test_callbacks_with_experimental_rerun(self, patched_warning): """Calling 'experimental_rerun' from within a widget callback is disallowed and results in a warning. """ # A mock on_changed handler for our checkbox. It will call # `st.experimental_rerun`, which should result in a warning # being printed to the user's app. mock_on_checkbox_changed = MagicMock(side_effect=st.experimental_rerun) st.checkbox("the checkbox", on_change=mock_on_checkbox_changed) session_state = _raw_session_state() # Pretend that the checkbox has a new state value checkbox_state = WidgetStateProto() checkbox_state.id = list(session_state._new_widget_state.keys())[0] checkbox_state.bool_value = True widget_states = WidgetStatesProto() widget_states.widgets.append(checkbox_state) # Tell session_state to call our callbacks. session_state.on_script_will_rerun(widget_states) mock_on_checkbox_changed.assert_called_once() patched_warning.assert_called_once()
def test_get_from_json_value(self): widget_state = WidgetStateProto() widget_state.id = "widget_id_3" widget_state.json_value = '{"foo":5}' self.wstates.set_widget_from_proto(widget_state) self.wstates.set_widget_metadata( WidgetMetadata( id="widget_id_3", deserializer=lambda x, s: x, serializer=identity, value_type="json_value", )) assert self.wstates["widget_id_3"] == {"foo": 5}
def test_filtered_state_resilient_to_missing_metadata(self): old_state = {"foo": "bar", "corge": "grault"} new_session_state = {} new_widget_state = WStates( { f"{GENERATED_WIDGET_KEY_PREFIX}-baz": Serialized(WidgetStateProto()) }, ) self.session_state = SessionState(old_state, new_session_state, new_widget_state) assert self.session_state.filtered_state == { "foo": "bar", "corge": "grault", }
def test_get_serialized_array_value(self): widget_state = WidgetStateProto() widget_state.id = "widget_id_1" widget_state.int_array_value.data.extend([1, 2, 3, 4]) self.wstates.set_widget_from_proto(widget_state) self.wstates.set_widget_metadata( WidgetMetadata( id="widget_id_1", deserializer=lambda x, s: x, serializer=identity, value_type="int_array_value", )) serialized = self.wstates.get_serialized("widget_id_1") assert serialized.id == "widget_id_1" assert list(serialized.int_array_value.data) == [1, 2, 3, 4]
def get_serialized(self, k: str) -> Optional[WidgetStateProto]: """Get the serialized value of the widget with the given id. If the widget doesn't exist, return None. If the widget exists but is not in serialized form, it will be serialized first. """ item = self.states.get(k) if item is None: # No such widget: return None. return None if isinstance(item, Serialized): # Widget value is serialized: return it directly. return item.value # Widget value is not serialized: serialize it first! metadata = self.widget_metadata.get(k) if metadata is None: # We're missing the widget's metadata. (Can this happen?) return None widget = WidgetStateProto() widget.id = k field = metadata.value_type serialized = metadata.serializer(item.value) if field in ( "double_array_value", "int_array_value", "string_array_value", ): arr = getattr(widget, field) arr.data.extend(serialized) elif field == "json_value": setattr(widget, field, json.dumps(serialized)) elif field == "file_uploader_state_value": widget.file_uploader_state_value.CopyFrom(serialized) else: setattr(widget, field, serialized) return widget