Skip to content

Commit 6861bfc

Browse files
Mike ProsserMike Prosser
authored andcommitted
streamlit panel accessor
1 parent cc5b1a6 commit 6861bfc

6 files changed

Lines changed: 138 additions & 39 deletions

File tree

src/nipanel/_panel.py

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,15 @@
66
from ni_measurement_plugin_sdk_service.discovery import DiscoveryClient
77
from ni_measurement_plugin_sdk_service.grpc.channelpool import GrpcChannelPool
88

9-
from nipanel._panel_client import PanelClient
9+
from nipanel._panel_accessor import PanelAccessor
1010

1111

12-
class Panel(ABC):
12+
class Panel(PanelAccessor, ABC):
1313
"""This class allows you to open a panel and specify values for its controls."""
1414

15-
_panel_client: PanelClient
16-
_panel_id: str
1715
_panel_uri: str
1816

19-
__slots__ = ["_panel_client", "_panel_id", "_panel_uri", "__weakref__"]
17+
__slots__ = PanelAccessor.__slots__ + ["_panel_uri", "__weakref__"]
2018

2119
def __init__(
2220
self,
@@ -29,22 +27,17 @@ def __init__(
2927
grpc_channel_pool: GrpcChannelPool | None = None,
3028
grpc_channel: grpc.Channel | None = None,
3129
) -> None:
32-
"""Initialize the panel."""
33-
self._panel_client = PanelClient(
30+
"""Initialize the Panel class."""
31+
super().__init__(
32+
panel_id=panel_id,
3433
provided_interface=provided_interface,
3534
service_class=service_class,
3635
discovery_client=discovery_client,
3736
grpc_channel_pool=grpc_channel_pool,
3837
grpc_channel=grpc_channel,
3938
)
40-
self._panel_id = panel_id
4139
self._panel_uri = panel_uri
4240

43-
@property
44-
def panel_id(self) -> str:
45-
"""Read-only accessor for the panel ID."""
46-
return self._panel_id
47-
4841
@property
4942
def panel_uri(self) -> str:
5043
"""Read-only accessor for the panel URI."""
@@ -53,23 +46,3 @@ def panel_uri(self) -> str:
5346
def open_panel(self) -> None:
5447
"""Open the panel."""
5548
self._panel_client.open_panel(self._panel_id, self._panel_uri)
56-
57-
def get_value(self, value_id: str) -> object:
58-
"""Get the value for a control on the panel.
59-
60-
Args:
61-
value_id: The id of the value
62-
63-
Returns:
64-
The value
65-
"""
66-
return self._panel_client.get_value(self._panel_id, value_id)
67-
68-
def set_value(self, value_id: str, value: object) -> None:
69-
"""Set the value for a control on the panel.
70-
71-
Args:
72-
value_id: The id of the value
73-
value: The value
74-
"""
75-
self._panel_client.set_value(self._panel_id, value_id, value)

src/nipanel/_panel_accessor.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from __future__ import annotations
2+
3+
import grpc
4+
from ni_measurement_plugin_sdk_service.discovery import DiscoveryClient
5+
from ni_measurement_plugin_sdk_service.grpc.channelpool import GrpcChannelPool
6+
7+
from nipanel._panel_client import PanelClient
8+
9+
10+
class PanelAccessor:
11+
"""This class allows you to access values for a panel's controls."""
12+
13+
_panel_client: PanelClient
14+
_panel_id: str
15+
16+
__slots__ = ["_panel_client", "_panel_id"]
17+
18+
def __init__(
19+
self,
20+
*,
21+
panel_id: str,
22+
provided_interface: str,
23+
service_class: str,
24+
discovery_client: DiscoveryClient | None = None,
25+
grpc_channel_pool: GrpcChannelPool | None = None,
26+
grpc_channel: grpc.Channel | None = None,
27+
) -> None:
28+
"""Initialize the accessor."""
29+
self._panel_client = PanelClient(
30+
provided_interface=provided_interface,
31+
service_class=service_class,
32+
discovery_client=discovery_client,
33+
grpc_channel_pool=grpc_channel_pool,
34+
grpc_channel=grpc_channel,
35+
)
36+
self._panel_id = panel_id
37+
38+
@property
39+
def panel_id(self) -> str:
40+
"""Read-only accessor for the panel ID."""
41+
return self._panel_id
42+
43+
def get_value(self, value_id: str) -> object:
44+
"""Get the value for a control on the panel.
45+
46+
Args:
47+
value_id: The id of the value
48+
49+
Returns:
50+
The value
51+
"""
52+
return self._panel_client.get_value(self._panel_id, value_id)
53+
54+
def set_value(self, value_id: str, value: object) -> None:
55+
"""Set the value for a control on the panel.
56+
57+
Args:
58+
value_id: The id of the value
59+
value: The value
60+
"""
61+
self._panel_client.set_value(self._panel_id, value_id, value)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
STREAMLIT_PYTHON_PANEL_SERVICE = "ni.pythonpanel.v1.PythonPanelService"

src/nipanel/_streamlit_panel.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55
from ni_measurement_plugin_sdk_service.grpc.channelpool import GrpcChannelPool
66

77
from nipanel._panel import Panel
8+
from nipanel._streamlit_constants import STREAMLIT_PYTHON_PANEL_SERVICE
89

910

1011
class StreamlitPanel(Panel):
1112
"""This class allows you to open a Streamlit panel and specify values for its controls."""
1213

13-
PYTHON_PANEL_SERVICE = "ni.pythonpanel.v1.PythonPanelService"
14-
15-
__slots__ = ()
16-
1714
def __init__(
1815
self,
1916
panel_id: str,
@@ -36,8 +33,8 @@ def __init__(
3633
super().__init__(
3734
panel_id=panel_id,
3835
panel_uri=streamlit_script_uri,
39-
provided_interface=self.PYTHON_PANEL_SERVICE,
40-
service_class=self.PYTHON_PANEL_SERVICE,
36+
provided_interface=STREAMLIT_PYTHON_PANEL_SERVICE,
37+
service_class=STREAMLIT_PYTHON_PANEL_SERVICE,
4138
discovery_client=discovery_client,
4239
grpc_channel_pool=grpc_channel_pool,
4340
grpc_channel=grpc_channel,
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from __future__ import annotations
2+
3+
import grpc
4+
from ni_measurement_plugin_sdk_service.discovery import DiscoveryClient
5+
from ni_measurement_plugin_sdk_service.grpc.channelpool import GrpcChannelPool
6+
7+
from nipanel._panel import PanelAccessor
8+
from nipanel._streamlit_constants import STREAMLIT_PYTHON_PANEL_SERVICE
9+
10+
11+
class StreamlitPanelAccessor(PanelAccessor):
12+
"""This class provides access to values for a Streamlit panel's controls."""
13+
14+
def __init__(
15+
self,
16+
panel_id: str,
17+
*,
18+
discovery_client: DiscoveryClient | None = None,
19+
grpc_channel_pool: GrpcChannelPool | None = None,
20+
grpc_channel: grpc.Channel | None = None,
21+
) -> None:
22+
"""Create an accessor for a Streamlit panel.
23+
24+
Args:
25+
panel_id: A unique identifier for the panel.
26+
grpc_channel: An optional gRPC channel to use for communication with the panel service.
27+
28+
Returns:
29+
A new StreamlitPanelAccessor instance.
30+
"""
31+
super().__init__(
32+
panel_id=panel_id,
33+
provided_interface=STREAMLIT_PYTHON_PANEL_SERVICE,
34+
service_class=STREAMLIT_PYTHON_PANEL_SERVICE,
35+
discovery_client=discovery_client,
36+
grpc_channel_pool=grpc_channel_pool,
37+
grpc_channel=grpc_channel,
38+
)

tests/unit/test_streamlit_panel.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import tests.types as test_types
55
from nipanel._streamlit_panel import StreamlitPanel
6+
from nipanel._streamlit_panel_accessor import StreamlitPanelAccessor
67
from tests.utils._fake_python_panel_service import FakePythonPanelService
78

89

@@ -25,6 +26,34 @@ def test___opened_panel___set_value___gets_same_value(
2526
assert panel.get_value(value_id) == string_value
2627

2728

29+
def test___opened_panel___panel_set_value___accessor_gets_same_value(
30+
fake_panel_channel: grpc.Channel,
31+
) -> None:
32+
panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel)
33+
panel.open_panel()
34+
panel_accessor = StreamlitPanelAccessor("my_panel", grpc_channel=fake_panel_channel)
35+
36+
value_id = "test_id"
37+
string_value = "test_value"
38+
panel.set_value(value_id, string_value)
39+
40+
assert panel_accessor.get_value(value_id) == string_value
41+
42+
43+
def test___opened_panel___accessor_set_value___panel_gets_same_value(
44+
fake_panel_channel: grpc.Channel,
45+
) -> None:
46+
panel = StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel)
47+
panel.open_panel()
48+
panel_accessor = StreamlitPanelAccessor("my_panel", grpc_channel=fake_panel_channel)
49+
50+
value_id = "test_id"
51+
string_value = "test_value"
52+
panel_accessor.set_value(value_id, string_value)
53+
54+
assert panel.get_value(value_id) == string_value
55+
56+
2857
def test___first_open_panel_fails___open_panel___gets_value(
2958
fake_python_panel_service: FakePythonPanelService,
3059
fake_panel_channel: grpc.Channel,

0 commit comments

Comments
 (0)