Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input Support for Double2dArray for Client Generator and Service and updating Sample Measurement #1026

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion examples/sample_measurement/measurement.py
Blahpapto1 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ class Color(Enum):
@measurement_service.configuration(
"String Array In", nims.DataType.StringArray1D, ["String1", "String2"]
)
@measurement_service.configuration(
"Double 2D Array In",
nims.DataType.Double2DArray,
array_pb2.Double2DArray(rows=2, columns=3, data=[1, 2, 3, 4, 5, 6]),
)
@measurement_service.output("Float out", nims.DataType.Float)
@measurement_service.output("Double Array out", nims.DataType.DoubleArray1D)
@measurement_service.output("Bool out", nims.DataType.Boolean)
Expand All @@ -70,6 +75,7 @@ def measure(
enum_input: Color,
protobuf_enum_input: color_pb2.ProtobufColor.ValueType,
string_array_in: Iterable[str],
double_2d_array_input: array_pb2.Double2DArray,
) -> Tuple[
float,
Iterable[float],
Expand All @@ -95,7 +101,7 @@ def cancel_callback() -> None:
enum_output = enum_input
protobuf_enum_output = protobuf_enum_input
string_array_output = string_array_in
double_2d_array_output = array_pb2.Double2DArray()
double_2d_array_output = double_2d_array_input
logging.info("Completed measurement")

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import black
import click
from click_option_group import optgroup, RequiredMutuallyExclusiveOptionGroup
from click_option_group import RequiredMutuallyExclusiveOptionGroup, optgroup
from mako.template import Template
from ni_measurement_plugin_sdk_service._internal.stubs.ni.measurementlink.measurement.v2 import (
measurement_service_pb2 as v2_measurement_service_pb2,
Expand All @@ -19,19 +19,18 @@
create_class_name,
create_module_name,
extract_base_service_class,
get_all_registered_measurement_info,
get_configuration_and_output_metadata_by_index,
get_configuration_parameters_with_type_and_default_values,
get_measurement_service_stub_and_version,
get_output_parameters_with_type,
get_all_registered_measurement_info,
get_selected_measurement_service_class,
to_ordered_set,
resolve_output_directory,
to_ordered_set,
validate_identifier,
validate_measurement_service_classes,
)


_CLIENT_CREATION_ERROR_MESSAGE = "Client creation failed for '{}'. Possible reason(s): {}"


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@
import re
import sys
from enum import Enum
from typing import AbstractSet, Dict, Iterable, List, Optional, Tuple, Type, TypeVar
from typing import (
AbstractSet,
Any,
Dict,
Iterable,
List,
Optional,
Tuple,
Type,
TypeVar,
)

import click
import grpc
Expand All @@ -20,6 +30,9 @@
measurement_service_pb2 as v2_measurement_service_pb2,
measurement_service_pb2_grpc as v2_measurement_service_pb2_grpc,
)
from ni_measurement_plugin_sdk_service._internal.stubs.ni.protobuf.types.array_pb2 import (
Double2DArray,
)
from ni_measurement_plugin_sdk_service.discovery import DiscoveryClient
from ni_measurement_plugin_sdk_service.grpc.channelpool import GrpcChannelPool
from ni_measurement_plugin_sdk_service.measurement.client_support import (
Expand Down Expand Up @@ -66,6 +79,27 @@
]


def _format_default_value(value: Any) -> Any:
"""Format the default value for the given value.

Used for generating the service's metadata structs.
"""
if isinstance(value, str):
return repr(value)
elif isinstance(value, Double2DArray):
value = str(value).split("\n")[:-1]
value_2d_array_rows = int(value[0].split(" ")[1])
value_2d_array_columns = int(value[1].split(" ")[1])
value_2d_array_data = []
for data in value[2:]:
new_data = data.split(" ")[1]
value_2d_array_data.append(int(new_data))
value = f"Double2DArray(rows={value_2d_array_rows}, columns={value_2d_array_columns}, data={value_2d_array_data})"
return value
else:
return value


