viam-sdk 0.41.1__py3-none-linux_armv6l.whl → 0.66.0__py3-none-linux_armv6l.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 viam-sdk might be problematic. Click here for more details.
- viam/app/app_client.py +225 -51
- viam/app/billing_client.py +47 -5
- viam/app/data_client.py +771 -234
- viam/app/ml_training_client.py +3 -5
- viam/app/provisioning_client.py +3 -5
- viam/app/viam_client.py +58 -11
- viam/components/arm/arm.py +1 -1
- viam/components/arm/service.py +1 -1
- viam/components/audio_in/__init__.py +24 -0
- viam/components/audio_in/audio_in.py +74 -0
- viam/components/audio_in/client.py +76 -0
- viam/components/audio_in/service.py +83 -0
- viam/components/audio_out/__init__.py +21 -0
- viam/components/audio_out/audio_out.py +72 -0
- viam/components/audio_out/client.py +67 -0
- viam/components/audio_out/service.py +63 -0
- viam/components/base/base.py +1 -1
- viam/components/board/board.py +8 -2
- viam/components/board/client.py +2 -1
- viam/components/board/service.py +1 -0
- viam/components/button/__init__.py +10 -0
- viam/components/button/button.py +41 -0
- viam/components/button/client.py +52 -0
- viam/components/button/service.py +46 -0
- viam/components/camera/camera.py +15 -30
- viam/components/camera/client.py +10 -21
- viam/components/camera/service.py +15 -28
- viam/components/component_base.py +2 -2
- viam/components/gantry/client.py +17 -2
- viam/components/gantry/gantry.py +32 -1
- viam/components/gantry/service.py +21 -5
- viam/components/gripper/__init__.py +2 -0
- viam/components/gripper/client.py +25 -2
- viam/components/gripper/gripper.py +76 -1
- viam/components/gripper/service.py +32 -3
- viam/components/input/input.py +1 -1
- viam/components/motor/motor.py +1 -1
- viam/components/power_sensor/power_sensor.py +1 -1
- viam/components/switch/__init__.py +10 -0
- viam/components/switch/client.py +83 -0
- viam/components/switch/service.py +72 -0
- viam/components/switch/switch.py +98 -0
- viam/gen/app/agent/v1/agent_pb2.py +1 -1
- viam/gen/app/cloudslam/v1/cloud_slam_pb2.py +1 -1
- viam/gen/app/data/v1/data_grpc.py +74 -2
- viam/gen/app/data/v1/data_pb2.py +198 -104
- viam/gen/app/data/v1/data_pb2.pyi +563 -31
- viam/gen/app/datapipelines/__init__.py +0 -0
- viam/gen/app/datapipelines/v1/__init__.py +0 -0
- viam/gen/app/datapipelines/v1/data_pipelines_grpc.py +84 -0
- viam/gen/app/datapipelines/v1/data_pipelines_pb2.py +57 -0
- viam/gen/app/datapipelines/v1/data_pipelines_pb2.pyi +387 -0
- viam/gen/app/dataset/v1/dataset_grpc.py +10 -2
- viam/gen/app/dataset/v1/dataset_pb2.py +8 -4
- viam/gen/app/dataset/v1/dataset_pb2.pyi +36 -1
- viam/gen/app/datasync/v1/data_sync_pb2.py +39 -35
- viam/gen/app/datasync/v1/data_sync_pb2.pyi +21 -8
- viam/gen/app/mlinference/v1/ml_inference_pb2.py +7 -7
- viam/gen/app/mlinference/v1/ml_inference_pb2.pyi +4 -2
- viam/gen/app/mltraining/v1/ml_training_grpc.py +10 -2
- viam/gen/app/mltraining/v1/ml_training_pb2.py +63 -43
- viam/gen/app/mltraining/v1/ml_training_pb2.pyi +112 -7
- viam/gen/app/packages/v1/packages_pb2.py +1 -1
- viam/gen/app/v1/app_grpc.py +74 -3
- viam/gen/app/v1/app_pb2.py +600 -545
- viam/gen/app/v1/app_pb2.pyi +1108 -258
- viam/gen/app/v1/billing_grpc.py +26 -2
- viam/gen/app/v1/billing_pb2.py +52 -36
- viam/gen/app/v1/billing_pb2.pyi +158 -4
- viam/gen/app/v1/end_user_pb2.py +1 -1
- viam/gen/app/v1/robot_pb2.py +95 -89
- viam/gen/app/v1/robot_pb2.pyi +121 -9
- viam/gen/common/v1/common_pb2.py +76 -58
- viam/gen/common/v1/common_pb2.pyi +186 -17
- viam/gen/component/arm/v1/arm_grpc.py +10 -2
- viam/gen/component/arm/v1/arm_pb2.py +5 -3
- viam/gen/component/audioin/__init__.py +0 -0
- viam/gen/component/audioin/v1/__init__.py +0 -0
- viam/gen/component/audioin/v1/audioin_grpc.py +54 -0
- viam/gen/component/audioin/v1/audioin_pb2.py +34 -0
- viam/gen/component/audioin/v1/audioin_pb2.pyi +94 -0
- viam/gen/component/audioinput/v1/audioinput_pb2.py +1 -1
- viam/gen/component/audioout/__init__.py +0 -0
- viam/gen/component/audioout/v1/__init__.py +0 -0
- viam/gen/component/audioout/v1/audioout_grpc.py +54 -0
- viam/gen/component/audioout/v1/audioout_pb2.py +32 -0
- viam/gen/component/audioout/v1/audioout_pb2.pyi +47 -0
- viam/gen/component/base/v1/base_pb2.py +1 -1
- viam/gen/component/board/v1/board_pb2.py +1 -1
- viam/gen/component/button/v1/button_pb2.py +1 -1
- viam/gen/component/camera/v1/camera_grpc.py +1 -0
- viam/gen/component/camera/v1/camera_pb2.py +37 -36
- viam/gen/component/camera/v1/camera_pb2.pyi +31 -4
- viam/gen/component/encoder/v1/encoder_pb2.py +1 -1
- viam/gen/component/gantry/v1/gantry_grpc.py +9 -1
- viam/gen/component/gantry/v1/gantry_pb2.py +5 -3
- viam/gen/component/generic/v1/generic_pb2.py +1 -1
- viam/gen/component/gripper/v1/gripper_grpc.py +18 -2
- viam/gen/component/gripper/v1/gripper_pb2.py +12 -4
- viam/gen/component/gripper/v1/gripper_pb2.pyi +43 -1
- viam/gen/component/inputcontroller/v1/input_controller_pb2.py +1 -1
- viam/gen/component/motor/v1/motor_pb2.py +1 -1
- viam/gen/component/movementsensor/v1/movementsensor_pb2.py +1 -1
- viam/gen/component/posetracker/v1/pose_tracker_pb2.py +1 -1
- viam/gen/component/powersensor/v1/powersensor_pb2.py +1 -1
- viam/gen/component/sensor/v1/sensor_pb2.py +1 -1
- viam/gen/component/servo/v1/servo_pb2.py +1 -1
- viam/gen/component/switch/v1/switch_pb2.py +5 -5
- viam/gen/component/switch/v1/switch_pb2.pyi +9 -2
- viam/gen/component/testecho/v1/testecho_pb2.py +1 -1
- viam/gen/module/v1/module_pb2.py +5 -5
- viam/gen/module/v1/module_pb2.pyi +7 -2
- viam/gen/opentelemetry/__init__.py +0 -0
- viam/gen/opentelemetry/proto/__init__.py +0 -0
- viam/gen/opentelemetry/proto/common/__init__.py +0 -0
- viam/gen/opentelemetry/proto/common/v1/__init__.py +0 -0
- viam/gen/opentelemetry/proto/common/v1/common_grpc.py +0 -0
- viam/gen/opentelemetry/proto/common/v1/common_pb2.py +27 -0
- viam/gen/opentelemetry/proto/common/v1/common_pb2.pyi +208 -0
- viam/gen/opentelemetry/proto/resource/__init__.py +0 -0
- viam/gen/opentelemetry/proto/resource/v1/__init__.py +0 -0
- viam/gen/opentelemetry/proto/resource/v1/resource_grpc.py +0 -0
- viam/gen/opentelemetry/proto/resource/v1/resource_pb2.py +18 -0
- viam/gen/opentelemetry/proto/resource/v1/resource_pb2.pyi +59 -0
- viam/gen/opentelemetry/proto/trace/__init__.py +0 -0
- viam/gen/opentelemetry/proto/trace/v1/__init__.py +0 -0
- viam/gen/opentelemetry/proto/trace/v1/trace_grpc.py +0 -0
- viam/gen/opentelemetry/proto/trace/v1/trace_pb2.py +37 -0
- viam/gen/opentelemetry/proto/trace/v1/trace_pb2.pyi +402 -0
- viam/gen/proto/rpc/examples/echo/v1/echo_pb2.py +1 -1
- viam/gen/proto/rpc/examples/echoresource/v1/echoresource_pb2.py +1 -1
- viam/gen/proto/rpc/v1/auth_pb2.py +1 -1
- viam/gen/proto/rpc/webrtc/v1/grpc_pb2.py +1 -1
- viam/gen/proto/rpc/webrtc/v1/signaling_pb2.py +1 -1
- viam/gen/provisioning/v1/provisioning_grpc.py +10 -2
- viam/gen/provisioning/v1/provisioning_pb2.py +32 -26
- viam/gen/provisioning/v1/provisioning_pb2.pyi +46 -5
- viam/gen/robot/v1/robot_grpc.py +51 -34
- viam/gen/robot/v1/robot_pb2.py +147 -142
- viam/gen/robot/v1/robot_pb2.pyi +153 -86
- viam/gen/service/datamanager/v1/data_manager_grpc.py +11 -2
- viam/gen/service/datamanager/v1/data_manager_pb2.py +15 -8
- viam/gen/service/datamanager/v1/data_manager_pb2.pyi +47 -1
- viam/gen/service/discovery/v1/discovery_pb2.py +1 -1
- viam/gen/service/generic/v1/generic_pb2.py +1 -1
- viam/gen/service/mlmodel/v1/mlmodel_pb2.py +1 -1
- viam/gen/service/motion/v1/motion_pb2.py +92 -62
- viam/gen/service/motion/v1/motion_pb2.pyi +130 -68
- viam/gen/service/navigation/v1/navigation_pb2.py +1 -1
- viam/gen/service/sensors/v1/sensors_pb2.py +1 -1
- viam/gen/service/shell/v1/shell_pb2.py +1 -1
- viam/gen/service/slam/v1/slam_pb2.py +1 -1
- viam/gen/service/slam/v1/slam_pb2.pyi +1 -1
- viam/gen/service/video/__init__.py +0 -0
- viam/gen/service/video/v1/__init__.py +0 -0
- viam/gen/service/video/v1/video_grpc.py +39 -0
- viam/gen/service/video/v1/video_pb2.py +29 -0
- viam/gen/service/video/v1/video_pb2.pyi +72 -0
- viam/gen/service/vision/v1/vision_pb2.py +27 -27
- viam/gen/service/vision/v1/vision_pb2.pyi +28 -3
- viam/gen/service/worldstatestore/__init__.py +0 -0
- viam/gen/service/worldstatestore/v1/__init__.py +0 -0
- viam/gen/service/worldstatestore/v1/world_state_store_grpc.py +55 -0
- viam/gen/service/worldstatestore/v1/world_state_store_pb2.py +39 -0
- viam/gen/service/worldstatestore/v1/world_state_store_pb2.pyi +171 -0
- viam/gen/stream/v1/stream_pb2.py +1 -1
- viam/gen/tagger/v1/tagger_pb2.py +1 -1
- viam/logging.py +9 -8
- viam/media/audio.py +22 -10
- viam/media/utils/pil/__init__.py +5 -1
- viam/media/video.py +54 -40
- viam/module/module.py +85 -16
- viam/module/resource_data_consumer.py +41 -0
- viam/module/service.py +9 -1
- viam/proto/app/__init__.py +68 -0
- viam/proto/app/billing.py +16 -0
- viam/proto/app/data/__init__.py +48 -0
- viam/proto/app/datapipelines/__init__.py +56 -0
- viam/proto/app/dataset/__init__.py +4 -0
- viam/proto/app/mltraining/__init__.py +6 -0
- viam/proto/app/robot.py +6 -0
- viam/proto/common/__init__.py +14 -0
- viam/proto/component/audioin/__init__.py +16 -0
- viam/proto/component/audioout/__init__.py +15 -0
- viam/proto/component/camera/__init__.py +0 -2
- viam/proto/component/gripper/__init__.py +4 -0
- viam/proto/opentelemetry/__init__.py +0 -0
- viam/proto/opentelemetry/proto/__init__.py +0 -0
- viam/proto/opentelemetry/proto/common/__init__.py +15 -0
- viam/proto/opentelemetry/proto/resource/__init__.py +10 -0
- viam/proto/opentelemetry/proto/trace/__init__.py +15 -0
- viam/proto/provisioning/__init__.py +6 -0
- viam/proto/robot/__init__.py +16 -8
- viam/proto/service/datamanager/__init__.py +8 -1
- viam/proto/service/motion/__init__.py +2 -0
- viam/proto/service/video/__init__.py +15 -0
- viam/proto/service/worldstatestore/__init__.py +32 -0
- viam/resource/easy_resource.py +5 -9
- viam/resource/manager.py +4 -3
- viam/resource/registry.py +2 -2
- viam/resource/types.py +2 -2
- viam/robot/client.py +38 -59
- viam/rpc/dial.py +48 -5
- viam/rpc/libviam_rust_utils.so +0 -0
- viam/rpc/server.py +24 -10
- viam/services/motion/client.py +8 -9
- viam/services/motion/motion.py +48 -46
- viam/services/navigation/navigation.py +2 -2
- viam/services/vision/client.py +1 -1
- viam/services/vision/service.py +5 -8
- viam/services/vision/vision.py +5 -3
- viam/services/worldstatestore/__init__.py +18 -0
- viam/services/worldstatestore/client.py +94 -0
- viam/services/worldstatestore/service.py +55 -0
- viam/services/worldstatestore/worldstatestore.py +90 -0
- viam/sessions_client.py +115 -46
- viam/version_metadata.py +2 -2
- {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/METADATA +10 -6
- {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/RECORD +221 -152
- {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/WHEEL +1 -1
- viam/components/audio_input/__init__.py +0 -18
- viam/components/audio_input/audio_input.py +0 -81
- viam/components/audio_input/client.py +0 -70
- viam/components/audio_input/service.py +0 -114
- {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/licenses/LICENSE +0 -0
viam/sessions_client.py
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import importlib
|
|
3
|
+
import pkgutil
|
|
4
|
+
import sys
|
|
5
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
6
|
+
from contextlib import asynccontextmanager
|
|
2
7
|
from copy import deepcopy
|
|
3
8
|
from datetime import timedelta
|
|
4
9
|
from enum import IntEnum
|
|
5
10
|
from threading import Lock, Thread
|
|
6
|
-
from typing import Optional
|
|
11
|
+
from typing import MutableMapping, Optional
|
|
7
12
|
|
|
8
13
|
from grpclib import Status
|
|
9
14
|
from grpclib.client import Channel
|
|
@@ -12,26 +17,13 @@ from grpclib.exceptions import GRPCError, StreamTerminatedError
|
|
|
12
17
|
from grpclib.metadata import _MetadataLike
|
|
13
18
|
|
|
14
19
|
from viam import logging
|
|
20
|
+
from viam.gen.common.v1.common_pb2 import safety_heartbeat_monitored
|
|
15
21
|
from viam.proto.robot import RobotServiceStub, SendSessionHeartbeatRequest, StartSessionRequest, StartSessionResponse
|
|
16
22
|
from viam.rpc.dial import DialOptions, dial
|
|
17
23
|
|
|
18
24
|
LOGGER = logging.getLogger(__name__)
|
|
19
25
|
SESSION_METADATA_KEY = "viam-sid"
|
|
20
26
|
|
|
21
|
-
EXEMPT_METADATA_METHODS = frozenset(
|
|
22
|
-
[
|
|
23
|
-
"/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo",
|
|
24
|
-
"/proto.rpc.webrtc.v1.SignalingService/Call",
|
|
25
|
-
"/proto.rpc.webrtc.v1.SignalingService/CallUpdate",
|
|
26
|
-
"/proto.rpc.webrtc.v1.SignalingService/OptionalWebRTCConfig",
|
|
27
|
-
"/proto.rpc.v1.AuthService/Authenticate",
|
|
28
|
-
"/viam.robot.v1.RobotService/ResourceNames",
|
|
29
|
-
"/viam.robot.v1.RobotService/ResourceRPCSubtypes",
|
|
30
|
-
"/viam.robot.v1.RobotService/StartSession",
|
|
31
|
-
"/viam.robot.v1.RobotService/SendSessionHeartbeat",
|
|
32
|
-
]
|
|
33
|
-
)
|
|
34
|
-
|
|
35
27
|
|
|
36
28
|
class _SupportedState(IntEnum):
|
|
37
29
|
UNKNOWN = 0
|
|
@@ -47,7 +39,8 @@ class SessionsClient:
|
|
|
47
39
|
|
|
48
40
|
channel: Channel
|
|
49
41
|
client: RobotServiceStub
|
|
50
|
-
_address: str
|
|
42
|
+
_address: str # direct dial address, when using webRTC this is the local socket rather than a robot address
|
|
43
|
+
_robot_address: Optional[str] # the actual machine address on app.viam.com. important for creating a sessions client on Windows
|
|
51
44
|
_dial_options: DialOptions
|
|
52
45
|
_disabled: bool
|
|
53
46
|
_lock: Lock
|
|
@@ -55,19 +48,33 @@ class SessionsClient:
|
|
|
55
48
|
_heartbeat_interval: Optional[timedelta]
|
|
56
49
|
_supported: _SupportedState
|
|
57
50
|
_thread: Optional[Thread]
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
_pool: ThreadPoolExecutor
|
|
52
|
+
|
|
53
|
+
_HEARTBEAT_MONITORED_METHODS: MutableMapping[str, bool] = {}
|
|
54
|
+
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
channel: Channel,
|
|
58
|
+
direct_dial_address: str,
|
|
59
|
+
dial_options: Optional[DialOptions],
|
|
60
|
+
*,
|
|
61
|
+
disabled: bool = False,
|
|
62
|
+
robot_addr: Optional[str] = None,
|
|
63
|
+
):
|
|
60
64
|
self.channel = channel
|
|
61
65
|
self.client = RobotServiceStub(channel)
|
|
62
66
|
self._address = direct_dial_address
|
|
67
|
+
self._robot_address = robot_addr
|
|
63
68
|
self._disabled = disabled
|
|
64
69
|
self._dial_options = deepcopy(dial_options) if dial_options is not None else DialOptions()
|
|
65
|
-
|
|
70
|
+
if sys.platform != "win32" and sys.platform != "cygwin":
|
|
71
|
+
self._dial_options.disable_webrtc = True
|
|
66
72
|
self._lock = Lock()
|
|
67
73
|
self._current_id = ""
|
|
68
74
|
self._heartbeat_interval = None
|
|
69
75
|
self._supported = _SupportedState.UNKNOWN
|
|
70
76
|
self._thread = None
|
|
77
|
+
self._pool = ThreadPoolExecutor()
|
|
71
78
|
|
|
72
79
|
listen(self.channel, SendRequest, self._send_request)
|
|
73
80
|
listen(self.channel, RecvTrailingMetadata, self._recv_trailers)
|
|
@@ -92,7 +99,7 @@ class SessionsClient:
|
|
|
92
99
|
if self._disabled:
|
|
93
100
|
return
|
|
94
101
|
|
|
95
|
-
if event.method_name
|
|
102
|
+
if not self._is_safety_heartbeat_monitored(event.method_name):
|
|
96
103
|
return
|
|
97
104
|
|
|
98
105
|
event.metadata.update(await self.metadata)
|
|
@@ -102,39 +109,45 @@ class SessionsClient:
|
|
|
102
109
|
LOGGER.debug("Session expired")
|
|
103
110
|
self.reset()
|
|
104
111
|
|
|
112
|
+
@asynccontextmanager
|
|
113
|
+
async def _acquire_lock_async(self):
|
|
114
|
+
loop = asyncio.get_event_loop()
|
|
115
|
+
await loop.run_in_executor(self._pool, self._lock.acquire)
|
|
116
|
+
try:
|
|
117
|
+
yield
|
|
118
|
+
finally:
|
|
119
|
+
self._lock.release()
|
|
120
|
+
|
|
105
121
|
@property
|
|
106
122
|
async def metadata(self) -> _MetadataLike:
|
|
107
|
-
with self.
|
|
123
|
+
async with self._acquire_lock_async():
|
|
108
124
|
if self._disabled or self._supported != _SupportedState.UNKNOWN:
|
|
109
125
|
return self._metadata
|
|
110
126
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
with self._lock:
|
|
127
|
+
request = StartSessionRequest(resume=self._current_id)
|
|
128
|
+
try:
|
|
129
|
+
response: StartSessionResponse = await self.client.StartSession(request)
|
|
130
|
+
except GRPCError as error:
|
|
131
|
+
if error.status == Status.UNIMPLEMENTED:
|
|
117
132
|
self._reset()
|
|
118
133
|
self._supported = _SupportedState.FALSE
|
|
119
134
|
return self._metadata
|
|
120
|
-
|
|
121
|
-
|
|
135
|
+
else:
|
|
136
|
+
raise
|
|
122
137
|
|
|
123
|
-
|
|
124
|
-
|
|
138
|
+
if response is None:
|
|
139
|
+
raise GRPCError(status=Status.INTERNAL, message="Expected response to start session")
|
|
125
140
|
|
|
126
|
-
|
|
127
|
-
|
|
141
|
+
if response.heartbeat_window is None:
|
|
142
|
+
raise GRPCError(status=Status.INTERNAL, message="Expected heartbeat window in response to start session")
|
|
128
143
|
|
|
129
|
-
with self._lock:
|
|
130
144
|
self._supported = _SupportedState.TRUE
|
|
131
145
|
self._heartbeat_interval = response.heartbeat_window.ToTimedelta()
|
|
132
146
|
self._current_id = response.id
|
|
133
147
|
|
|
134
|
-
|
|
135
|
-
|
|
148
|
+
# tick once to ensure heartbeats are supported
|
|
149
|
+
await self._heartbeat_tick(self.client)
|
|
136
150
|
|
|
137
|
-
with self._lock:
|
|
138
151
|
if self._thread is not None:
|
|
139
152
|
self._reset()
|
|
140
153
|
if self._supported == _SupportedState.TRUE:
|
|
@@ -153,28 +166,38 @@ class SessionsClient:
|
|
|
153
166
|
return self._metadata
|
|
154
167
|
|
|
155
168
|
async def _heartbeat_tick(self, client: RobotServiceStub):
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
request = SendSessionHeartbeatRequest(id=self._current_id)
|
|
169
|
+
if not self._current_id:
|
|
170
|
+
LOGGER.debug("Failed to send heartbeat, session client reset")
|
|
171
|
+
return
|
|
172
|
+
request = SendSessionHeartbeatRequest(id=self._current_id)
|
|
161
173
|
|
|
162
174
|
try:
|
|
163
175
|
await client.SendSessionHeartbeat(request)
|
|
164
176
|
except (GRPCError, StreamTerminatedError):
|
|
165
177
|
LOGGER.debug("Heartbeat terminated", exc_info=True)
|
|
166
|
-
self.
|
|
178
|
+
self._reset()
|
|
167
179
|
else:
|
|
168
180
|
LOGGER.debug("Sent heartbeat successfully")
|
|
169
181
|
|
|
182
|
+
def _get_local_addr(self) -> str:
|
|
183
|
+
if sys.platform != "win32" and sys.platform != "cygwin":
|
|
184
|
+
# if we're not on windows, we want the direct dial address
|
|
185
|
+
return self._address
|
|
186
|
+
|
|
187
|
+
# return `robot_address` if it exists, otherwise fallback
|
|
188
|
+
# when using TCP (i.e., on Windows), we need to create a connection to the actual
|
|
189
|
+
# robot address for a sessions client to maintain connectivity successfully
|
|
190
|
+
return self._robot_address if self._robot_address is not None else self._address
|
|
191
|
+
|
|
170
192
|
async def _heartbeat_process(self, wait: float):
|
|
171
|
-
|
|
193
|
+
addr = self._get_local_addr()
|
|
194
|
+
channel = await dial(address=addr, options=self._dial_options)
|
|
172
195
|
client = RobotServiceStub(channel.channel)
|
|
173
196
|
while True:
|
|
174
|
-
with self.
|
|
197
|
+
async with self._acquire_lock_async():
|
|
175
198
|
if self._supported != _SupportedState.TRUE:
|
|
176
199
|
return
|
|
177
|
-
|
|
200
|
+
await self._heartbeat_tick(client)
|
|
178
201
|
await asyncio.sleep(wait)
|
|
179
202
|
|
|
180
203
|
@property
|
|
@@ -183,3 +206,49 @@ class SessionsClient:
|
|
|
183
206
|
return {SESSION_METADATA_KEY: self._current_id}
|
|
184
207
|
|
|
185
208
|
return {}
|
|
209
|
+
|
|
210
|
+
def _is_safety_heartbeat_monitored(self, method: str) -> bool:
|
|
211
|
+
if method in self._HEARTBEAT_MONITORED_METHODS:
|
|
212
|
+
return self._HEARTBEAT_MONITORED_METHODS[method]
|
|
213
|
+
|
|
214
|
+
parts = method.split("/")
|
|
215
|
+
if len(parts) != 3:
|
|
216
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
217
|
+
return False
|
|
218
|
+
service_path = parts[1]
|
|
219
|
+
method_name = parts[2]
|
|
220
|
+
|
|
221
|
+
parts = service_path.split(".")
|
|
222
|
+
if len(parts) < 5:
|
|
223
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
224
|
+
return False
|
|
225
|
+
if parts[0] != "viam":
|
|
226
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
227
|
+
return False
|
|
228
|
+
resource_type = parts[1]
|
|
229
|
+
resource_subtype = parts[2]
|
|
230
|
+
version = parts[3]
|
|
231
|
+
service_name = parts[4]
|
|
232
|
+
try:
|
|
233
|
+
module = importlib.import_module(f"viam.gen.{resource_type}.{resource_subtype}.{version}")
|
|
234
|
+
submods = pkgutil.iter_modules(module.__path__)
|
|
235
|
+
for mod in submods:
|
|
236
|
+
if "_pb2" in mod.name:
|
|
237
|
+
submod = getattr(module, mod.name)
|
|
238
|
+
DESCRIPTOR = getattr(submod, "DESCRIPTOR")
|
|
239
|
+
for service in DESCRIPTOR.services_by_name.values():
|
|
240
|
+
if service.name == service_name:
|
|
241
|
+
for method_actual in service.methods:
|
|
242
|
+
if method_actual.name == method_name:
|
|
243
|
+
options = method_actual.GetOptions()
|
|
244
|
+
if options.HasExtension(safety_heartbeat_monitored):
|
|
245
|
+
is_monitored = options.Extensions[safety_heartbeat_monitored]
|
|
246
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = is_monitored
|
|
247
|
+
return is_monitored
|
|
248
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
249
|
+
return False
|
|
250
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
251
|
+
return False
|
|
252
|
+
except Exception:
|
|
253
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
254
|
+
return False
|
viam/version_metadata.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: viam-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.66.0
|
|
4
4
|
Summary: Viam Robotics Python SDK
|
|
5
5
|
Project-URL: Homepage, https://www.viam.com
|
|
6
6
|
Project-URL: Documentation, https://python.viam.dev
|
|
@@ -11,7 +11,7 @@ License-File: LICENSE
|
|
|
11
11
|
Requires-Python: >=3.8.1
|
|
12
12
|
Requires-Dist: googleapis-common-protos>=1.65.0
|
|
13
13
|
Requires-Dist: grpclib>=0.4.7
|
|
14
|
-
Requires-Dist: protobuf==5.29.
|
|
14
|
+
Requires-Dist: protobuf==5.29.5
|
|
15
15
|
Requires-Dist: pymongo>=4.10.1
|
|
16
16
|
Requires-Dist: typing-extensions>=4.12.2
|
|
17
17
|
Provides-Extra: mlmodel
|
|
@@ -38,6 +38,12 @@ Currently, we have pre-built binaries for macOS (both Intel `x86_64` and Apple S
|
|
|
38
38
|
|
|
39
39
|
`pip install viam-sdk`
|
|
40
40
|
|
|
41
|
+
If you want to install on Windows, you can install from github directly with `pip`:
|
|
42
|
+
|
|
43
|
+
`pip install git+https://github.com/viamrobotics/viam-python-sdk.git`
|
|
44
|
+
|
|
45
|
+
Note that only direct gRPC connections are supported on Windows; you will need to [disable webrtc](https://python.viam.dev/autoapi/viam/rpc/dial/index.html#viam.rpc.dial.DialOptions.disable_webrtc) or else connection will fail. Full support (including webRTC) _does_ exist on WSL.
|
|
46
|
+
|
|
41
47
|
If you intend to use the [`MLModel` service](https://python.viam.dev/autoapi/viam/services/mlmodel/mlmodel/index.html#viam.services.mlmodel.mlmodel.MLModel), use the following command instead, which installs additional required dependencies:
|
|
42
48
|
|
|
43
49
|
`pip install 'viam-sdk[mlmodel]'`
|
|
@@ -45,8 +51,6 @@ If you intend to use the [`MLModel` service](https://python.viam.dev/autoapi/via
|
|
|
45
51
|
You can also run this command on an existing Python SDK install to add support for the ML model service.
|
|
46
52
|
See the [ML (machine learning) model service](https://docs.viam.com/data-ai/ai/deploy/) documentation for more information.
|
|
47
53
|
|
|
48
|
-
Windows is not supported. If you are using Windows, install `viam-sdk` in WSL. For other unsupported systems, read further on how to install from source.
|
|
49
|
-
|
|
50
54
|
### Upgrading
|
|
51
55
|
|
|
52
56
|
To upgrade, simply run the `pip install` command with the `-U` option:
|
|
@@ -88,7 +92,7 @@ To create a client application, to navigate to [app.viam.com](https://app.viam.c
|
|
|
88
92
|
2. Create a robot (for example `arduino`)
|
|
89
93
|
3. Follow the steps on the setup tab:
|
|
90
94
|
|
|
91
|
-
1. Setup
|
|
95
|
+
1. Setup machine cloud credentials on Single Board Computer (SBC)
|
|
92
96
|
2. Download and Install Viam Server
|
|
93
97
|
3. Wait until the robot shows as connected. If this doesn't happen try restarting the viam-server:
|
|
94
98
|
|
|
@@ -96,7 +100,7 @@ To create a client application, to navigate to [app.viam.com](https://app.viam.c
|
|
|
96
100
|
sudo systemctl restart viam-server
|
|
97
101
|
```
|
|
98
102
|
|
|
99
|
-
Next, select the `
|
|
103
|
+
Next, select the `CONNECT` tab in the Viam Web UI, and copy the boilerplate code from the section labeled `Python SDK`.
|
|
100
104
|
|
|
101
105
|
To ensure the installation succeeded and the systems are functional, save and run this simple program. If the program runs successfully, the python-sdk is properly installed, the `viam-server` instance on your robot is alive, and the computer running the program is able to connect to that instance.
|
|
102
106
|
|