Skip to content

Commit 6d2ec85

Browse files
author
Dilmi Wickramanayake
committed
Merge branch 'main' of https://github.com/ni/nipanel-python
2 parents aa6488a + 4752bbc commit 6d2ec85

File tree

4 files changed

+152
-1
lines changed

4 files changed

+152
-1
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
STREAMLIT_PYTHON_PANEL_SERVICE = "ni.pythonpanel.v1.PythonPanelService"
2+
STREAMLIT_REFRESH_COMPONENT_URL = "http://localhost:42001/panel-service/refresh"

src/nipanel/_streamlit_panel_initializer.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import streamlit as st
44

55
from nipanel._streamlit_panel_value_accessor import StreamlitPanelValueAccessor
6+
from nipanel.streamlit_refresh import initialize_refresh_component
67

78
PANEL_ACCESSOR_KEY = "StreamlitPanelValueAccessor"
89

@@ -22,7 +23,8 @@ def initialize_panel() -> StreamlitPanelValueAccessor:
2223
st.session_state[PANEL_ACCESSOR_KEY] = _initialize_panel_from_base_path()
2324

2425
panel = cast(StreamlitPanelValueAccessor, st.session_state[PANEL_ACCESSOR_KEY])
25-
# TODO: declare the refresh component here
26+
refresh_component = initialize_refresh_component(panel.panel_id)
27+
refresh_component()
2628
return panel
2729

