ni.datastore 0.1.0.dev4__tar.gz → 0.1.0.dev5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/PKG-INFO +16 -10
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/README.md +10 -4
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/pyproject.toml +7 -8
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/data/__init__.py +3 -2
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/data/_data_store_client.py +302 -30
- ni_datastore-0.1.0.dev5/src/ni/datastore/data/_types/_error_information.py +73 -0
- ni_datastore-0.1.0.dev5/src/ni/datastore/data/_types/_moniker.py +69 -0
- ni_datastore-0.1.0.dev5/src/ni/datastore/data/_types/_outcome.py +53 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/data/_types/_published_condition.py +29 -11
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/data/_types/_published_measurement.py +70 -33
- ni_datastore-0.1.0.dev5/src/ni/datastore/data/_types/_step.py +190 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/data/_types/_test_result.py +81 -57
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/__init__.py +1 -1
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_metadata_store_client.py +241 -28
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/_alias.py +26 -15
- ni_datastore-0.1.0.dev5/src/ni/datastore/metadata/_types/_alias_target_type.py +75 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/_extension_schema.py +17 -8
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/_hardware_item.py +33 -13
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/_operator.py +34 -19
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/_software_item.py +28 -13
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/_test.py +34 -19
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/_test_adapter.py +35 -13
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/_test_description.py +35 -19
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/_test_station.py +37 -19
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/_uut.py +33 -13
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/_uut_instance.py +35 -13
- ni_datastore-0.1.0.dev4/src/ni/datastore/data/_types/_step.py +0 -157
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/LICENSE +0 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/__init__.py +0 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/data/_grpc_conversion.py +0 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/data/_types/__init__.py +0 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/data/_types/py.typed +0 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/data/py.typed +0 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_grpc_conversion.py +0 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/__init__.py +0 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/_types/py.typed +0 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/metadata/py.typed +0 -0
- {ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/py.typed +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: ni.datastore
|
|
3
|
-
Version: 0.1.0.
|
|
4
|
-
Summary: APIs for publishing and retrieving data from
|
|
3
|
+
Version: 0.1.0.dev5
|
|
4
|
+
Summary: APIs for publishing and retrieving data from NI Measurement Data Services
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: datastore
|
|
7
7
|
Author: NI
|
|
8
8
|
Author-email: opensource@ni.com
|
|
9
9
|
Maintainer: Johann Scholtz
|
|
10
10
|
Maintainer-email: johann.scholtz@emerson.com
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.10,<4.0
|
|
12
12
|
Classifier: Development Status :: 3 - Alpha
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
14
14
|
Classifier: Intended Audience :: Manufacturing
|
|
@@ -17,16 +17,16 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
17
17
|
Classifier: Operating System :: Microsoft :: Windows
|
|
18
18
|
Classifier: Operating System :: POSIX
|
|
19
19
|
Classifier: Programming Language :: Python :: 3
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
23
|
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
25
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
26
|
Requires-Dist: hightime (>=0.3.0.dev0)
|
|
27
27
|
Requires-Dist: ni-datamonikers-v1-client (>=0.1.0.dev1)
|
|
28
|
-
Requires-Dist: ni-measurements-data-v1-client (>=0.
|
|
29
|
-
Requires-Dist: ni-measurements-metadata-v1-client (>=0.
|
|
28
|
+
Requires-Dist: ni-measurements-data-v1-client (>=0.2.0.dev1)
|
|
29
|
+
Requires-Dist: ni-measurements-metadata-v1-client (>=0.2.0.dev1)
|
|
30
30
|
Requires-Dist: ni-protobuf-types (>=1.0.1.dev0)
|
|
31
31
|
Requires-Dist: protobuf (>=4.21)
|
|
32
32
|
Description-Content-Type: text/markdown
|
|
@@ -34,21 +34,23 @@ Description-Content-Type: text/markdown
|
|
|
34
34
|
# Table of Contents
|
|
35
35
|
|
|
36
36
|
- [Table of Contents](#table-of-contents)
|
|
37
|
+
- [Measurement Data Services API for Python](#measurement-data-services-api-for-python)
|
|
37
38
|
- [About](#about)
|
|
38
39
|
- [Operating System Support](#operating-system-support)
|
|
39
40
|
- [Python Version Support](#python-version-support)
|
|
41
|
+
- [Installation](#installation)
|
|
40
42
|
|
|
41
|
-
# Measurement Data
|
|
43
|
+
# Measurement Data Services API for Python
|
|
42
44
|
|
|
43
45
|
`datastore-python` contains Python code for writing to and reading from
|
|
44
|
-
|
|
46
|
+
[NI Measurement Data Services](https://github.com/ni/datastore-service).
|
|
45
47
|
It will include examples of how to use the Python API.
|
|
46
48
|
|
|
47
49
|
# About
|
|
48
50
|
|
|
49
51
|
`ni.datastore` is the main Python package in this repo that
|
|
50
52
|
provides APIs for publishing and retrieving data from the NI
|
|
51
|
-
Measurement Data
|
|
53
|
+
Measurement Data Services
|
|
52
54
|
|
|
53
55
|
NI created and supports this package.
|
|
54
56
|
|
|
@@ -58,10 +60,14 @@ NI created and supports this package.
|
|
|
58
60
|
|
|
59
61
|
## Python Version Support
|
|
60
62
|
|
|
61
|
-
`ni.datastore` supports CPython 3.
|
|
63
|
+
`ni.datastore` supports CPython 3.10+.
|
|
62
64
|
|
|
63
65
|
## Installation
|
|
64
66
|
|
|
67
|
+
As a prerequisite to using the `ni.datastore` module, you must install Measurement Data Services
|
|
68
|
+
Software 2026 Q1 or later on your system. You can download and install this software using
|
|
69
|
+
[NI Package Manager](https://www.ni.com/en/support/downloads/software-products/download.package-manager.html).
|
|
70
|
+
|
|
65
71
|
You can directly install the `ni.datastore` package using `pip` or by listing it as a
|
|
66
72
|
dependency in your project's `pyproject.toml` file.
|
|
67
73
|
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
# Table of Contents
|
|
2
2
|
|
|
3
3
|
- [Table of Contents](#table-of-contents)
|
|
4
|
+
- [Measurement Data Services API for Python](#measurement-data-services-api-for-python)
|
|
4
5
|
- [About](#about)
|
|
5
6
|
- [Operating System Support](#operating-system-support)
|
|
6
7
|
- [Python Version Support](#python-version-support)
|
|
8
|
+
- [Installation](#installation)
|
|
7
9
|
|
|
8
|
-
# Measurement Data
|
|
10
|
+
# Measurement Data Services API for Python
|
|
9
11
|
|
|
10
12
|
`datastore-python` contains Python code for writing to and reading from
|
|
11
|
-
|
|
13
|
+
[NI Measurement Data Services](https://github.com/ni/datastore-service).
|
|
12
14
|
It will include examples of how to use the Python API.
|
|
13
15
|
|
|
14
16
|
# About
|
|
15
17
|
|
|
16
18
|
`ni.datastore` is the main Python package in this repo that
|
|
17
19
|
provides APIs for publishing and retrieving data from the NI
|
|
18
|
-
Measurement Data
|
|
20
|
+
Measurement Data Services
|
|
19
21
|
|
|
20
22
|
NI created and supports this package.
|
|
21
23
|
|
|
@@ -25,9 +27,13 @@ NI created and supports this package.
|
|
|
25
27
|
|
|
26
28
|
## Python Version Support
|
|
27
29
|
|
|
28
|
-
`ni.datastore` supports CPython 3.
|
|
30
|
+
`ni.datastore` supports CPython 3.10+.
|
|
29
31
|
|
|
30
32
|
## Installation
|
|
31
33
|
|
|
34
|
+
As a prerequisite to using the `ni.datastore` module, you must install Measurement Data Services
|
|
35
|
+
Software 2026 Q1 or later on your system. You can download and install this software using
|
|
36
|
+
[NI Package Manager](https://www.ni.com/en/support/downloads/software-products/download.package-manager.html).
|
|
37
|
+
|
|
32
38
|
You can directly install the `ni.datastore` package using `pip` or by listing it as a
|
|
33
39
|
dependency in your project's `pyproject.toml` file.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "ni.datastore"
|
|
3
|
-
version = "0.1.0.
|
|
3
|
+
version = "0.1.0.dev5"
|
|
4
4
|
license = "MIT"
|
|
5
|
-
description = "APIs for publishing and retrieving data from
|
|
5
|
+
description = "APIs for publishing and retrieving data from NI Measurement Data Services"
|
|
6
6
|
authors = [{name = "NI", email = "opensource@ni.com"}]
|
|
7
7
|
maintainers = [
|
|
8
8
|
{name = "Johann Scholtz", email = "johann.scholtz@emerson.com"},
|
|
@@ -20,26 +20,26 @@ classifiers = [
|
|
|
20
20
|
"Operating System :: Microsoft :: Windows",
|
|
21
21
|
"Operating System :: POSIX",
|
|
22
22
|
"Programming Language :: Python :: 3",
|
|
23
|
-
"Programming Language :: Python :: 3.9",
|
|
24
23
|
"Programming Language :: Python :: 3.10",
|
|
25
24
|
"Programming Language :: Python :: 3.11",
|
|
26
25
|
"Programming Language :: Python :: 3.12",
|
|
27
26
|
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Programming Language :: Python :: 3.14",
|
|
28
28
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
29
29
|
]
|
|
30
30
|
dynamic = ["dependencies"]
|
|
31
|
-
requires-python = '>=3.
|
|
31
|
+
requires-python = '>=3.10,<4.0'
|
|
32
32
|
|
|
33
33
|
[tool.poetry]
|
|
34
34
|
packages = [{include = "ni", from = "src"}]
|
|
35
35
|
requires-poetry = '>=2.1,<3.0'
|
|
36
36
|
|
|
37
37
|
[tool.poetry.dependencies]
|
|
38
|
-
python = "^3.
|
|
38
|
+
python = "^3.10"
|
|
39
39
|
protobuf = {version=">=4.21"}
|
|
40
40
|
ni-datamonikers-v1-client = { version = ">=0.1.0.dev1", allow-prereleases = true }
|
|
41
|
-
ni-measurements-data-v1-client = { version = ">=0.
|
|
42
|
-
ni-measurements-metadata-v1-client = { version = ">=0.
|
|
41
|
+
ni-measurements-data-v1-client = { version = ">=0.2.0.dev1", allow-prereleases = true }
|
|
42
|
+
ni-measurements-metadata-v1-client = { version = ">=0.2.0.dev1", allow-prereleases = true }
|
|
43
43
|
ni-protobuf-types = { version = ">=1.0.1.dev0", allow-prereleases = true }
|
|
44
44
|
hightime = { version = ">=0.3.0.dev0", allow-prereleases = true }
|
|
45
45
|
|
|
@@ -70,7 +70,6 @@ optional = true
|
|
|
70
70
|
[tool.poetry.group.docs.dependencies]
|
|
71
71
|
# The latest Sphinx requires a recent Python version.
|
|
72
72
|
Sphinx = [
|
|
73
|
-
{ version = ">=7.4", python = ">=3.9,<3.10" },
|
|
74
73
|
{ version = ">=8.1", python = ">=3.10,<3.11" },
|
|
75
74
|
{ version = ">=8.2", python = "^3.11" },
|
|
76
75
|
]
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"""Public API for accessing the NI Data Store."""
|
|
2
2
|
|
|
3
|
-
from ni.datamonikers.v1.data_moniker_pb2 import Moniker
|
|
4
3
|
from ni.datastore.data._data_store_client import DataStoreClient
|
|
4
|
+
from ni.datastore.data._types._error_information import ErrorInformation
|
|
5
|
+
from ni.datastore.data._types._moniker import Moniker
|
|
6
|
+
from ni.datastore.data._types._outcome import Outcome
|
|
5
7
|
from ni.datastore.data._types._published_condition import PublishedCondition
|
|
6
8
|
from ni.datastore.data._types._published_measurement import PublishedMeasurement
|
|
7
9
|
from ni.datastore.data._types._step import Step
|
|
8
10
|
from ni.datastore.data._types._test_result import TestResult
|
|
9
|
-
from ni.measurements.data.v1.data_store_pb2 import ErrorInformation, Outcome
|
|
10
11
|
|
|
11
12
|
__all__ = [
|
|
12
13
|
"DataStoreClient",
|
{ni_datastore-0.1.0.dev4 → ni_datastore-0.1.0.dev5}/src/ni/datastore/data/_data_store_client.py
RENAMED
|
@@ -13,7 +13,6 @@ from urllib.parse import urlparse
|
|
|
13
13
|
import hightime as ht
|
|
14
14
|
from grpc import Channel
|
|
15
15
|
from ni.datamonikers.v1.client import MonikerClient
|
|
16
|
-
from ni.datamonikers.v1.data_moniker_pb2 import Moniker
|
|
17
16
|
from ni.datastore.data._grpc_conversion import (
|
|
18
17
|
get_publish_measurement_timestamp,
|
|
19
18
|
populate_publish_condition_batch_request_values,
|
|
@@ -22,16 +21,15 @@ from ni.datastore.data._grpc_conversion import (
|
|
|
22
21
|
populate_publish_measurement_request_value,
|
|
23
22
|
unpack_and_convert_from_protobuf_any,
|
|
24
23
|
)
|
|
24
|
+
from ni.datastore.data._types._error_information import ErrorInformation
|
|
25
|
+
from ni.datastore.data._types._moniker import Moniker
|
|
26
|
+
from ni.datastore.data._types._outcome import Outcome
|
|
25
27
|
from ni.datastore.data._types._published_condition import PublishedCondition
|
|
26
28
|
from ni.datastore.data._types._published_measurement import PublishedMeasurement
|
|
27
29
|
from ni.datastore.data._types._step import Step
|
|
28
30
|
from ni.datastore.data._types._test_result import TestResult
|
|
29
31
|
from ni.measurementlink.discovery.v1.client import DiscoveryClient
|
|
30
32
|
from ni.measurements.data.v1.client import DataStoreClient as DataStoreServiceClient
|
|
31
|
-
from ni.measurements.data.v1.data_store_pb2 import (
|
|
32
|
-
ErrorInformation,
|
|
33
|
-
Outcome,
|
|
34
|
-
)
|
|
35
33
|
from ni.measurements.data.v1.data_store_service_pb2 import (
|
|
36
34
|
CreateStepRequest,
|
|
37
35
|
CreateTestResultRequest,
|
|
@@ -151,7 +149,30 @@ class DataStoreClient:
|
|
|
151
149
|
value: object,
|
|
152
150
|
step_id: str,
|
|
153
151
|
) -> PublishedCondition:
|
|
154
|
-
"""Publish a condition value to the data store.
|
|
152
|
+
"""Publish a condition value to the data store.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
condition_name: An identifier describing the condition value.
|
|
156
|
+
For example, "Voltage" or "Temperature".
|
|
157
|
+
|
|
158
|
+
type: The type of this condition. For example, "Upper Limit",
|
|
159
|
+
"Environment", or "Setup".
|
|
160
|
+
|
|
161
|
+
value: The single value for this condition to publish on the test
|
|
162
|
+
step. This should be a scalar value that can be converted to
|
|
163
|
+
the appropriate protobuf scalar type.
|
|
164
|
+
|
|
165
|
+
step_id: The ID of the step associated with this condition. This
|
|
166
|
+
value is expected to be a parsable GUID.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
PublishedCondition: The published condition containing:
|
|
170
|
+
- A moniker for retrieving the condition data (returns a
|
|
171
|
+
Vector)
|
|
172
|
+
- The unique ID of the condition for referencing in queries
|
|
173
|
+
- Metadata including condition name, type, step ID and test
|
|
174
|
+
result ID
|
|
175
|
+
"""
|
|
155
176
|
publish_request = PublishConditionRequest(
|
|
156
177
|
condition_name=condition_name,
|
|
157
178
|
type=type,
|
|
@@ -164,7 +185,31 @@ class DataStoreClient:
|
|
|
164
185
|
def publish_condition_batch(
|
|
165
186
|
self, condition_name: str, type: str, values: object, step_id: str
|
|
166
187
|
) -> PublishedCondition:
|
|
167
|
-
"""Publish a batch of N values for a condition to the data store.
|
|
188
|
+
"""Publish a batch of N values for a condition to the data store.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
condition_name: An identifier describing the condition values.
|
|
192
|
+
For example, "Voltage" or "Temperature".
|
|
193
|
+
|
|
194
|
+
type: The type of this condition. For example, "Upper Limit",
|
|
195
|
+
"Environment", or "Setup".
|
|
196
|
+
|
|
197
|
+
values: The values for this condition across all publishes on the
|
|
198
|
+
test step. This should be a Vector of N values.
|
|
199
|
+
|
|
200
|
+
step_id: The ID of the step associated with this batch of condition
|
|
201
|
+
values. This value is expected to be a parsable GUID.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
PublishedCondition: Represents all the values published with
|
|
205
|
+
this call, containing:
|
|
206
|
+
|
|
207
|
+
- A moniker for retrieving the condition data (returns a
|
|
208
|
+
Vector)
|
|
209
|
+
- The unique ID of the condition for referencing in queries
|
|
210
|
+
- Metadata including condition name, type, step ID and test
|
|
211
|
+
result ID
|
|
212
|
+
"""
|
|
168
213
|
publish_request = PublishConditionBatchRequest(
|
|
169
214
|
condition_name=condition_name,
|
|
170
215
|
type=type,
|
|
@@ -180,19 +225,74 @@ class DataStoreClient:
|
|
|
180
225
|
value: object, # More strongly typed Union[bool, AnalogWaveform] can be used if needed
|
|
181
226
|
step_id: str,
|
|
182
227
|
timestamp: ht.datetime | None = None,
|
|
183
|
-
outcome: Outcome
|
|
228
|
+
outcome: Outcome = Outcome.UNSPECIFIED,
|
|
184
229
|
error_information: ErrorInformation | None = None,
|
|
185
230
|
hardware_item_ids: Iterable[str] = tuple(),
|
|
186
231
|
test_adapter_ids: Iterable[str] = tuple(),
|
|
187
232
|
software_item_ids: Iterable[str] = tuple(),
|
|
188
233
|
notes: str = "",
|
|
189
234
|
) -> PublishedMeasurement:
|
|
190
|
-
"""Publish a measurement value
|
|
235
|
+
"""Publish a single measurement value associated with a test step.
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
measurement_name: The name used for associating/grouping
|
|
239
|
+
conceptually alike measurements across multiple publish
|
|
240
|
+
iterations. For example, "Temperature" can be used for
|
|
241
|
+
associating temperature readings across multiple iterations.
|
|
242
|
+
|
|
243
|
+
value: The value of the measurement being published. Supported types:
|
|
244
|
+
|
|
245
|
+
- Scalar: Single float, int, str or boolean
|
|
246
|
+
- Vector: Array of float, int, str or boolean values
|
|
247
|
+
- DoubleAnalogWaveform: Analog waveform with double precision
|
|
248
|
+
- DoubleXYData: XY coordinate data with double precision
|
|
249
|
+
- I16AnalogWaveform: Analog waveform with 16-bit integer precision
|
|
250
|
+
- DoubleComplexWaveform: Complex waveform with double precision
|
|
251
|
+
- I16ComplexWaveform: Complex waveform with 16-bit integer precision
|
|
252
|
+
- DoubleSpectrum: Frequency spectrum data with double precision
|
|
253
|
+
- DigitalWaveform: Digital waveform data
|
|
254
|
+
|
|
255
|
+
step_id: The ID of the step associated with this measurement. This
|
|
256
|
+
value is expected to be a parsable GUID.
|
|
257
|
+
|
|
258
|
+
timestamp: The timestamp of the measurement. If None, the current
|
|
259
|
+
time will be used.
|
|
260
|
+
|
|
261
|
+
outcome: The outcome of the measurement (PASSED, FAILED,
|
|
262
|
+
INDETERMINATE, or UNSPECIFIED).
|
|
263
|
+
|
|
264
|
+
error_information: Error or exception information in case of
|
|
265
|
+
measurement failure.
|
|
266
|
+
|
|
267
|
+
hardware_item_ids: The IDs of the hardware items associated with
|
|
268
|
+
this measurement. These values are expected to be parsable
|
|
269
|
+
GUIDs or aliases.
|
|
270
|
+
|
|
271
|
+
test_adapter_ids: The IDs of the test adapters associated with this
|
|
272
|
+
measurement. These values are expected to be parsable GUIDs or
|
|
273
|
+
aliases.
|
|
274
|
+
|
|
275
|
+
software_item_ids: The IDs of the software items associated with
|
|
276
|
+
this measurement. These values are expected to be parsable
|
|
277
|
+
GUIDs or aliases.
|
|
278
|
+
|
|
279
|
+
notes: Any notes to be associated with the captured measurement.
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
PublishedMeasurement: The moniker of the published measurement and
|
|
283
|
+
its metadata, including:
|
|
284
|
+
- A moniker for retrieving the measurement data
|
|
285
|
+
- Associated conditions from the test step
|
|
286
|
+
- Measurement metadata (name, type, timestamps, outcome)
|
|
287
|
+
- Associated hardware, software, and test adapter IDs
|
|
288
|
+
"""
|
|
191
289
|
publish_request = PublishMeasurementRequest(
|
|
192
290
|
measurement_name=measurement_name,
|
|
193
291
|
step_id=step_id,
|
|
194
|
-
outcome=outcome,
|
|
195
|
-
error_information=
|
|
292
|
+
outcome=outcome.to_protobuf(),
|
|
293
|
+
error_information=(
|
|
294
|
+
error_information.to_protobuf() if error_information is not None else None
|
|
295
|
+
),
|
|
196
296
|
hardware_item_ids=hardware_item_ids,
|
|
197
297
|
test_adapter_ids=test_adapter_ids,
|
|
198
298
|
software_item_ids=software_item_ids,
|
|
@@ -211,22 +311,75 @@ class DataStoreClient:
|
|
|
211
311
|
values: object,
|
|
212
312
|
step_id: str,
|
|
213
313
|
timestamps: Iterable[ht.datetime] = tuple(),
|
|
214
|
-
outcomes: Iterable[Outcome
|
|
314
|
+
outcomes: Iterable[Outcome] = tuple(),
|
|
215
315
|
error_information: Iterable[ErrorInformation] = tuple(),
|
|
216
316
|
hardware_item_ids: Iterable[str] = tuple(),
|
|
217
317
|
test_adapter_ids: Iterable[str] = tuple(),
|
|
218
318
|
software_item_ids: Iterable[str] = tuple(),
|
|
319
|
+
notes: str = "",
|
|
219
320
|
) -> Sequence[PublishedMeasurement]:
|
|
220
|
-
"""Publish
|
|
321
|
+
"""Publish multiple scalar measurements at once for parametric sweeps.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
measurement_name: The name used for associating/grouping
|
|
325
|
+
conceptually alike measurements across multiple publish
|
|
326
|
+
iterations. For example, "Temperature" can be used for
|
|
327
|
+
associating temperature readings across multiple iterations.
|
|
328
|
+
|
|
329
|
+
values: The values of the (scalar) measurement being published
|
|
330
|
+
across N iterations.
|
|
331
|
+
|
|
332
|
+
step_id: The ID of the step associated with this measurement. This
|
|
333
|
+
value is expected to be a parsable GUID.
|
|
334
|
+
|
|
335
|
+
timestamps: The timestamps corresponding to the N iterations of
|
|
336
|
+
batched measurement being published. Can be empty (no timestamp
|
|
337
|
+
info), single value (applied to all), or N values (one per
|
|
338
|
+
measurement).
|
|
339
|
+
|
|
340
|
+
outcomes: The outcomes corresponding to the N iterations of batched
|
|
341
|
+
measurement being published. Can be empty (no outcome info),
|
|
342
|
+
single value (applied to all), or N values (one per
|
|
343
|
+
measurement).
|
|
344
|
+
|
|
345
|
+
error_information: The error information corresponding to the N
|
|
346
|
+
iterations of batched measurement being published. Can be empty
|
|
347
|
+
(no error info), single value (applied to all), or N values
|
|
348
|
+
(one per measurement).
|
|
349
|
+
|
|
350
|
+
hardware_item_ids: The IDs of the hardware items associated with
|
|
351
|
+
this measurement. These values are expected to be parsable
|
|
352
|
+
GUIDs or aliases.
|
|
353
|
+
|
|
354
|
+
test_adapter_ids: The IDs of the test adapters associated with this
|
|
355
|
+
measurement. These values are expected to be parsable GUIDs or
|
|
356
|
+
aliases.
|
|
357
|
+
|
|
358
|
+
software_item_ids: The IDs of the software items associated with
|
|
359
|
+
this measurement. These values are expected to be parsable
|
|
360
|
+
GUIDs or aliases.
|
|
361
|
+
|
|
362
|
+
notes: Any notes to be associated with the published measurements.
|
|
363
|
+
|
|
364
|
+
Returns:
|
|
365
|
+
Sequence[PublishedMeasurement]: The monikers of the published
|
|
366
|
+
measurements and their corresponding metadata. NOTE: Using
|
|
367
|
+
a Sequence is for future flexibility. This sequence
|
|
368
|
+
will currently always have a single PublishedMeasurement
|
|
369
|
+
returned.
|
|
370
|
+
"""
|
|
221
371
|
publish_request = PublishMeasurementBatchRequest(
|
|
222
372
|
measurement_name=measurement_name,
|
|
223
373
|
step_id=step_id,
|
|
224
|
-
|
|
225
|
-
outcome
|
|
226
|
-
error_information=
|
|
374
|
+
timestamps=[hightime_datetime_to_protobuf(ts) for ts in timestamps],
|
|
375
|
+
outcomes=[outcome.to_protobuf() for outcome in outcomes],
|
|
376
|
+
error_information=(
|
|
377
|
+
[ei.to_protobuf() for ei in (error_information or [])] if error_information else []
|
|
378
|
+
),
|
|
227
379
|
hardware_item_ids=hardware_item_ids,
|
|
228
380
|
test_adapter_ids=test_adapter_ids,
|
|
229
381
|
software_item_ids=software_item_ids,
|
|
382
|
+
notes=notes,
|
|
230
383
|
)
|
|
231
384
|
populate_publish_measurement_batch_request_values(publish_request, values)
|
|
232
385
|
publish_response = self._get_data_store_client().publish_measurement_batch(publish_request)
|
|
@@ -252,51 +405,132 @@ class DataStoreClient:
|
|
|
252
405
|
moniker_source: Moniker | PublishedMeasurement | PublishedCondition,
|
|
253
406
|
expected_type: Type[TRead] | None = None,
|
|
254
407
|
) -> TRead | object:
|
|
255
|
-
"""Read data published to the data store.
|
|
408
|
+
"""Read data published to the data store.
|
|
409
|
+
|
|
410
|
+
Args:
|
|
411
|
+
moniker_source: The source from which to read data. Can be:
|
|
412
|
+
- A Moniker (wrapper type) directly
|
|
413
|
+
- A PublishedMeasurement (uses its moniker)
|
|
414
|
+
- A PublishedCondition (uses its moniker)
|
|
415
|
+
|
|
416
|
+
expected_type: Optional type to validate the returned data against.
|
|
417
|
+
If provided, a TypeError will be raised if the actual data type
|
|
418
|
+
doesn't match.
|
|
419
|
+
|
|
420
|
+
Returns:
|
|
421
|
+
The data retrieved from the data store. The return type depends on
|
|
422
|
+
what was originally published:
|
|
423
|
+
- Scalar measurements return as Vectors
|
|
424
|
+
- Other types are returned as originally published
|
|
425
|
+
If expected_type is specified, the return value is guaranteed to be
|
|
426
|
+
of that type.
|
|
427
|
+
|
|
428
|
+
Raises:
|
|
429
|
+
ValueError: If the moniker_source doesn't have a valid moniker.
|
|
430
|
+
TypeError: If expected_type is provided and the actual data type
|
|
431
|
+
doesn't match.
|
|
432
|
+
"""
|
|
433
|
+
from ni.datamonikers.v1.data_moniker_pb2 import Moniker as MonikerProto
|
|
434
|
+
|
|
435
|
+
moniker_proto: MonikerProto
|
|
436
|
+
|
|
256
437
|
if isinstance(moniker_source, Moniker):
|
|
257
|
-
|
|
438
|
+
moniker_proto = moniker_source.to_protobuf()
|
|
258
439
|
elif isinstance(moniker_source, PublishedMeasurement):
|
|
259
440
|
if moniker_source.moniker is None:
|
|
260
441
|
raise ValueError("PublishedMeasurement must have a Moniker to read data")
|
|
261
|
-
|
|
442
|
+
moniker_proto = moniker_source.moniker.to_protobuf()
|
|
262
443
|
elif isinstance(moniker_source, PublishedCondition):
|
|
263
444
|
if moniker_source.moniker is None:
|
|
264
445
|
raise ValueError("PublishedCondition must have a Moniker to read data")
|
|
265
|
-
|
|
446
|
+
moniker_proto = moniker_source.moniker.to_protobuf()
|
|
447
|
+
else:
|
|
448
|
+
raise TypeError(f"Unsupported moniker_source type: {type(moniker_source)}")
|
|
266
449
|
|
|
267
|
-
moniker_client = self._get_moniker_client(
|
|
268
|
-
read_result = moniker_client.read_from_moniker(
|
|
450
|
+
moniker_client = self._get_moniker_client(moniker_proto.service_location)
|
|
451
|
+
read_result = moniker_client.read_from_moniker(moniker_proto)
|
|
269
452
|
converted_data = unpack_and_convert_from_protobuf_any(read_result.value)
|
|
270
453
|
if expected_type is not None and not isinstance(converted_data, expected_type):
|
|
271
454
|
raise TypeError(f"Expected type {expected_type}, got {type(converted_data)}")
|
|
272
455
|
return converted_data
|
|
273
456
|
|
|
274
457
|
def create_step(self, step: Step) -> str:
|
|
275
|
-
"""Create a step in the data store.
|
|
458
|
+
"""Create a new step in the data store.
|
|
459
|
+
|
|
460
|
+
A step is owned by a test result and is a logical grouping of published
|
|
461
|
+
measurements and conditions. All measurements and conditions must be
|
|
462
|
+
associated with a step.
|
|
463
|
+
|
|
464
|
+
Args:
|
|
465
|
+
step: The metadata of the step to be created.
|
|
466
|
+
|
|
467
|
+
Returns:
|
|
468
|
+
str: The identifier of the created step.
|
|
469
|
+
"""
|
|
276
470
|
create_request = CreateStepRequest(step=step.to_protobuf())
|
|
277
471
|
create_response = self._get_data_store_client().create_step(create_request)
|
|
278
472
|
return create_response.step_id
|
|
279
473
|
|
|
280
474
|
def get_step(self, step_id: str) -> Step:
|
|
281
|
-
"""Get
|
|
475
|
+
"""Get the step associated with the given identifier.
|
|
476
|
+
|
|
477
|
+
Args:
|
|
478
|
+
step_id: The identifier of the desired step.
|
|
479
|
+
|
|
480
|
+
Returns:
|
|
481
|
+
Step: The metadata of the requested step.
|
|
482
|
+
"""
|
|
282
483
|
get_request = GetStepRequest(step_id=step_id)
|
|
283
484
|
get_response = self._get_data_store_client().get_step(get_request)
|
|
284
485
|
return Step.from_protobuf(get_response.step)
|
|
285
486
|
|
|
286
487
|
def create_test_result(self, test_result: TestResult) -> str:
|
|
287
|
-
"""Create a test result
|
|
488
|
+
"""Create a test result object for publishing measurements.
|
|
489
|
+
|
|
490
|
+
Once a test result is created, you can publish an arbitrary number of
|
|
491
|
+
measurements and conditions to a step which is owned by the test result.
|
|
492
|
+
|
|
493
|
+
Args:
|
|
494
|
+
test_result: The metadata of the test result to be created.
|
|
495
|
+
|
|
496
|
+
Returns:
|
|
497
|
+
str: The test result ID. Generated if not specified in the request.
|
|
498
|
+
"""
|
|
288
499
|
create_request = CreateTestResultRequest(test_result=test_result.to_protobuf())
|
|
289
500
|
create_response = self._get_data_store_client().create_test_result(create_request)
|
|
290
501
|
return create_response.test_result_id
|
|
291
502
|
|
|
292
503
|
def get_test_result(self, test_result_id: str) -> TestResult:
|
|
293
|
-
"""Get
|
|
504
|
+
"""Get the test result associated with the given identifier.
|
|
505
|
+
|
|
506
|
+
Args:
|
|
507
|
+
test_result_id: The ID of the desired test result. This value is
|
|
508
|
+
expected to be a parsable GUID.
|
|
509
|
+
|
|
510
|
+
Returns:
|
|
511
|
+
TestResult: The TestResult object that corresponds to the
|
|
512
|
+
requested ID.
|
|
513
|
+
"""
|
|
294
514
|
get_request = GetTestResultRequest(test_result_id=test_result_id)
|
|
295
515
|
get_response = self._get_data_store_client().get_test_result(get_request)
|
|
296
516
|
return TestResult.from_protobuf(get_response.test_result)
|
|
297
517
|
|
|
298
518
|
def query_conditions(self, odata_query: str = "") -> Sequence[PublishedCondition]:
|
|
299
|
-
"""Query conditions
|
|
519
|
+
"""Query conditions using OData query syntax.
|
|
520
|
+
|
|
521
|
+
Args:
|
|
522
|
+
odata_query: An OData query string. Example: "$filter=name eq
|
|
523
|
+
'Value'". An empty string will return all conditions. $expand,
|
|
524
|
+
$count, and $select are not supported. For more information,
|
|
525
|
+
see https://learn.microsoft.com/en-us/odata/concepts/
|
|
526
|
+
queryoptions-overview.
|
|
527
|
+
|
|
528
|
+
Returns:
|
|
529
|
+
Sequence[PublishedCondition]: The list of matching conditions. Each
|
|
530
|
+
item contains a moniker for retrieving the condition
|
|
531
|
+
measurements, as well as the metadata associated with the
|
|
532
|
+
condition.
|
|
533
|
+
"""
|
|
300
534
|
query_request = QueryConditionsRequest(odata_query=odata_query)
|
|
301
535
|
query_response = self._get_data_store_client().query_conditions(query_request)
|
|
302
536
|
return [
|
|
@@ -305,7 +539,20 @@ class DataStoreClient:
|
|
|
305
539
|
]
|
|
306
540
|
|
|
307
541
|
def query_measurements(self, odata_query: str = "") -> Sequence[PublishedMeasurement]:
|
|
308
|
-
"""Query measurements
|
|
542
|
+
"""Query measurements using OData query syntax.
|
|
543
|
+
|
|
544
|
+
Args:
|
|
545
|
+
odata_query: An OData query string. Example: "$filter=name eq
|
|
546
|
+
'Value'". An empty string will return all measurements.
|
|
547
|
+
$expand, $count, and $select are not supported. For more
|
|
548
|
+
information, see https://learn.microsoft.com/en-us/odata/
|
|
549
|
+
concepts/queryoptions-overview.
|
|
550
|
+
|
|
551
|
+
Returns:
|
|
552
|
+
Sequence[PublishedMeasurement]: The list of matching measurements.
|
|
553
|
+
Each item contains a moniker for retrieving the measurement, as
|
|
554
|
+
well as the metadata associated with the measurement.
|
|
555
|
+
"""
|
|
309
556
|
query_request = QueryMeasurementsRequest(odata_query=odata_query)
|
|
310
557
|
query_response = self._get_data_store_client().query_measurements(query_request)
|
|
311
558
|
return [
|
|
@@ -314,7 +561,21 @@ class DataStoreClient:
|
|
|
314
561
|
]
|
|
315
562
|
|
|
316
563
|
def query_test_results(self, odata_query: str = "") -> Sequence[TestResult]:
|
|
317
|
-
"""Query test results
|
|
564
|
+
"""Query test results using OData query syntax.
|
|
565
|
+
|
|
566
|
+
Args:
|
|
567
|
+
odata_query: An OData query string. Example: "$filter=name eq
|
|
568
|
+
'Value'". An empty string will return all test results.
|
|
569
|
+
$expand, $count, and $select are not supported. For more
|
|
570
|
+
information, see https://learn.microsoft.com/en-us/odata/
|
|
571
|
+
concepts/queryoptions-overview.
|
|
572
|
+
|
|
573
|
+
Returns:
|
|
574
|
+
Sequence[TestResult]: The list of matching test results. Each
|
|
575
|
+
item contains the metadata associated with the test result,
|
|
576
|
+
including test result ID, name, timestamps, and other
|
|
577
|
+
properties.
|
|
578
|
+
"""
|
|
318
579
|
query_request = QueryTestResultsRequest(odata_query=odata_query)
|
|
319
580
|
query_response = self._get_data_store_client().query_test_results(query_request)
|
|
320
581
|
return [
|
|
@@ -322,7 +583,18 @@ class DataStoreClient:
|
|
|
322
583
|
]
|
|
323
584
|
|
|
324
585
|
def query_steps(self, odata_query: str = "") -> Sequence[Step]:
|
|
325
|
-
"""Query steps
|
|
586
|
+
"""Query for steps matching the given OData query.
|
|
587
|
+
|
|
588
|
+
Args:
|
|
589
|
+
odata_query: An OData query string. Example: "$filter=name eq
|
|
590
|
+
'Value'". An empty string will return all steps. $expand,
|
|
591
|
+
$count, and $select are not supported. For more information,
|
|
592
|
+
see https://learn.microsoft.com/en-us/odata/concepts/
|
|
593
|
+
queryoptions-overview.
|
|
594
|
+
|
|
595
|
+
Returns:
|
|
596
|
+
Sequence[Step]: The list of steps that match the query.
|
|
597
|
+
"""
|
|
326
598
|
query_request = QueryStepsRequest(odata_query=odata_query)
|
|
327
599
|
query_response = self._get_data_store_client().query_steps(query_request)
|
|
328
600
|
return [Step.from_protobuf(step) for step in query_response.steps]
|