ni.measurementlink.sessionmanagement.v1.client 0.1.0.dev0__py3-none-any.whl

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.

Potentially problematic release.


This version of ni.measurementlink.sessionmanagement.v1.client might be problematic. Click here for more details.

Files changed (20) hide show
  1. ni/measurementlink/sessionmanagement/v1/client/__init__.py +107 -0
  2. ni/measurementlink/sessionmanagement/v1/client/_client.py +405 -0
  3. ni/measurementlink/sessionmanagement/v1/client/_constants.py +32 -0
  4. ni/measurementlink/sessionmanagement/v1/client/_drivers/__init__.py +46 -0
  5. ni/measurementlink/sessionmanagement/v1/client/_drivers/_configuration.py +111 -0
  6. ni/measurementlink/sessionmanagement/v1/client/_drivers/_dotenvpath.py +73 -0
  7. ni/measurementlink/sessionmanagement/v1/client/_drivers/_grpcdevice.py +96 -0
  8. ni/measurementlink/sessionmanagement/v1/client/_drivers/_nidaqmx.py +54 -0
  9. ni/measurementlink/sessionmanagement/v1/client/_drivers/_nidcpower.py +63 -0
  10. ni/measurementlink/sessionmanagement/v1/client/_drivers/_nidigital.py +64 -0
  11. ni/measurementlink/sessionmanagement/v1/client/_drivers/_nidmm.py +64 -0
  12. ni/measurementlink/sessionmanagement/v1/client/_drivers/_nifgen.py +63 -0
  13. ni/measurementlink/sessionmanagement/v1/client/_drivers/_niscope.py +64 -0
  14. ni/measurementlink/sessionmanagement/v1/client/_drivers/_niswitch.py +82 -0
  15. ni/measurementlink/sessionmanagement/v1/client/_reservation.py +2769 -0
  16. ni/measurementlink/sessionmanagement/v1/client/_types.py +507 -0
  17. ni/measurementlink/sessionmanagement/v1/client/py.typed +0 -0
  18. ni_measurementlink_sessionmanagement_v1_client-0.1.0.dev0.dist-info/METADATA +80 -0
  19. ni_measurementlink_sessionmanagement_v1_client-0.1.0.dev0.dist-info/RECORD +20 -0
  20. ni_measurementlink_sessionmanagement_v1_client-0.1.0.dev0.dist-info/WHEEL +4 -0