2830

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Initializes a refresh component for Streamlit."""
2+
3+
from typing import Any
4+
5+
import streamlit.components.v1 as components
6+
7+
from nipanel._streamlit_constants import STREAMLIT_REFRESH_COMPONENT_URL
8+
9+
10+
def initialize_refresh_component(panel_id: str) -> Any:
11+
"""Initialize a refresh component to the Streamlit app."""
12+
_refresh_component_func = components.declare_component(
13+
"panelRefreshComponent",
14+
url=f"{STREAMLIT_REFRESH_COMPONENT_URL}/{panel_id}",
15+
)
16+
17+
return _refresh_component_func

tests/unit/test_convert.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
from typing import Any, Type, Union
2+
3+
import pytest
4+
from google.protobuf import any_pb2, wrappers_pb2
5+
from ni.pythonpanel.v1 import python_panel_types_pb2
6+
from typing_extensions import TypeAlias
7+
8+
import nipanel._convert
9+
10+
11+
_AnyWrappersPb2: TypeAlias = Union[
12+
wrappers_pb2.BoolValue,
13+
wrappers_pb2.BytesValue,
14+
wrappers_pb2.DoubleValue,
15+
wrappers_pb2.Int64Value,
16+
wrappers_pb2.StringValue,
17+
]
18+
19+
_AnyPanelPbTypes: TypeAlias = Union[
20+
python_panel_types_pb2.BoolCollection,
21+
python_panel_types_pb2.ByteStringCollection,
22+
python_panel_types_pb2.FloatCollection,
23+
python_panel_types_pb2.IntCollection,
24+
python_panel_types_pb2.StringCollection,
25+
]
26+
27+
28+
# ========================================================
29+
# Python to Protobuf
30+
# ========================================================
31+
@pytest.mark.parametrize(
32+
"proto_type, default_value, expected_value",
33+
[
34+
(wrappers_pb2.BoolValue, False, True),
35+
(wrappers_pb2.BytesValue, b"", b"mystr"),
36+
(wrappers_pb2.DoubleValue, 0.0, 456.2),
37+
(wrappers_pb2.Int64Value, 0, 123),
38+
(wrappers_pb2.StringValue, "", "mystr"),
39+
],
40+
)
41+
def test___python_builtin_scalar___to_any___valid_wrapperpb2_value(
42+
proto_type: Type[_AnyWrappersPb2], default_value: Any, expected_value: Any
43+
) -> None:
44+
result = nipanel._convert.to_any(expected_value)
45+
unpack_dest = proto_type(value=default_value)
46+
_assert_any_and_unpack(result, unpack_dest)
47+
48+
assert isinstance(unpack_dest, proto_type)
49+
assert unpack_dest.value == expected_value
50+
51+
52+
@pytest.mark.parametrize(
53+
"proto_type, default_value, expected_value",
54+
[
55+
(python_panel_types_pb2.BoolCollection, [False, False, False], [True, True, True]),
56+
(python_panel_types_pb2.ByteStringCollection, [b"", b"", b""], [b"a", b"b", b"c"]),
57+
(python_panel_types_pb2.FloatCollection, [0.0, 0.0, 0.0], [1.0, 2.0, 3.0]),
58+
(python_panel_types_pb2.IntCollection, [0, 0, 0], [1, 2, 3]),
59+
(python_panel_types_pb2.StringCollection, ["", "", ""], ["a", "b", "c"]),
60+
],
61+
)
62+
def test___python_panel_collection___to_any___valid_paneltype_value(
63+
proto_type: Type[_AnyPanelPbTypes], default_value: Any, expected_value: Any
64+
) -> None:
65+
result = nipanel._convert.to_any(expected_value)
66+
unpack_dest = proto_type(values=default_value)
67+
_assert_any_and_unpack(result, unpack_dest)
68+
69+
assert isinstance(unpack_dest, proto_type)
70+
assert unpack_dest.values == expected_value
71+
72+
73+
# ========================================================
74+
# Protobuf to Python
75+
# ========================================================
76+
@pytest.mark.parametrize(
77+
"proto_type, expected_value",
78+
[
79+
(wrappers_pb2.BoolValue, True),
80+
(wrappers_pb2.BytesValue, b"mystr"),
81+
(wrappers_pb2.DoubleValue, 456.2),
82+
(wrappers_pb2.Int64Value, 123),
83+
(wrappers_pb2.StringValue, "mystr"),
84+
],
85+
)
86+
def test___wrapperpb2_value___from_any___valid_python_value(
87+
proto_type: Type[_AnyWrappersPb2], expected_value: Any
88+
) -> None:
89+
pb_value = proto_type(value=expected_value)
90+
packed_any = _pack_into_any(pb_value)
91+
92+
result = nipanel._convert.from_any(packed_any)
93+
94+
assert isinstance(result, type(expected_value))
95+
assert result == expected_value
96+
97+
98+
@pytest.mark.parametrize(
99+
"proto_type, expected_value",
100+
[
101+
(python_panel_types_pb2.BoolCollection, [True, True, True]),
102+
(python_panel_types_pb2.ByteStringCollection, [b"a", b"b", b"c"]),
103+
(python_panel_types_pb2.FloatCollection, [1.0, 2.0, 3.0]),
104+
(python_panel_types_pb2.IntCollection, [1, 2, 3]),
105+
(python_panel_types_pb2.StringCollection, ["a", "b", "c"]),
106+
],
107+
)
108+
def test___paneltype_value___from_any___valid_python_value(
109+
proto_type: Type[_AnyPanelPbTypes], expected_value: Any
110+
) -> None:
111+
pb_value = proto_type(values=expected_value)
112+
packed_any = _pack_into_any(pb_value)
113+
114+
result = nipanel._convert.from_any(packed_any)
115+
116+
assert isinstance(result, type(expected_value))
117+
assert result == expected_value
118+
119+
120+
# ========================================================
121+
# Pack/Unpack Helpers
122+
# ========================================================
123+
def _assert_any_and_unpack(packed_message: any_pb2.Any, unpack_destination: Any) -> None:
124+
assert isinstance(packed_message, any_pb2.Any)
125+
assert packed_message.Unpack(unpack_destination)
126+
127+
128+
def _pack_into_any(proto_value: Union[_AnyWrappersPb2, _AnyPanelPbTypes]) -> any_pb2.Any:
129+
as_any = any_pb2.Any()
130+
as_any.Pack(proto_value)
131+
return as_any

0 commit comments

Comments
 (0)