From 99e4218482c84662daeea7ed965f2a4a00785bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valerie=20Gleason=20=F0=9F=91=8C?= Date: Tue, 12 Aug 2025 13:16:23 -0500 Subject: [PATCH 1/5] using pathlib.Path for paths instead of str MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valerie Gleason 👌 --- src/nipanel/_panel_client.py | 12 ++-- src/nipanel/_streamlit_panel.py | 16 ++--- src/nipanel/_streamlit_panel_initializer.py | 3 +- tests/unit/test_panel_client.py | 14 ++-- tests/unit/test_streamlit_panel.py | 77 +++++++++++---------- 5 files changed, 63 insertions(+), 59 deletions(-) diff --git a/src/nipanel/_panel_client.py b/src/nipanel/_panel_client.py index 5fae4d6..bbf1724 100644 --- a/src/nipanel/_panel_client.py +++ b/src/nipanel/_panel_client.py @@ -8,12 +8,12 @@ import grpc from google.protobuf.any_pb2 import Any from ni.panels.v1.panel_service_pb2 import ( - StartPanelRequest, - StopPanelRequest, EnumeratePanelsRequest, GetValueRequest, - TryGetValueRequest, SetValueRequest, + StartPanelRequest, + StopPanelRequest, + TryGetValueRequest, ) from ni.panels.v1.panel_service_pb2_grpc import PanelServiceStub from ni.panels.v1.streamlit_panel_configuration_pb2 import StreamlitPanelConfiguration @@ -49,11 +49,11 @@ def __init__( self._stub: PanelServiceStub | None = None def start_streamlit_panel( - self, panel_id: str, panel_script_path: str, python_interpreter_path: str + self, panel_id: str, panel_script_path: pathlib.Path, python_interpreter_path: pathlib.Path ) -> str: - panel_script_url = pathlib.Path(panel_script_path).absolute().as_uri() - python_interpreter_url = pathlib.Path(python_interpreter_path).absolute().as_uri() + panel_script_url = panel_script_path.absolute().as_uri() + python_interpreter_url = python_interpreter_path.absolute().as_uri() streamlit_panel_configuration = StreamlitPanelConfiguration( panel_script_url=panel_script_url, python_interpreter_url=python_interpreter_url ) diff --git a/src/nipanel/_streamlit_panel.py b/src/nipanel/_streamlit_panel.py index 2d258fa..994541f 100644 --- a/src/nipanel/_streamlit_panel.py +++ b/src/nipanel/_streamlit_panel.py @@ -20,7 +20,7 @@ class StreamlitPanel(PanelValueAccessor): def __init__( self, panel_id: str, - panel_script_path: str, + panel_script_path: Path, *, discovery_client: DiscoveryClient | None = None, grpc_channel_pool: GrpcChannelPool | None = None, @@ -51,7 +51,7 @@ def __init__( ) @property - def panel_script_path(self) -> str: + def panel_script_path(self) -> Path: """Read-only accessor for the streamlit script file path.""" return self._panel_script_path @@ -60,7 +60,7 @@ def panel_url(self) -> str: """Read-only accessor for the panel's streamlit webpage URL.""" return self._panel_url - def _get_python_path(self) -> str: + def _get_python_path(self) -> Path: """Get the Python interpreter path for the panel that ensures the same environment.""" if sys.executable is None or sys.executable == "": raise RuntimeError("Python environment not found") @@ -78,16 +78,16 @@ def _get_python_path(self) -> str: bin_dir = "bin" # Construct path to the Python in the virtual environment based on sys.prefix - python_path = str(Path(sys.prefix) / bin_dir / python_executable) + python_path = Path(sys.prefix) / bin_dir / python_executable # Fall back to sys.executable if the constructed path doesn't exist - if not Path(python_path).exists(): - python_path = str(Path(sys.executable).resolve()) + if not python_path.exists(): + python_path = Path(sys.executable).resolve() else: # If not in a .venv environment, use sys.executable - python_path = str(Path(sys.executable).resolve()) + python_path = Path(sys.executable).resolve() - if sys.prefix not in python_path: + if sys.prefix not in str(python_path): # Ensure the Python path is within the current environment raise RuntimeError( f"Python path '{python_path}' does not match the current environment prefix '{sys.prefix}'." diff --git a/src/nipanel/_streamlit_panel_initializer.py b/src/nipanel/_streamlit_panel_initializer.py index 40eb35d..169e42d 100644 --- a/src/nipanel/_streamlit_panel_initializer.py +++ b/src/nipanel/_streamlit_panel_initializer.py @@ -43,8 +43,7 @@ def create_streamlit_panel(streamlit_script_path: Path, panel_id: str = "") -> S if not panel_id: panel_id = streamlit_script_path.stem - path_str = str(streamlit_script_path) - return StreamlitPanel(panel_id, path_str) + return StreamlitPanel(panel_id, streamlit_script_path) def get_streamlit_panel_accessor() -> PanelValueAccessor: diff --git a/tests/unit/test_panel_client.py b/tests/unit/test_panel_client.py index be71f2e..1fca5df 100644 --- a/tests/unit/test_panel_client.py +++ b/tests/unit/test_panel_client.py @@ -1,3 +1,5 @@ +from pathlib import Path + import grpc import pytest @@ -13,8 +15,8 @@ def test___enumerate_is_empty(fake_panel_channel: grpc.Channel) -> None: def test___start_panels___enumerate_has_panels(fake_panel_channel: grpc.Channel) -> None: client = _PanelClient(grpc_channel=fake_panel_channel) - client.start_streamlit_panel("panel1", "uri1", "python.exe") - client.start_streamlit_panel("panel2", "uri2", "python.exe") + client.start_streamlit_panel("panel1", Path("uri1"), Path("python.exe")) + client.start_streamlit_panel("panel2", Path("uri2"), Path("python.exe")) assert client.enumerate_panels() == { "panel1": ("http://localhost:50051/panel1", []), @@ -26,8 +28,8 @@ def test___start_panels___stop_panel_1_with_reset___enumerate_has_panel_2( fake_panel_channel: grpc.Channel, ) -> None: client = _PanelClient(grpc_channel=fake_panel_channel) - client.start_streamlit_panel("panel1", "uri1", "python.exe") - client.start_streamlit_panel("panel2", "uri2", "python.exe") + client.start_streamlit_panel("panel1", Path("uri1"), Path("python.exe")) + client.start_streamlit_panel("panel2", Path("uri2"), Path("python.exe")) client.stop_panel("panel1", reset=True) @@ -40,8 +42,8 @@ def test___start_panels___stop_panel_1_without_reset___enumerate_has_both_panels fake_panel_channel: grpc.Channel, ) -> None: client = _PanelClient(grpc_channel=fake_panel_channel) - client.start_streamlit_panel("panel1", "uri1", "python.exe") - client.start_streamlit_panel("panel2", "uri2", "python.exe") + client.start_streamlit_panel("panel1", Path("uri1"), Path("python.exe")) + client.start_streamlit_panel("panel2", Path("uri2"), Path("python.exe")) client.stop_panel("panel1", reset=False) diff --git a/tests/unit/test_streamlit_panel.py b/tests/unit/test_streamlit_panel.py index f88ff67..299fdcf 100644 --- a/tests/unit/test_streamlit_panel.py +++ b/tests/unit/test_streamlit_panel.py @@ -1,38 +1,41 @@ import datetime as dt import enum +from pathlib import Path import grpc import pytest from typing_extensions import assert_type import tests.types as test_types -from nipanel import StreamlitPanel, PanelValueAccessor +from nipanel import PanelValueAccessor, StreamlitPanel from tests.utils._fake_python_panel_service import FakePythonPanelService +PATH_TO_SCRIPT = Path("path/to/script") + def test___panel___has_panel_id_and_panel_script_path(fake_panel_channel: grpc.Channel) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) assert panel.panel_id == "my_panel" - assert panel.panel_script_path == "path/to/script" + assert panel.panel_script_path == PATH_TO_SCRIPT def test___different_panels___have_different_panel_ids_and_panel_script_paths( fake_panel_channel: grpc.Channel, ) -> None: - panel1 = StreamlitPanel("panel1", "path/to/script1", grpc_channel=fake_panel_channel) - panel2 = StreamlitPanel("panel2", "path/to/script2", grpc_channel=fake_panel_channel) + panel1 = StreamlitPanel("panel1", Path("path/to/script1"), grpc_channel=fake_panel_channel) + panel2 = StreamlitPanel("panel2", Path("path/to/script2"), grpc_channel=fake_panel_channel) assert panel1.panel_id == "panel1" assert panel2.panel_id == "panel2" - assert panel1._panel_script_path == "path/to/script1" - assert panel2._panel_script_path == "path/to/script2" + assert panel1._panel_script_path == Path("path/to/script1") + assert panel2._panel_script_path == Path("path/to/script2") assert panel1._panel_client != panel2._panel_client def test___panel___set_value___gets_same_value( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" string_value = "test_value" @@ -44,7 +47,7 @@ def test___panel___set_value___gets_same_value( def test___panel___panel_set_value___accessor_gets_same_value( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) accessor = PanelValueAccessor(panel_id="my_panel", grpc_channel=fake_panel_channel) value_id = "test_id" @@ -57,7 +60,7 @@ def test___panel___panel_set_value___accessor_gets_same_value( def test___panel___accessor_set_value___panel_gets_same_value( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) accessor = PanelValueAccessor(panel_id="my_panel", grpc_channel=fake_panel_channel) value_id = "test_id" @@ -72,7 +75,7 @@ def test___panel___set_value___notifies( fake_panel_channel: grpc.Channel, ) -> None: service = fake_python_panel_service - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) assert service.servicer.notification_count == 0 panel.set_value("value_id", "string_value") @@ -104,7 +107,7 @@ def test___first_start_will_fail___start_panel___panel_is_functional( # Simulate a failure on the first attempt service.servicer.fail_next_start_panel() - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" string_value = "test_value" @@ -118,7 +121,7 @@ def test___first_start_will_fail___start_panel___panel_is_functional( def test___panel___set_value___sets_value( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" string_value = "test_value" @@ -133,7 +136,7 @@ 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.""" - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" with pytest.raises(KeyError): @@ -143,7 +146,7 @@ def test___panel___get_unset_value_with_no_default___raises_exception( def test___panel___set_value___gets_value( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" string_value = "test_value" @@ -155,7 +158,7 @@ def test___panel___set_value___gets_value( def test___panel___set_value___get_value_ignores_default( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" string_value = "test_value" @@ -167,7 +170,7 @@ def test___panel___set_value___get_value_ignores_default( def test___no_set_value___get_value_returns_default( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + 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 @@ -184,7 +187,7 @@ def test___no_set_value___get_value_returns_default( def test___set_string_type___get_value_with_string_default___returns_string_type( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + 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) @@ -198,7 +201,7 @@ def test___set_string_type___get_value_with_string_default___returns_string_type def test___set_int_type___get_value_with_int_default___returns_int_type( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" int_value = 10 panel.set_value(value_id, int_value) @@ -212,7 +215,7 @@ def test___set_int_type___get_value_with_int_default___returns_int_type( def test___set_bool_type___get_value_with_bool_default___returns_bool_type( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" bool_value = True panel.set_value(value_id, bool_value) @@ -226,7 +229,7 @@ def test___set_bool_type___get_value_with_bool_default___returns_bool_type( def test___set_string_type___get_value_with_int_default___raises_exception( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + 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) @@ -238,7 +241,7 @@ def test___set_string_type___get_value_with_int_default___raises_exception( def test___set_int_type___get_value_with_bool_default___raises_exception( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" int_value = 10 panel.set_value(value_id, int_value) @@ -250,7 +253,7 @@ def test___set_int_type___get_value_with_bool_default___raises_exception( def test___set_string_enum_type___get_value_with_int_enum_default___raises_exception( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" panel.set_value(value_id, test_types.MyStrEnum.VALUE3) @@ -274,7 +277,7 @@ def test___builtin_scalar_type___set_value___gets_same_value( value_payload: object, ) -> None: """Test that set_value() and get_value() work for builtin scalar types.""" - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" panel.set_value(value_id, value_payload) @@ -301,7 +304,7 @@ def test___enum_type___set_value___gets_same_value( value_payload: enum.Enum, ) -> None: """Test that set_value() and get_value() work for enum types.""" - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" panel.set_value(value_id, value_payload) @@ -330,7 +333,7 @@ def test___unsupported_type___set_value___raises( value_payload: object, ) -> None: """Test that set_value() raises for unsupported types.""" - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" with pytest.raises(TypeError): @@ -380,7 +383,7 @@ def test___sequence_of_builtin_type___set_value___gets_same_value( fake_panel_channel: grpc.Channel, value_payload: object, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" panel.set_value(value_id, value_payload) @@ -392,7 +395,7 @@ def test___sequence_of_builtin_type___set_value___gets_same_value( def test___set_int_enum_value___get_value___returns_int_enum( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" enum_value = test_types.MyIntEnum.VALUE20 panel.set_value(value_id, enum_value) @@ -408,7 +411,7 @@ def test___set_int_enum_value___get_value___returns_int_enum( def test___set_intable_enum_value___get_value___returns_intable_enum( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" enum_value = test_types.MyIntableEnum.VALUE200 panel.set_value(value_id, enum_value) @@ -424,7 +427,7 @@ def test___set_intable_enum_value___get_value___returns_intable_enum( def test___set_string_enum_value___get_value___returns_string_enum( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" enum_value = test_types.MyStrEnum.VALUE3 panel.set_value(value_id, enum_value) @@ -440,7 +443,7 @@ def test___set_string_enum_value___get_value___returns_string_enum( def test___set_stringable_enum_value___get_value___returns_stringable_enum( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" enum_value = test_types.MyStringableEnum.VALUE3 panel.set_value(value_id, enum_value) @@ -456,7 +459,7 @@ def test___set_stringable_enum_value___get_value___returns_stringable_enum( def test___set_mixed_enum_value___get_value___returns_mixed_enum( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" enum_value = test_types.MyMixedEnum.VALUE2 panel.set_value(value_id, enum_value) @@ -472,7 +475,7 @@ def test___set_mixed_enum_value___get_value___returns_mixed_enum( def test___set_int_flags_value___get_value___returns_int_flags( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" flags_value = test_types.MyIntFlags.VALUE1 | test_types.MyIntFlags.VALUE4 panel.set_value(value_id, flags_value) @@ -487,7 +490,7 @@ def test___set_int_flags_value___get_value___returns_int_flags( def test___set_intable_flags_value___get_value___returns_intable_flags( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) value_id = "test_id" flags_value = test_types.MyIntableFlags.VALUE16 | test_types.MyIntableFlags.VALUE32 panel.set_value(value_id, flags_value) @@ -503,7 +506,7 @@ def test___set_intable_flags_value___get_value___returns_intable_flags( def test___panel___panel_is_running_and_in_memory( fake_panel_channel: grpc.Channel, ) -> None: - panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) assert is_panel_in_memory(panel) assert is_panel_running(panel) @@ -513,7 +516,7 @@ def test___panel___python_interpreter_url_is_in_venv( fake_python_panel_service: FakePythonPanelService, fake_panel_channel: grpc.Channel, ) -> None: - StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) assert fake_python_panel_service.servicer.python_interpreter_url.startswith("file:///") assert ".venv" in fake_python_panel_service.servicer.python_interpreter_url @@ -523,7 +526,7 @@ def test___panel___python_script_url_starts_with_file( fake_python_panel_service: FakePythonPanelService, fake_panel_channel: grpc.Channel, ) -> None: - StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) assert fake_python_panel_service.servicer.python_script_url.startswith("file:///") From 848d2838c32099e6f6389ecb31f60fa71d9fe402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valerie=20Gleason=20=F0=9F=91=8C?= Date: Tue, 12 Aug 2025 13:36:22 -0500 Subject: [PATCH 2/5] error if not pathlib.Path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valerie Gleason 👌 --- src/nipanel/_streamlit_panel_initializer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nipanel/_streamlit_panel_initializer.py b/src/nipanel/_streamlit_panel_initializer.py index 169e42d..a66230f 100644 --- a/src/nipanel/_streamlit_panel_initializer.py +++ b/src/nipanel/_streamlit_panel_initializer.py @@ -34,6 +34,8 @@ def create_streamlit_panel(streamlit_script_path: Path, panel_id: str = "") -> S raise RuntimeError( "nipanel.create_panel() should not be called from a Streamlit script. Call nipanel.get_panel_accessor() instead." ) + if not isinstance(streamlit_script_path, Path): + raise TypeError("The provided script path must be a pathlib.Path instance.") if streamlit_script_path.suffix != ".py": raise ValueError( From e208c17996d279156828595fa528714783ed1e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valerie=20Gleason=20=F0=9F=91=8C?= Date: Tue, 12 Aug 2025 13:43:55 -0500 Subject: [PATCH 3/5] removing extra blank line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valerie Gleason 👌 --- tests/unit/test_streamlit_panel.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/test_streamlit_panel.py b/tests/unit/test_streamlit_panel.py index 299fdcf..814af77 100644 --- a/tests/unit/test_streamlit_panel.py +++ b/tests/unit/test_streamlit_panel.py @@ -12,7 +12,6 @@ PATH_TO_SCRIPT = Path("path/to/script") - def test___panel___has_panel_id_and_panel_script_path(fake_panel_channel: grpc.Channel) -> None: panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) assert panel.panel_id == "my_panel" From c723ea65d71fa505e70e4d1f88c248e405649266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valerie=20Gleason=20=F0=9F=91=8C?= Date: Tue, 12 Aug 2025 13:53:11 -0500 Subject: [PATCH 4/5] I guess black wanted that line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valerie Gleason 👌 --- tests/unit/test_streamlit_panel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/test_streamlit_panel.py b/tests/unit/test_streamlit_panel.py index 814af77..299fdcf 100644 --- a/tests/unit/test_streamlit_panel.py +++ b/tests/unit/test_streamlit_panel.py @@ -12,6 +12,7 @@ PATH_TO_SCRIPT = Path("path/to/script") + def test___panel___has_panel_id_and_panel_script_path(fake_panel_channel: grpc.Channel) -> None: panel = StreamlitPanel("my_panel", PATH_TO_SCRIPT, grpc_channel=fake_panel_channel) assert panel.panel_id == "my_panel" From 126e919b26a6ec9e2a017b130ab072d802fa57d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valerie=20Gleason=20=F0=9F=91=8C?= Date: Wed, 13 Aug 2025 08:32:11 -0500 Subject: [PATCH 5/5] fixing sys.prefix check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valerie Gleason 👌 --- src/nipanel/_streamlit_panel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nipanel/_streamlit_panel.py b/src/nipanel/_streamlit_panel.py index 994541f..c33456a 100644 --- a/src/nipanel/_streamlit_panel.py +++ b/src/nipanel/_streamlit_panel.py @@ -87,7 +87,7 @@ def _get_python_path(self) -> Path: # If not in a .venv environment, use sys.executable python_path = Path(sys.executable).resolve() - if sys.prefix not in str(python_path): + if python_path.is_relative_to(Path(sys.prefix)) is False: # Ensure the Python path is within the current environment raise RuntimeError( f"Python path '{python_path}' does not match the current environment prefix '{sys.prefix}'."