@@ -0,0 +1,111 @@
1
+ """Measurement plug-in configuration options."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from typing import TYPE_CHECKING, Any, Callable, NamedTuple, TypeVar
7
+
8
+ from decouple import AutoConfig, Undefined, undefined
9
+
10
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._dotenvpath import (
11
+ get_dotenv_search_path,
12
+ )
13
+
14
+ if TYPE_CHECKING:
15
+ if sys.version_info >= (3, 11):
16
+ from typing import Self
17
+ else:
18
+ from typing_extensions import Self
19
+
20
+
21
+ _PREFIX = "MEASUREMENT_PLUGIN"
22
+
23
+ _config = AutoConfig(str(get_dotenv_search_path()))
24
+
25
+ if TYPE_CHECKING:
26
+ # Work around decouple's lack of type hints.
27
+ _T = TypeVar("_T")
28
+
29
+ def _config(
30
+ option: str,
31
+ default: _T | Undefined = undefined,
32
+ cast: Callable[[str], _T] | Undefined = undefined,
33
+ ) -> _T: ...
34
+
35
+
36
+ # ----------------------------------------------------------------------
37
+ # NI Modular Instrument Driver Options
38
+ # ----------------------------------------------------------------------
39
+ class MIDriverOptions(NamedTuple):
40
+ """Modular instrument driver options."""
41
+
42
+ driver_name: str
43
+ """The driver name."""
44
+
45
+ simulate: bool = False
46
+ """Specifies whether to simulate session operations."""
47
+
48
+ board_type: str = ""
49
+ """The simulated board type (bus)."""
50
+
51
+ model: str = ""
52
+ """The simulated instrument model."""
53
+
54
+ def update_from_config(self) -> Self:
55
+ """Read options from the configuration file and return a new options object."""
56
+ prefix = f"{_PREFIX}_{self.driver_name.upper()}"
57
+ return self._replace(
58
+ simulate=_config(f"{prefix}_SIMULATE", default=self.simulate, cast=bool),
59
+ board_type=_config(f"{prefix}_BOARD_TYPE", default=self.board_type),
60
+ model=_config(f"{prefix}_MODEL", default=self.model),
61
+ )
62
+
63
+ def to_dict(self) -> dict[str, Any]:
64
+ """Convert options to a dict to pass to nimi-python."""
65
+ options: dict[str, Any] = {}
66
+ if self.simulate:
67
+ options["simulate"] = True
68
+ if self.board_type or self.model:
69
+ options["driver_setup"] = {}
70
+ if self.board_type:
71
+ options["driver_setup"]["BoardType"] = self.board_type
72
+ if self.model:
73
+ options["driver_setup"]["Model"] = self.model
74
+ return options
75
+
76
+
77
+ class NISwitchOptions(NamedTuple):
78
+ """NI-SWITCH driver options."""
79
+
80
+ driver_name: str
81
+ """The driver name."""
82
+
83
+ simulate: bool = False
84
+ """Specifies whether to simulate session operations."""
85
+
86
+ topology: str = "Configured Topology"
87
+ """The default topology."""
88
+
89
+ def update_from_config(self) -> Self:
90
+ """Read options from the configuration file and return a new options object."""
91
+ prefix = f"{_PREFIX}_{self.driver_name.upper()}"
92
+ return self._replace(
93
+ simulate=_config(f"{prefix}_SIMULATE", default=self.simulate, cast=bool),
94
+ topology=_config(f"{prefix}_TOPOLOGY", default=self.topology),
95
+ )
96
+
97
+
98
+ NIDCPOWER_OPTIONS = MIDriverOptions("nidcpower").update_from_config()
99
+ NIDIGITAL_OPTIONS = MIDriverOptions("nidigital").update_from_config()
100
+ NIDMM_OPTIONS = MIDriverOptions("nidmm").update_from_config()
101
+ NIFGEN_OPTIONS = MIDriverOptions("nifgen").update_from_config()
102
+ NISCOPE_OPTIONS = MIDriverOptions("niscope").update_from_config()
103
+ NISWITCH_OPTIONS = NISwitchOptions("niswitch").update_from_config()
104
+ NISWITCH_MULTIPLEXER_OPTIONS = NISwitchOptions("niswitch_multiplexer").update_from_config()
105
+
106
+
107
+ # ----------------------------------------------------------------------
108
+ # NI gRPC Device Server Configuration
109
+ # ----------------------------------------------------------------------
110
+ USE_GRPC_DEVICE_SERVER: bool = _config(f"{_PREFIX}_USE_GRPC_DEVICE_SERVER", default=True, cast=bool)
111
+ GRPC_DEVICE_SERVER_ADDRESS: str = _config(f"{_PREFIX}_GRPC_DEVICE_SERVER_ADDRESS", default="")
@@ -0,0 +1,73 @@
1
+ from __future__ import annotations
2
+
3
+ import inspect
4
+ import sys
5
+ import traceback
6
+ from pathlib import Path
7
+
8
+
9
+ def get_dotenv_search_path() -> Path:
10
+ """Get the search path for loading the `.env` file."""
11
+ # Prefer to load the `.env` file from the current directory or its parents.
12
+ # If the current directory doesn't have a `.env` file, fall back to the
13
+ # script/EXE path or the TestStand code module path.
14
+ cwd = Path.cwd()
15
+ if not _has_dotenv_file(cwd):
16
+ if script_or_exe_path := _get_script_or_exe_path():
17
+ return script_or_exe_path.resolve().parent
18
+ if caller_path := _get_caller_path():
19
+ return caller_path.resolve().parent
20
+ return cwd
21
+
22
+
23
+ def _has_dotenv_file(dir: Path) -> bool:
24
+ """Check whether the dir or its parents contains a `.env` file."""
25
+ return (dir / ".env").exists() or any((p / ".env").exists() for p in dir.parents)
26
+
27
+
28
+ def _get_script_or_exe_path() -> Path | None:
29
+ """Get the path of the top-level script or PyInstaller EXE, if possible."""
30
+ if getattr(sys, "frozen", False):
31
+ return Path(sys.executable)
32
+
33
+ main_module = sys.modules.get("__main__")
34
+ if main_module:
35
+ script_path = getattr(main_module, "__file__", "")
36
+ if script_path:
37
+ return Path(script_path)
38
+
39
+ return None
40
+
41
+
42
+ def _get_caller_path() -> Path | None:
43
+ """Get the path of the module calling into this package, if possible."""
44
+ package_path = _get_package_path()
45
+ for frame, _ in traceback.walk_stack(inspect.currentframe()):
46
+ if frame.f_code.co_filename:
47
+ module_path = Path(frame.f_code.co_filename)
48
+ if _exists(module_path) and not module_path.is_relative_to(package_path):
49
+ return module_path
50
+
51
+ return None
52
+
53
+
54
+ # Path.exists() throws OSError when the path has invalid file characters.
55
+ # https://github.com/python/cpython/issues/79487
56
+ if sys.version_info >= (3, 10):
57
+
58
+ def _exists(path: Path) -> bool:
59
+ return path.exists()
60
+
61
+ else:
62
+
63
+ def _exists(path: Path) -> bool:
64
+ import os
65
+
66
+ return os.path.exists(path)
67
+
68
+
69
+ def _get_package_path() -> Path:
70
+ """Get the path of this package."""
71
+ package = sys.modules[__package__] # pyright: ignore[reportArgumentType]
72
+ assert package.__file__ and package.__file__.endswith("__init__.py")
73
+ return Path(package.__file__).parent
@@ -0,0 +1,96 @@
1
+ """Shared functions for interacting with NI gRPC Device Server."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ from urllib.parse import urlsplit
7
+
8
+ import grpc
9
+ from ni.measurementlink.discovery.v1.client import DiscoveryClient, ServiceLocation
10
+ from ni_grpc_extensions.channelpool import GrpcChannelPool
11
+
12
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._configuration import (
13
+ GRPC_DEVICE_SERVER_ADDRESS,
14
+ USE_GRPC_DEVICE_SERVER,
15
+ )
16
+
17
+ _logger = logging.getLogger(__name__)
18
+
19
+ SERVICE_CLASS = "ni.measurementlink.v1.grpcdeviceserver"
20
+ """The service class for NI gRPC Device Server."""
21
+
22
+
23
+ def get_grpc_device_server_location(
24
+ discovery_client: DiscoveryClient,
25
+ provided_interface: str,
26
+ ) -> ServiceLocation | None:
27
+ """Get an address targeting NI gRPC Device Server for unencrypted communication."""
28
+ if not USE_GRPC_DEVICE_SERVER:
29
+ _logger.debug("Not using NI gRPC Device Server")
30
+ return None
31
+
32
+ if GRPC_DEVICE_SERVER_ADDRESS:
33
+ service_location = _parse_url_to_service_location(GRPC_DEVICE_SERVER_ADDRESS)
34
+ _logger.debug(
35
+ "NI gRPC Device Server location (from GRPC_DEVICE_SERVER_ADDRESS): %r", service_location
36
+ )
37
+ return service_location
38
+
39
+ compute_nodes = discovery_client.enumerate_compute_nodes()
40
+ remote_compute_nodes = [node for node in compute_nodes if not node.is_local]
41
+ # Use remote node URL as deployment target if only one remote node is found.
42
+ # If more than one remote node exists, use empty string for deployment target.
43
+ first_remote_node_url = remote_compute_nodes[0].url if len(remote_compute_nodes) == 1 else ""
44
+ service_location = discovery_client.resolve_service(
45
+ provided_interface=provided_interface,
46
+ deployment_target=first_remote_node_url,
47
+ service_class=SERVICE_CLASS,
48
+ )
49
+ _logger.debug(
50
+ "NI gRPC Device Server location (for interface '%s'): %r",
51
+ provided_interface,
52
+ service_location,
53
+ )
54
+ return service_location
55
+
56
+
57
+ def _parse_url_to_service_location(url: str) -> ServiceLocation:
58
+ parsed_url = urlsplit(url)
59
+
60
+ if parsed_url.scheme not in ("http", "https"):
61
+ raise ValueError(f"Unsupported URL scheme '{parsed_url.scheme}' in '{url}'")
62
+ if parsed_url.path not in ("", "/"):
63
+ raise ValueError(f"Unsupported path '{parsed_url.path}' in '{url}'")
64
+ if parsed_url.query:
65
+ raise ValueError(f"Unsupported query '?{parsed_url.query}' in '{url}'")
66
+ if parsed_url.fragment:
67
+ raise ValueError(f"Unsupported fragment '#{parsed_url.fragment}' in '{url}'")
68
+ if parsed_url.hostname is None:
69
+ raise ValueError(f"No host specified in '{url}'")
70
+ if parsed_url.port is None:
71
+ raise ValueError(f"No port number specified in '{url}'")
72
+
73
+ host = parsed_url.hostname
74
+ port = str(parsed_url.port)
75
+ if "[" in parsed_url.netloc and "]" in parsed_url.netloc:
76
+ # Preserve IPv6 address brackets
77
+ host = "[" + host + "]"
78
+
79
+ if parsed_url.scheme == "http":
80
+ return ServiceLocation(location=host, insecure_port=port, ssl_authenticated_port="")
81
+ else:
82
+ return ServiceLocation(location=host, insecure_port="", ssl_authenticated_port=port)
83
+
84
+
85
+ def get_insecure_grpc_device_server_channel(
86
+ discovery_client: DiscoveryClient,
87
+ grpc_channel_pool: GrpcChannelPool,
88
+ provided_interface: str,
89
+ ) -> grpc.Channel | None:
90
+ """Get an unencrypted gRPC channel targeting NI gRPC Device Server."""
91
+ service_location = get_grpc_device_server_location(discovery_client, provided_interface)
92
+ if not service_location:
93
+ return None
94
+ if not service_location.insecure_port:
95
+ raise ValueError(f"No insecure port specified in {service_location!r}")
96
+ return grpc_channel_pool.get_channel(service_location.insecure_address)
@@ -0,0 +1,54 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import nidaqmx
6
+ from ni.measurementlink.discovery.v1.client import DiscoveryClient
7
+ from ni_grpc_extensions.channelpool import GrpcChannelPool
8
+
9
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._grpcdevice import (
10
+ get_insecure_grpc_device_server_channel,
11
+ )
12
+ from ni.measurementlink.sessionmanagement.v1.client._types import (
13
+ SessionInformation,
14
+ SessionInitializationBehavior,
15
+ )
16
+
17
+ _INITIALIZATION_BEHAVIOR = {
18
+ SessionInitializationBehavior.AUTO: nidaqmx.SessionInitializationBehavior.AUTO,
19
+ SessionInitializationBehavior.INITIALIZE_SERVER_SESSION: nidaqmx.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
20
+ SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION: nidaqmx.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
21
+ SessionInitializationBehavior.INITIALIZE_SESSION_THEN_DETACH: nidaqmx.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
22
+ SessionInitializationBehavior.ATTACH_TO_SESSION_THEN_CLOSE: nidaqmx.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
23
+ }
24
+
25
+
26
+ class SessionConstructor:
27
+ """Constructs sessions based on SessionInformation."""
28
+
29
+ def __init__(
30
+ self,
31
+ discovery_client: DiscoveryClient,
32
+ grpc_channel_pool: GrpcChannelPool,
33
+ initialization_behavior: SessionInitializationBehavior,
34
+ ) -> None:
35
+ """Initialize the session constructor."""
36
+ self._grpc_channel = get_insecure_grpc_device_server_channel(
37
+ discovery_client, grpc_channel_pool, nidaqmx.GRPC_SERVICE_INTERFACE_NAME
38
+ )
39
+ self._initialization_behavior = _INITIALIZATION_BEHAVIOR[initialization_behavior]
40
+
41
+ def __call__(self, session_info: SessionInformation) -> nidaqmx.Task:
42
+ """Construct a session object."""
43
+ kwargs: dict[str, Any] = {}
44
+ if self._grpc_channel:
45
+ kwargs["grpc_options"] = nidaqmx.GrpcSessionOptions(
46
+ grpc_channel=self._grpc_channel,
47
+ session_name=session_info.session_name,
48
+ initialization_behavior=self._initialization_behavior,
49
+ )
50
+
51
+ return nidaqmx.Task(
52
+ new_task_name=session_info.session_name,
53
+ **kwargs,
54
+ )
@@ -0,0 +1,63 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import nidcpower
6
+ from ni.measurementlink.discovery.v1.client import DiscoveryClient
7
+ from ni_grpc_extensions.channelpool import GrpcChannelPool
8
+
9
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._configuration import (
10
+ NIDCPOWER_OPTIONS,
11
+ )
12
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._grpcdevice import (
13
+ get_insecure_grpc_device_server_channel,
14
+ )
15
+ from ni.measurementlink.sessionmanagement.v1.client._types import (
16
+ SessionInformation,
17
+ SessionInitializationBehavior,
18
+ )
19
+
20
+ _INITIALIZATION_BEHAVIOR = {
21
+ SessionInitializationBehavior.AUTO: nidcpower.SessionInitializationBehavior.AUTO,
22
+ SessionInitializationBehavior.INITIALIZE_SERVER_SESSION: nidcpower.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
23
+ SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION: nidcpower.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
24
+ SessionInitializationBehavior.INITIALIZE_SESSION_THEN_DETACH: nidcpower.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
25
+ SessionInitializationBehavior.ATTACH_TO_SESSION_THEN_CLOSE: nidcpower.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
26
+ }
27
+
28
+
29
+ class SessionConstructor:
30
+ """Constructs sessions based on SessionInformation."""
31
+
32
+ def __init__(
33
+ self,
34
+ discovery_client: DiscoveryClient,
35
+ grpc_channel_pool: GrpcChannelPool,
36
+ reset: bool,
37
+ options: dict[str, Any] | None,
38
+ initialization_behavior: SessionInitializationBehavior,
39
+ ) -> None:
40
+ """Initialize the session constructor."""
41
+ self._grpc_channel = get_insecure_grpc_device_server_channel(
42
+ discovery_client, grpc_channel_pool, nidcpower.GRPC_SERVICE_INTERFACE_NAME
43
+ )
44
+ self._reset = reset
45
+ self._options = NIDCPOWER_OPTIONS.to_dict() if options is None else options
46
+ self._initialization_behavior = _INITIALIZATION_BEHAVIOR[initialization_behavior]
47
+
48
+ def __call__(self, session_info: SessionInformation) -> nidcpower.Session:
49
+ """Construct a session object."""
50
+ kwargs: dict[str, Any] = {}
51
+ if self._grpc_channel:
52
+ kwargs["grpc_options"] = nidcpower.GrpcSessionOptions(
53
+ grpc_channel=self._grpc_channel,
54
+ session_name=session_info.session_name,
55
+ initialization_behavior=self._initialization_behavior,
56
+ )
57
+
58
+ return nidcpower.Session(
59
+ resource_name=session_info.resource_name,
60
+ reset=self._reset,
61
+ options=self._options,
62
+ **kwargs,
63
+ )
@@ -0,0 +1,64 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import nidigital
6
+ from ni.measurementlink.discovery.v1.client import DiscoveryClient
7
+ from ni_grpc_extensions.channelpool import GrpcChannelPool
8
+
9
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._configuration import (
10
+ NIDIGITAL_OPTIONS,
11
+ )
12
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._grpcdevice import (
13
+ get_insecure_grpc_device_server_channel,
14
+ )
15
+ from ni.measurementlink.sessionmanagement.v1.client._types import (
16
+ SessionInformation,
17
+ SessionInitializationBehavior,
18
+ )
19
+
20
+ _INITIALIZATION_BEHAVIOR = {
21
+ SessionInitializationBehavior.AUTO: nidigital.SessionInitializationBehavior.AUTO,
22
+ SessionInitializationBehavior.INITIALIZE_SERVER_SESSION: nidigital.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
23
+ SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION: nidigital.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
24
+ SessionInitializationBehavior.INITIALIZE_SESSION_THEN_DETACH: nidigital.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
25
+ SessionInitializationBehavior.ATTACH_TO_SESSION_THEN_CLOSE: nidigital.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
26
+ }
27
+
28
+
29
+ class SessionConstructor:
30
+ """Constructs sessions based on SessionInformation."""
31
+
32
+ def __init__(
33
+ self,
34
+ discovery_client: DiscoveryClient,
35
+ grpc_channel_pool: GrpcChannelPool,
36
+ reset_device: bool,
37
+ options: dict[str, Any] | None,
38
+ initialization_behavior: SessionInitializationBehavior,
39
+ ) -> None:
40
+ """Initialize the session constructor."""
41
+ self._grpc_channel = get_insecure_grpc_device_server_channel(
42
+ discovery_client, grpc_channel_pool, nidigital.GRPC_SERVICE_INTERFACE_NAME
43
+ )
44
+ self._reset_device = reset_device
45
+ self._options = NIDIGITAL_OPTIONS.to_dict() if options is None else options
46
+ self._initialization_behavior = _INITIALIZATION_BEHAVIOR[initialization_behavior]
47
+
48
+ def __call__(self, session_info: SessionInformation) -> nidigital.Session:
49
+ """Construct a session object."""
50
+ kwargs: dict[str, Any] = {}
51
+ if self._grpc_channel:
52
+ kwargs["grpc_options"] = nidigital.GrpcSessionOptions(
53
+ grpc_channel=self._grpc_channel,
54
+ session_name=session_info.session_name,
55
+ initialization_behavior=self._initialization_behavior,
56
+ )
57
+
58
+ # Omit id_query because it has no effect.
59
+ return nidigital.Session(
60
+ resource_name=session_info.resource_name,
61
+ reset_device=self._reset_device,
62
+ options=self._options,
63
+ **kwargs,
64
+ )
@@ -0,0 +1,64 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import nidmm
6
+ from ni.measurementlink.discovery.v1.client import DiscoveryClient
7
+ from ni_grpc_extensions.channelpool import GrpcChannelPool
8
+
9
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._configuration import (
10
+ NIDMM_OPTIONS,
11
+ )
12
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._grpcdevice import (
13
+ get_insecure_grpc_device_server_channel,
14
+ )
15
+ from ni.measurementlink.sessionmanagement.v1.client._types import (
16
+ SessionInformation,
17
+ SessionInitializationBehavior,
18
+ )
19
+
20
+ _INITIALIZATION_BEHAVIOR = {
21
+ SessionInitializationBehavior.AUTO: nidmm.SessionInitializationBehavior.AUTO,
22
+ SessionInitializationBehavior.INITIALIZE_SERVER_SESSION: nidmm.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
23
+ SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION: nidmm.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
24
+ SessionInitializationBehavior.INITIALIZE_SESSION_THEN_DETACH: nidmm.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
25
+ SessionInitializationBehavior.ATTACH_TO_SESSION_THEN_CLOSE: nidmm.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
26
+ }
27
+
28
+
29
+ class SessionConstructor:
30
+ """Constructs sessions based on SessionInformation."""
31
+
32
+ def __init__(
33
+ self,
34
+ discovery_client: DiscoveryClient,
35
+ grpc_channel_pool: GrpcChannelPool,
36
+ reset_device: bool,
37
+ options: dict[str, Any] | None,
38
+ initialization_behavior: SessionInitializationBehavior,
39
+ ) -> None:
40
+ """Initialize the session constructor."""
41
+ self._grpc_channel = get_insecure_grpc_device_server_channel(
42
+ discovery_client, grpc_channel_pool, nidmm.GRPC_SERVICE_INTERFACE_NAME
43
+ )
44
+ self._reset_device = reset_device
45
+ self._options = NIDMM_OPTIONS.to_dict() if options is None else options
46
+ self._initialization_behavior = _INITIALIZATION_BEHAVIOR[initialization_behavior]
47
+
48
+ def __call__(self, session_info: SessionInformation) -> nidmm.Session:
49
+ """Construct a session object."""
50
+ kwargs: dict[str, Any] = {}
51
+ if self._grpc_channel:
52
+ kwargs["grpc_options"] = nidmm.GrpcSessionOptions(
53
+ grpc_channel=self._grpc_channel,
54
+ session_name=session_info.session_name,
55
+ initialization_behavior=self._initialization_behavior,
56
+ )
57
+
58
+ # Omit id_query because it has no effect.
59
+ return nidmm.Session(
60
+ resource_name=session_info.resource_name,
61
+ reset_device=self._reset_device,
62
+ options=self._options,
63
+ **kwargs,
64
+ )
@@ -0,0 +1,63 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import nifgen
6
+ from ni.measurementlink.discovery.v1.client import DiscoveryClient
7
+ from ni_grpc_extensions.channelpool import GrpcChannelPool
8
+
9
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._configuration import (
10
+ NIFGEN_OPTIONS,
11
+ )
12
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._grpcdevice import (
13
+ get_insecure_grpc_device_server_channel,
14
+ )
15
+ from ni.measurementlink.sessionmanagement.v1.client._types import (
16
+ SessionInformation,
17
+ SessionInitializationBehavior,
18
+ )
19
+
20
+ _INITIALIZATION_BEHAVIOR = {
21
+ SessionInitializationBehavior.AUTO: nifgen.SessionInitializationBehavior.AUTO,
22
+ SessionInitializationBehavior.INITIALIZE_SERVER_SESSION: nifgen.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
23
+ SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION: nifgen.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
24
+ SessionInitializationBehavior.INITIALIZE_SESSION_THEN_DETACH: nifgen.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
25
+ SessionInitializationBehavior.ATTACH_TO_SESSION_THEN_CLOSE: nifgen.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
26
+ }
27
+
28
+
29
+ class SessionConstructor:
30
+ """Constructs sessions based on SessionInformation."""
31
+
32
+ def __init__(
33
+ self,
34
+ discovery_client: DiscoveryClient,
35
+ grpc_channel_pool: GrpcChannelPool,
36
+ reset_device: bool,
37
+ options: dict[str, Any] | None,
38
+ initialization_behavior: SessionInitializationBehavior,
39
+ ) -> None:
40
+ """Initialize the session constructor."""
41
+ self._grpc_channel = get_insecure_grpc_device_server_channel(
42
+ discovery_client, grpc_channel_pool, nifgen.GRPC_SERVICE_INTERFACE_NAME
43
+ )
44
+ self._reset_device = reset_device
45
+ self._options = NIFGEN_OPTIONS.to_dict() if options is None else options
46
+ self._initialization_behavior = _INITIALIZATION_BEHAVIOR[initialization_behavior]
47
+
48
+ def __call__(self, session_info: SessionInformation) -> nifgen.Session:
49
+ """Construct a session object."""
50
+ kwargs: dict[str, Any] = {}
51
+ if self._grpc_channel:
52
+ kwargs["grpc_options"] = nifgen.GrpcSessionOptions(
53
+ grpc_channel=self._grpc_channel,
54
+ session_name=session_info.session_name,
55
+ initialization_behavior=self._initialization_behavior,
56
+ )
57
+
58
+ return nifgen.Session(
59
+ resource_name=session_info.resource_name,
60
+ reset_device=self._reset_device,
61
+ options=self._options,
62
+ **kwargs,
63
+ )
@@ -0,0 +1,64 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import niscope
6
+ from ni.measurementlink.discovery.v1.client import DiscoveryClient
7
+ from ni_grpc_extensions.channelpool import GrpcChannelPool
8
+
9
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._configuration import (
10
+ NISCOPE_OPTIONS,
11
+ )
12
+ from ni.measurementlink.sessionmanagement.v1.client._drivers._grpcdevice import (
13
+ get_insecure_grpc_device_server_channel,
14
+ )
15
+ from ni.measurementlink.sessionmanagement.v1.client._types import (
16
+ SessionInformation,
17
+ SessionInitializationBehavior,
18
+ )
19
+
20
+ _INITIALIZATION_BEHAVIOR = {
21
+ SessionInitializationBehavior.AUTO: niscope.SessionInitializationBehavior.AUTO,
22
+ SessionInitializationBehavior.INITIALIZE_SERVER_SESSION: niscope.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
23
+ SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION: niscope.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
24
+ SessionInitializationBehavior.INITIALIZE_SESSION_THEN_DETACH: niscope.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
25
+ SessionInitializationBehavior.ATTACH_TO_SESSION_THEN_CLOSE: niscope.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
26
+ }
27
+
28
+
29
+ class SessionConstructor:
30
+ """Constructs sessions based on SessionInformation."""
31
+
32
+ def __init__(
33
+ self,
34
+ discovery_client: DiscoveryClient,
35
+ grpc_channel_pool: GrpcChannelPool,
36
+ reset_device: bool,
37
+ options: dict[str, Any] | None,
38
+ initialization_behavior: SessionInitializationBehavior,
39
+ ) -> None:
40
+ """Initialize the session constructor."""
41
+ self._grpc_channel = get_insecure_grpc_device_server_channel(
42
+ discovery_client, grpc_channel_pool, niscope.GRPC_SERVICE_INTERFACE_NAME
43
+ )
44
+ self._reset_device = reset_device
45
+ self._options = NISCOPE_OPTIONS.to_dict() if options is None else options
46
+ self._initialization_behavior = _INITIALIZATION_BEHAVIOR[initialization_behavior]
47
+
48
+ def __call__(self, session_info: SessionInformation) -> niscope.Session:
49
+ """Construct a session object."""
50
+ kwargs: dict[str, Any] = {}
51
+ if self._grpc_channel:
52
+ kwargs["grpc_options"] = niscope.GrpcSessionOptions(
53
+ grpc_channel=self._grpc_channel,
54
+ session_name=session_info.session_name,
55
+ initialization_behavior=self._initialization_behavior,
56
+ )
57
+
58
+ # Omit id_query because it has no effect.
59
+ return niscope.Session(
60
+ resource_name=session_info.resource_name,
61
+ reset_device=self._reset_device,
62
+ options=self._options,
63
+ **kwargs,
64
+ )