diff --git a/examples/sample/sample_panel.py b/examples/sample/sample_panel.py index 16506a5..18a1941 100644 --- a/examples/sample/sample_panel.py +++ b/examples/sample/sample_panel.py @@ -18,8 +18,8 @@ st.write("List") with col2: - st.write(panel.get_value("sample_string")) - st.write(panel.get_value("sample_int")) - st.write(panel.get_value("sample_float")) - st.write(panel.get_value("sample_bool")) - st.write(panel.get_value("float_values")) + st.write(panel.get_value("sample_string", "")) + st.write(panel.get_value("sample_int", 0)) + st.write(panel.get_value("sample_float", 0.0)) + st.write(panel.get_value("sample_bool", False)) + st.write(panel.get_value("float_values", [])) diff --git a/src/nipanel/_panel_value_accessor.py b/src/nipanel/_panel_value_accessor.py index afada1c..f05d2ab 100644 --- a/src/nipanel/_panel_value_accessor.py +++ b/src/nipanel/_panel_value_accessor.py @@ -41,16 +41,23 @@ def panel_id(self) -> str: """Read-only accessor for the panel ID.""" return self._panel_id - def get_value(self, value_id: str) -> object: - """Get the value for a control on the panel. + def get_value(self, value_id: str, default_value: object = None) -> object: + """Get the value for a control on the panel with an optional default value. Args: value_id: The id of the value + default_value: The default value to return if the value is not set Returns: - The value + The value, or the default value if not set """ - return self._panel_client.get_value(self._panel_id, value_id) + try: + return self._panel_client.get_value(self._panel_id, value_id) + except grpc.RpcError as e: + if e.code() == grpc.StatusCode.NOT_FOUND and default_value is not None: + return default_value + else: + raise e def set_value(self, value_id: str, value: object) -> None: """Set the value for a control on the panel. diff --git a/tests/unit/test_streamlit_panel.py b/tests/unit/test_streamlit_panel.py index 94f9107..78e77a8 100644 --- a/tests/unit/test_streamlit_panel.py +++ b/tests/unit/test_streamlit_panel.py @@ -123,7 +123,7 @@ def test___panel___set_value___sets_value( } -def test___panel___get_unset_value___raises_exception( +def test___panel___get_unset_value_with_no_default___raises_exception( fake_panel_channel: grpc.Channel, ) -> None: """Test that get_value() raises an exception for an unset value.""" @@ -146,6 +146,30 @@ def test___panel___set_value___gets_value( assert panel.get_value(value_id) == string_value +def test___set_value___get_value_ignores_default( + fake_panel_channel: grpc.Channel, +) -> None: + panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + + value_id = "test_id" + string_value = "test_value" + panel.set_value(value_id, string_value) + + assert panel.get_value(value_id, "default") == string_value + + +def test___get_value_returns_default_when_value_not_set( + fake_panel_channel: grpc.Channel, +) -> None: + panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + + assert panel.get_value("missing_string", "default") == "default" + assert panel.get_value("missing_int", 123) == 123 + assert panel.get_value("missing_float", 1.23) == 1.23 + assert panel.get_value("missing_bool", True) is True + assert panel.get_value("missing_list", [1, 2, 3]) == [1, 2, 3] + + @pytest.mark.parametrize( "value_payload", [ diff --git a/tests/utils/_fake_python_panel_servicer.py b/tests/utils/_fake_python_panel_servicer.py index 79e4872..3490ec6 100644 --- a/tests/utils/_fake_python_panel_servicer.py +++ b/tests/utils/_fake_python_panel_servicer.py @@ -59,6 +59,8 @@ def EnumeratePanels( # noqa: N802 def GetValue(self, request: GetValueRequest, context: Any) -> GetValueResponse: # noqa: N802 """Trivial implementation for testing.""" + if request.value_id not in self._panel_value_ids.get(request.panel_id, {}): + context.abort(grpc.StatusCode.NOT_FOUND, "Value ID not found in panel") value = self._panel_value_ids[request.panel_id][request.value_id] return GetValueResponse(value=value)