def get_measurement_service_stub_and_version(
discovery_client: DiscoveryClient,
channel_pool: GrpcChannelPool,
Expand Down Expand Up @@ -124,7 +158,10 @@ def get_configuration_and_output_metadata_by_index(
"""Returns the configuration and output metadata of the measurement."""
configuration_parameter_list = []
for configuration in metadata.measurement_signature.configuration_parameters:
if configuration.message_type:
if (
configuration.message_type
and configuration.message_type != "ni.protobuf.types.Double2DArray"
):
raise click.ClickException(
f"Measurement configurations do not support message data types ({configuration.message_type} is unsupported)."
)
Expand Down Expand Up @@ -208,6 +245,7 @@ def get_configuration_and_output_metadata_by_index(
default_value = default_value.value
elif isinstance(default_value, list) and any(isinstance(e, Enum) for e in default_value):
default_value = [e.value for e in default_value]

configuration_metadata[id] = configuration_metadata[id]._replace(
default_value=default_value
)
Expand All @@ -220,7 +258,10 @@ def get_configuration_parameters_with_type_and_default_values(
built_in_import_modules: List[str],
enum_values_by_type: Dict[Type[Enum], Dict[str, int]] = {},
) -> Tuple[str, str]:
"""Returns configuration parameters of the measurement with type and default values."""
"""Return configuration parameters of the measurement with type and default values.

Used to generate Client API class's measure() parameter list.
"""
configuration_parameters = []
parameter_names = []

Expand All @@ -231,7 +272,7 @@ def get_configuration_parameters_with_type_and_default_values(
default_value = metadata.default_value
parameter_type = _get_configuration_python_type_as_str(metadata.type, metadata.repeated)
if isinstance(default_value, str):
default_value = repr(default_value)
default_value = _format_default_value(default_value)

if metadata.annotations and metadata.annotations.get("ni/type_specialization") == "path":
parameter_type = "pathlib.PurePath"
Expand Down Expand Up @@ -264,6 +305,10 @@ def get_configuration_parameters_with_type_and_default_values(
enum_value = next((e.name for e in enum_type if e.value == default_value), None)
default_value = f"{parameter_type}.{enum_value}"

if metadata.message_type and metadata.message_type == "ni.protobuf.types.Double2DArray":
default_value = _format_default_value(default_value)
parameter_type = "Double2DArray"

configuration_parameters.append(f"{parameter_name}: {parameter_type} = {default_value}")

configuration_parameters_with_type_and_value = f", ".join(configuration_parameters)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
<%!
import re
from typing import Any
from ni_measurement_plugin_sdk_generator.client._support import _format_default_value
%>\
\
<%page args="class_name, display_name, version, configuration_metadata, output_metadata, service_class, configuration_parameters_with_type_and_default_values, measure_api_parameters, output_parameters_with_type, built_in_import_modules, custom_import_modules, enum_by_class_name, configuration_parameters_type_url, outputs_message_type"/>\
\
<%
def _format_default_value(value: Any) -> Any:
if isinstance(value, str):
return repr(value)
else:
return value
%>\
\

"""Generated client API for the ${display_name | repr} measurement plug-in."""
Expand Down Expand Up @@ -138,7 +132,7 @@ class ${class_name}:
display_name=${value.display_name | repr},
type=Field.Kind.ValueType(${value.type}),
repeated=${value.repeated},
default_value=${value.default_value},
default_value=${_format_default_value(value.default_value)},
annotations=${value.annotations | n, repr},
message_type=${value.message_type | repr},
field_name=${value.field_name | repr},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
from typing import Any, Generator, Tuple, Type, Union

import pytest
from ni_measurement_plugin_sdk_service._internal.stubs.ni.protobuf.types import (
array_pb2,
)
from ni_measurement_plugin_sdk_service.measurement.service import MeasurementService

from tests.conftest import CliRunnerFunction
Expand Down Expand Up @@ -65,7 +68,7 @@ def test___measurement_plugin_client___measure___returns_output(
enum_out=EnumInEnum.BLUE,
enum_array_out=[EnumInEnum.RED, EnumInEnum.GREEN],
protobuf_enum_out=ProtobufEnumInEnum.BLACK,
double_2d_array_out=None,
double_2d_array_out=array_pb2.Double2DArray(rows=2, columns=3, data=[1, 2, 3, 4, 5, 6]),
)
measurement_plugin_client = test_measurement_client_type()

Expand Down Expand Up @@ -121,7 +124,7 @@ def test___measurement_plugin_client___stream_measure___returns_output(
enum_out=EnumInEnum.BLUE,
enum_array_out=[EnumInEnum.RED, EnumInEnum.GREEN],
protobuf_enum_out=ProtobufEnumInEnum.BLACK,
double_2d_array_out=None,
double_2d_array_out=array_pb2.Double2DArray(rows=2, columns=3, data=[1, 2, 3, 4, 5, 6]),
)
measurement_plugin_client = test_measurement_client_type()

Expand Down Expand Up @@ -219,7 +222,7 @@ def _verify_output_types(outputs: Any, measurement_plugin_client_module: ModuleT
_assert_type(outputs.enum_out, enum_type)
_assert_collection_type(outputs.enum_array_out, Sequence, enum_type)
_assert_type(outputs.protobuf_enum_out, protobuf_enum_type)
_assert_type(outputs.double_2d_array_out, type(None))
_assert_type(outputs.double_2d_array_out, array_pb2.Double2DArray)


def _assert_type(value: Any, expected_type: Union[Type[Any], Tuple[Type[Any], ...]]) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,16 @@ def __init__(
field_name="Protobuf_Enum_In",
enum_type=ProtobufEnumInEnum,
),
14: ParameterMetadata(
display_name="Double 2D Array In",
type=Field.Kind.ValueType(11),
repeated=False,
default_value=Double2DArray(rows=2, columns=3, data=[1, 2, 3, 4, 5, 6]),
annotations={},
message_type="ni.protobuf.types.Double2DArray",
field_name="Double_2D_Array_In",
enum_type=None,
),
}
self._output_metadata = {
1: ParameterMetadata(
Expand Down Expand Up @@ -585,6 +595,9 @@ def measure(
enum_in: EnumInEnum = EnumInEnum.BLUE,
enum_array_in: typing.Iterable[EnumInEnum] = [EnumInEnum.RED, EnumInEnum.GREEN],
protobuf_enum_in: ProtobufEnumInEnum = ProtobufEnumInEnum.BLACK,
double_2d_array_in: Double2DArray = Double2DArray(
rows=2, columns=3, data=[1, 2, 3, 4, 5, 6]
),
) -> Outputs:
"""Perform a single measurement.

Expand All @@ -605,6 +618,7 @@ def measure(
enum_in,
enum_array_in,
protobuf_enum_in,
double_2d_array_in,
)
for response in stream_measure_response:
result = response
Expand Down Expand Up @@ -639,6 +653,9 @@ def stream_measure(
enum_in: EnumInEnum = EnumInEnum.BLUE,
enum_array_in: typing.Iterable[EnumInEnum] = [EnumInEnum.RED, EnumInEnum.GREEN],
protobuf_enum_in: ProtobufEnumInEnum = ProtobufEnumInEnum.BLACK,
double_2d_array_in: Double2DArray = Double2DArray(
rows=2, columns=3, data=[1, 2, 3, 4, 5, 6]
),
) -> typing.Generator[Outputs, None, None]:
"""Perform a streaming measurement.

Expand All @@ -659,6 +676,7 @@ def stream_measure(
enum_in,
enum_array_in,
protobuf_enum_in,
double_2d_array_in,
]
with self._initialization_lock:
if self._measure_response is not None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ class Color(Enum):
color_pb2.ProtobufColor.BLACK,
enum_type=color_pb2.ProtobufColor,
)
@measurement_service.configuration(
"Double 2D Array In",
nims.DataType.Double2DArray,
array_pb2.Double2DArray(rows=2, columns=3, data=[1, 2, 3, 4, 5, 6]),
)
@measurement_service.output("Float out", nims.DataType.Float)
@measurement_service.output("Double Array out", nims.DataType.DoubleArray1D)
@measurement_service.output("Bool out", nims.DataType.Boolean)
Expand Down Expand Up @@ -106,6 +111,7 @@ def measure(
enum_input: Color,
enum_array_input: Iterable[Color],
protobuf_enum_input: color_pb2.ProtobufColor.ValueType,
double_2d_array_input: array_pb2.Double2DArray,
) -> Tuple[
float,
Iterable[float],
Expand Down Expand Up @@ -138,7 +144,7 @@ def measure(
enum_output = enum_input
enum_array_output = enum_array_input
protobuf_enum_output = protobuf_enum_input
double_2d_array_output = array_pb2.Double2DArray()
double_2d_array_output = double_2d_array_input

return (
float_output,
Expand Down
16 changes: 16 additions & 0 deletions packages/service/tests/unit/test_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
TypeSpecialization,
)
from ni_measurement_plugin_sdk_service._internal.stubs.ni.protobuf.types import (
array_pb2,
xydata_pb2,
)
from tests.utilities.stubs.serialization import test_pb2
Expand Down Expand Up @@ -53,6 +54,8 @@ class Countries(IntEnum):

double_xy_data_array = [double_xy_data, double_xy_data2]

double_2d_array = array_pb2.Double2DArray(rows=2, columns=3, data=[1, 2, 3, 4, 5, 6])

# This should match the number of fields in bigmessage.proto.
BIG_MESSAGE_SIZE = 100

Expand Down Expand Up @@ -83,6 +86,7 @@ class Countries(IntEnum):
[Countries.AUSTRALIA, Countries.CANADA],
double_xy_data,
double_xy_data_array,
double_2d_array,
]
],
)
Expand Down Expand Up @@ -125,6 +129,7 @@ def test___empty_buffer___deserialize_parameters___returns_zero_or_empty():
[Countries.AUSTRALIA, Countries.CANADA],
double_xy_data,
double_xy_data_array,
double_2d_array,
]
parameter = _get_test_parameter_by_id(nonzero_defaults)
service_name = _test_create_file_descriptor(list(parameter.values()), "empty_buffer")
Expand Down Expand Up @@ -347,6 +352,14 @@ def _get_test_parameter_by_id(default_values):
annotations={},
message_type=xydata_pb2.DoubleXYData.DESCRIPTOR.full_name,
),
23: ParameterMetadata.initialize(
display_name="double_2d_array",
type=type_pb2.Field.TYPE_MESSAGE,
repeated=False,
default_value=default_values[22],
annotations={},
message_type=array_pb2.Double2DArray.DESCRIPTOR.full_name,
),
}
return parameter_by_id

Expand Down Expand Up @@ -376,6 +389,9 @@ def _get_test_grpc_message(test_values):
parameter.xy_data.x_data.append(test_values[20].x_data[0])
parameter.xy_data.y_data.append(test_values[20].y_data[0])
parameter.xy_data_array.extend(test_values[21])
parameter.double_2d_array.rows = test_values[22].rows
parameter.double_2d_array.columns = test_values[22].columns
parameter.double_2d_array.data.extend(test_values[22].data)
return parameter


Expand Down
Loading
Loading