Skip to content

Commit af5253a

Browse files
authored
Add basic iterable support to publish_measurement (#38)
Signed-off-by: Michael Johansen <[email protected]>
1 parent 810f0a4 commit af5253a

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

src/ni/datastore/data/_grpc_conversion.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,17 @@ def populate_publish_measurement_request_value(
137137
raise TypeError(f"Unsupported Spectrum dtype: {value.dtype}")
138138
elif isinstance(value, DigitalWaveform):
139139
publish_request.digital_waveform.CopyFrom(digital_waveform_to_protobuf(value))
140+
elif isinstance(value, Iterable):
141+
if not value:
142+
raise ValueError("Cannot publish an empty Iterable.")
143+
try:
144+
vector = Vector(value)
145+
except (TypeError, ValueError):
146+
raise TypeError(
147+
f"Unsupported iterable: {value}. Subtype must be bool, float, int, or string."
148+
)
149+
150+
publish_request.vector.CopyFrom(vector_to_protobuf(vector))
140151
else:
141152
raise TypeError(
142153
f"Unsupported measurement value type: {type(value)}. Please consult the documentation."

tests/unit/data/test_publish_measurement.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import datetime as std_datetime
66
import unittest.mock
7-
from typing import cast
7+
from typing import Any, Iterable, cast
88
from unittest.mock import NonCallableMock
99

1010
import numpy as np
@@ -25,6 +25,8 @@
2525
from ni.protobuf.types.precision_timestamp_conversion import (
2626
hightime_datetime_to_protobuf,
2727
)
28+
from ni.protobuf.types.vector_conversion import vector_to_protobuf
29+
from ni.protobuf.types.vector_pb2 import Vector as VectorProto
2830
from ni.protobuf.types.waveform_conversion import float64_analog_waveform_to_protobuf
2931
from ni.protobuf.types.waveform_pb2 import DoubleAnalogWaveform
3032
from nitypes.vector import Vector
@@ -116,6 +118,45 @@ def test___publish_analog_waveform_data___calls_data_store_service_client(
116118
assert request.test_adapter_ids == []
117119

118120

121+
@pytest.mark.parametrize(
122+
"value", [[1, 2, 3], [1.0, 2.0, 3.0], [True, False, True], ["one", "two", "three"]]
123+
)
124+
def test___publish_basic_iterable_data___calls_data_store_service_client(
125+
data_store_client: DataStoreClient,
126+
mocked_data_store_service_client: NonCallableMock,
127+
value: Iterable[Any],
128+
) -> None:
129+
expected_vector = Vector(value)
130+
expected_protobuf_vector = VectorProto()
131+
expected_protobuf_vector.CopyFrom(vector_to_protobuf(expected_vector))
132+
published_measurement = PublishedMeasurement(published_measurement_id="response_id")
133+
expected_response = PublishMeasurementResponse(published_measurement=published_measurement)
134+
mocked_data_store_service_client.publish_measurement.return_value = expected_response
135+
136+
# Now, when client.publish_measurement calls foo.MyClass().publish(), it will use the mock
137+
result = data_store_client.publish_measurement("name", value, "step_id")
138+
139+
args, __ = mocked_data_store_service_client.publish_measurement.call_args
140+
request = cast(PublishMeasurementRequest, args[0]) # The PublishMeasurementRequest object
141+
assert result.published_measurement_id == "response_id"
142+
assert request.step_id == "step_id"
143+
assert request.measurement_name == "name"
144+
assert request.vector == expected_protobuf_vector
145+
146+
147+
def test___unsupported_list___publish_measurement___raises_type_error(
148+
data_store_client: DataStoreClient,
149+
) -> None:
150+
with pytest.raises(TypeError) as exc:
151+
_ = data_store_client.publish_measurement(
152+
measurement_name="name",
153+
value=[[1, 2, 3], [4, 5, 6]], # List of lists will error during vector creation.
154+
step_id="step_id",
155+
)
156+
157+
assert exc.value.args[0].startswith("Unsupported iterable:")
158+
159+
119160
def test___publish_analog_waveform_data_without_timestamp_parameter___uses_waveform_t0(
120161
data_store_client: DataStoreClient,
121162
mocked_data_store_service_client: NonCallableMock,

0 commit comments

Comments
 (0)