viam-sdk 0.55.1__py3-none-linux_armv7l.whl → 0.57.0__py3-none-linux_armv7l.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.

Files changed (75) hide show
  1. viam/app/app_client.py +3 -5
  2. viam/app/billing_client.py +3 -5
  3. viam/app/data_client.py +129 -11
  4. viam/app/ml_training_client.py +3 -5
  5. viam/app/provisioning_client.py +3 -5
  6. viam/app/viam_client.py +19 -1
  7. viam/gen/app/agent/v1/agent_pb2.py +1 -1
  8. viam/gen/app/cloudslam/v1/cloud_slam_pb2.py +1 -1
  9. viam/gen/app/data/v1/data_grpc.py +26 -2
  10. viam/gen/app/data/v1/data_pb2.py +123 -105
  11. viam/gen/app/data/v1/data_pb2.pyi +186 -4
  12. viam/gen/app/datapipelines/v1/data_pipelines_pb2.py +1 -1
  13. viam/gen/app/dataset/v1/dataset_pb2.py +1 -1
  14. viam/gen/app/datasync/v1/data_sync_pb2.py +1 -1
  15. viam/gen/app/mlinference/v1/ml_inference_pb2.py +1 -1
  16. viam/gen/app/mltraining/v1/ml_training_pb2.py +1 -1
  17. viam/gen/app/packages/v1/packages_pb2.py +1 -1
  18. viam/gen/app/v1/app_pb2.py +1 -1
  19. viam/gen/app/v1/billing_pb2.py +52 -48
  20. viam/gen/app/v1/billing_pb2.pyi +59 -3
  21. viam/gen/app/v1/end_user_pb2.py +1 -1
  22. viam/gen/app/v1/robot_pb2.py +1 -1
  23. viam/gen/common/v1/common_pb2.py +1 -1
  24. viam/gen/component/arm/v1/arm_pb2.py +1 -1
  25. viam/gen/component/audioinput/v1/audioinput_pb2.py +1 -1
  26. viam/gen/component/base/v1/base_pb2.py +1 -1
  27. viam/gen/component/board/v1/board_pb2.py +1 -1
  28. viam/gen/component/button/v1/button_pb2.py +1 -1
  29. viam/gen/component/camera/v1/camera_pb2.py +1 -1
  30. viam/gen/component/encoder/v1/encoder_pb2.py +1 -1
  31. viam/gen/component/gantry/v1/gantry_pb2.py +1 -1
  32. viam/gen/component/generic/v1/generic_pb2.py +1 -1
  33. viam/gen/component/gripper/v1/gripper_pb2.py +1 -1
  34. viam/gen/component/inputcontroller/v1/input_controller_pb2.py +1 -1
  35. viam/gen/component/motor/v1/motor_pb2.py +1 -1
  36. viam/gen/component/movementsensor/v1/movementsensor_pb2.py +1 -1
  37. viam/gen/component/posetracker/v1/pose_tracker_pb2.py +1 -1
  38. viam/gen/component/powersensor/v1/powersensor_pb2.py +1 -1
  39. viam/gen/component/sensor/v1/sensor_pb2.py +1 -1
  40. viam/gen/component/servo/v1/servo_pb2.py +1 -1
  41. viam/gen/component/switch/v1/switch_pb2.py +1 -1
  42. viam/gen/component/testecho/v1/testecho_pb2.py +1 -1
  43. viam/gen/module/v1/module_pb2.py +1 -1
  44. viam/gen/proto/rpc/examples/echo/v1/echo_pb2.py +1 -1
  45. viam/gen/proto/rpc/examples/echoresource/v1/echoresource_pb2.py +1 -1
  46. viam/gen/proto/rpc/v1/auth_pb2.py +1 -1
  47. viam/gen/proto/rpc/webrtc/v1/grpc_pb2.py +1 -1
  48. viam/gen/proto/rpc/webrtc/v1/signaling_pb2.py +1 -1
  49. viam/gen/provisioning/v1/provisioning_pb2.py +1 -1
  50. viam/gen/robot/v1/robot_pb2.py +1 -1
  51. viam/gen/service/datamanager/v1/data_manager_pb2.py +1 -1
  52. viam/gen/service/discovery/v1/discovery_pb2.py +1 -1
  53. viam/gen/service/generic/v1/generic_pb2.py +1 -1
  54. viam/gen/service/mlmodel/v1/mlmodel_pb2.py +1 -1
  55. viam/gen/service/motion/v1/motion_pb2.py +87 -63
  56. viam/gen/service/motion/v1/motion_pb2.pyi +92 -66
  57. viam/gen/service/navigation/v1/navigation_pb2.py +1 -1
  58. viam/gen/service/sensors/v1/sensors_pb2.py +1 -1
  59. viam/gen/service/shell/v1/shell_pb2.py +1 -1
  60. viam/gen/service/slam/v1/slam_pb2.py +1 -1
  61. viam/gen/service/vision/v1/vision_pb2.py +1 -1
  62. viam/gen/service/worldstatestore/v1/world_state_store_pb2.py +1 -1
  63. viam/gen/stream/v1/stream_pb2.py +1 -1
  64. viam/gen/tagger/v1/tagger_pb2.py +1 -1
  65. viam/proto/app/billing.py +4 -0
  66. viam/proto/app/data/__init__.py +18 -0
  67. viam/services/motion/client.py +8 -9
  68. viam/services/motion/motion.py +37 -43
  69. viam/services/worldstatestore/worldstatestore.py +2 -2
  70. viam/sessions_client.py +34 -25
  71. viam/version_metadata.py +2 -2
  72. {viam_sdk-0.55.1.dist-info → viam_sdk-0.57.0.dist-info}/METADATA +1 -1
  73. {viam_sdk-0.55.1.dist-info → viam_sdk-0.57.0.dist-info}/RECORD +75 -75
  74. {viam_sdk-0.55.1.dist-info → viam_sdk-0.57.0.dist-info}/WHEEL +0 -0
  75. {viam_sdk-0.55.1.dist-info → viam_sdk-0.57.0.dist-info}/licenses/LICENSE +0 -0
@@ -10,7 +10,6 @@ from viam.proto.common import (
10
10
  GeoPoint,
11
11
  Pose,
12
12
  PoseInFrame,
13
- ResourceName,
14
13
  Transform,
15
14
  WorldState,
16
15
  )
@@ -54,7 +53,7 @@ class MotionClient(Motion, ReconfigurableResourceRPCClientBase):
54
53
 
55
54
  async def move(
56
55
  self,
57
- component_name: ResourceName,
56
+ component_name: str,
58
57
  destination: PoseInFrame,
59
58
  world_state: Optional[WorldState] = None,
60
59
  constraints: Optional[Constraints] = None,
@@ -77,9 +76,9 @@ class MotionClient(Motion, ReconfigurableResourceRPCClientBase):
77
76
 
78
77
  async def move_on_globe(
79
78
  self,
80
- component_name: ResourceName,
79
+ component_name: str,
81
80
  destination: GeoPoint,
82
- movement_sensor_name: ResourceName,
81
+ movement_sensor_name: str,
83
82
  obstacles: Optional[Sequence[GeoGeometry]] = None,
84
83
  heading: Optional[float] = None,
85
84
  configuration: Optional[MotionConfiguration] = None,
@@ -106,9 +105,9 @@ class MotionClient(Motion, ReconfigurableResourceRPCClientBase):
106
105
 
107
106
  async def move_on_map(
108
107
  self,
109
- component_name: ResourceName,
108
+ component_name: str,
110
109
  destination: Pose,
111
- slam_service_name: ResourceName,
110
+ slam_service_name: str,
112
111
  configuration: Optional[MotionConfiguration] = None,
113
112
  obstacles: Optional[Sequence[Geometry]] = None,
114
113
  *,
@@ -131,7 +130,7 @@ class MotionClient(Motion, ReconfigurableResourceRPCClientBase):
131
130
 
132
131
  async def stop_plan(
133
132
  self,
134
- component_name: ResourceName,
133
+ component_name: str,
135
134
  *,
136
135
  extra: Optional[Mapping[str, ValueTypes]] = None,
137
136
  timeout: Optional[float] = None,
@@ -149,7 +148,7 @@ class MotionClient(Motion, ReconfigurableResourceRPCClientBase):
149
148
 
150
149
  async def get_plan(
151
150
  self,
152
- component_name: ResourceName,
151
+ component_name: str,
153
152
  last_plan_only: bool = False,
154
153
  execution_id: Optional[str] = None,
155
154
  *,
@@ -189,7 +188,7 @@ class MotionClient(Motion, ReconfigurableResourceRPCClientBase):
189
188
 
190
189
  async def get_pose(
191
190
  self,
192
- component_name: ResourceName,
191
+ component_name: str,
193
192
  destination_frame: str,
194
193
  supplemental_transforms: Optional[Sequence[Transform]] = None,
195
194
  *,
@@ -7,7 +7,7 @@ if sys.version_info >= (3, 10):
7
7
  else:
8
8
  from typing_extensions import TypeAlias
9
9
 
10
- from viam.proto.common import GeoGeometry, Geometry, GeoPoint, Pose, PoseInFrame, ResourceName, Transform, WorldState
10
+ from viam.proto.common import GeoGeometry, Geometry, GeoPoint, Pose, PoseInFrame, Transform, WorldState
11
11
  from viam.proto.service.motion import Constraints, GetPlanResponse, MotionConfiguration, PlanStatusWithID
12
12
  from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_SERVICE
13
13
  from viam.utils import ValueTypes
@@ -33,7 +33,7 @@ class Motion(ServiceBase):
33
33
  @abc.abstractmethod
34
34
  async def move(
35
35
  self,
36
- component_name: ResourceName,
36
+ component_name: str,
37
37
  destination: PoseInFrame,
38
38
  world_state: Optional[WorldState] = None,
39
39
  constraints: Optional[Constraints] = None,
@@ -44,18 +44,17 @@ class Motion(ServiceBase):
44
44
  """Plan and execute a movement to move the component specified to its goal destination.
45
45
 
46
46
  Note: Frames designated with respect to components can also be used as the ``component_name`` when calling for a move. This
47
- technique allows for planning and moving the frame itself to the ``destination``. To do so, simply create a resource name with
48
- originating ReferenceFrame's name. Then pass in the resource name into ``component_name``. Ex::
47
+ technique allows for planning and moving the frame itself to the ``destination``.
48
+ To do so, simply pass in a string into ``component_name``. Ex::
49
49
 
50
- resource_name = Gripper.get_resource_name("externalFrame")
51
- success = await MotionServiceClient.move(resource_name, ...)
50
+ success = await MotionServiceClient.move("externalFrame", ...)
52
51
 
53
52
  ::
54
53
 
55
54
  motion = MotionClient.from_robot(robot=machine, name="builtin")
56
55
 
57
- # Assumes a gripper configured with name "my_gripper" on the machine
58
- gripper_name = Gripper.get_resource_name("my_gripper")
56
+ # Assumes "my_gripper" on the machine
57
+ gripper_name = "my_gripper"
59
58
  my_frame = "my_gripper_offset"
60
59
 
61
60
  goal_pose = Pose(x=0, y=0, z=300, o_x=0, o_y=0, o_z=1, theta=0)
@@ -69,7 +68,7 @@ class Motion(ServiceBase):
69
68
  extra={})
70
69
 
71
70
  Args:
72
- component_name (viam.proto.common.ResourceName): Name of a component on a given robot.
71
+ component_name (str): Name of a component on a given robot.
73
72
  destination (viam.proto.common.PoseInFrame): The destination to move to, expressed as a ``Pose`` and the frame in which it was
74
73
  observed.
75
74
  world_state (viam.proto.common.WorldState): When supplied, the motion service will create a plan that obeys any constraints
@@ -95,9 +94,9 @@ class Motion(ServiceBase):
95
94
  @abc.abstractmethod
96
95
  async def move_on_globe(
97
96
  self,
98
- component_name: ResourceName,
97
+ component_name: str,
99
98
  destination: GeoPoint,
100
- movement_sensor_name: ResourceName,
99
+ movement_sensor_name: str,
101
100
  obstacles: Optional[Sequence[GeoGeometry]] = None,
102
101
  heading: Optional[float] = None,
103
102
  configuration: Optional[MotionConfiguration] = None,
@@ -120,24 +119,23 @@ class Motion(ServiceBase):
120
119
 
121
120
  motion = MotionClient.from_robot(robot=machine, name="builtin")
122
121
 
123
- # Get the ResourceNames of the base and movement sensor
124
- my_base_resource_name = Base.get_resource_name("my_base")
125
- mvmnt_sensor_resource_name = MovementSensor.get_resource_name(
126
- "my_movement_sensor")
122
+ # Get the names of the base and movement sensor
123
+ my_base_name = "my_base"
124
+ mvmnt_sensor_name = "my_movement_sensor"
127
125
  # Define a destination GeoPoint at the GPS coordinates [0, 0]
128
126
  my_destination = movement_sensor.GeoPoint(latitude=0, longitude=0)
129
127
 
130
128
  # Move the base component to the designated geographic location, as reported by the movement sensor
131
129
  execution_id = await motion.move_on_globe(
132
- component_name=my_base_resource_name,
130
+ component_name=my_base_name,
133
131
  destination=my_destination,
134
- movement_sensor_name=mvmnt_sensor_resource_name)
132
+ movement_sensor_name=mvmnt_sensor_name)
135
133
 
136
134
  Args:
137
- component_name (ResourceName): The ResourceName of the base to move.
135
+ component_name (str): The name of the base to move.
138
136
  destination (GeoPoint): The location of the component's destination, represented in geographic notation as a
139
137
  GeoPoint (lat, lng).
140
- movement_sensor_name (ResourceName): The ResourceName of the movement sensor that you want to use to check
138
+ movement_sensor_name (str): The name of the movement sensor that you want to use to check
141
139
  the machine's location.
142
140
  obstacles (Optional[Sequence[GeoGeometry]]): Obstacles to consider when planning the motion of the component,
143
141
  with each represented as a GeoGeometry. Default: None
@@ -170,9 +168,9 @@ class Motion(ServiceBase):
170
168
  @abc.abstractmethod
171
169
  async def move_on_map(
172
170
  self,
173
- component_name: ResourceName,
171
+ component_name: str,
174
172
  destination: Pose,
175
- slam_service_name: ResourceName,
173
+ slam_service_name: str,
176
174
  configuration: Optional[MotionConfiguration] = None,
177
175
  obstacles: Optional[Sequence[Geometry]] = None,
178
176
  *,
@@ -194,23 +192,23 @@ class Motion(ServiceBase):
194
192
 
195
193
  motion = MotionClient.from_robot(robot=machine, name="builtin")
196
194
 
197
- # Get the ResourceNames of the base component and SLAM service
198
- my_base_resource_name = Base.get_resource_name("my_base")
199
- my_slam_service_name = SLAMClient.get_resource_name("my_slam_service")
195
+ # Get the names of the base component and SLAM service
196
+ my_base_name = "my_base"
197
+ my_slam_service_name = "my_slam_service"
200
198
 
201
199
  # Define a destination pose with respect to the origin of the map from the SLAM service "my_slam_service"
202
200
  my_pose = Pose(y=10)
203
201
 
204
202
  # Move the base component to the destination pose of Y=10, a location of
205
203
  # (0, 10, 0) in respect to the origin of the map
206
- execution_id = await motion.move_on_map(component_name=my_base_resource_name,
204
+ execution_id = await motion.move_on_map(component_name=my_base_name,
207
205
  destination=my_pose,
208
206
  slam_service_name=my_slam_service_name)
209
207
 
210
208
  Args:
211
- component_name (ResourceName): The ResourceName of the base to move.
209
+ component_name (str): The name of the base to move.
212
210
  destination (Pose): The destination, which can be any Pose with respect to the SLAM map's origin.
213
- slam_service_name (ResourceName): The ResourceName of the SLAM service from which the SLAM map is requested.
211
+ slam_service_name (str): The name of the SLAM service from which the SLAM map is requested.
214
212
  configuration (Optional[MotionConfiguration]): The configuration you want to set across this machine for this motion service.
215
213
  This parameter and each of its fields are optional.
216
214
 
@@ -237,7 +235,7 @@ class Motion(ServiceBase):
237
235
  @abc.abstractmethod
238
236
  async def stop_plan(
239
237
  self,
240
- component_name: ResourceName,
238
+ component_name: str,
241
239
  *,
242
240
  extra: Optional[Mapping[str, ValueTypes]] = None,
243
241
  timeout: Optional[float] = None,
@@ -251,11 +249,11 @@ class Motion(ServiceBase):
251
249
  # Assuming a `move_on_globe()` started the execution
252
250
  # Stop the base component which was instructed to move by `move_on_globe()`
253
251
  # or `move_on_map()`
254
- my_base_resource_name = Base.get_resource_name("my_base")
252
+ my_base_name = "my_base"
255
253
  await motion.stop_plan(component_name=mvmnt_sensor)
256
254
 
257
255
  Args:
258
- component_name (ResourceName): The component to stop
256
+ component_name (str): The component to stop
259
257
 
260
258
  For more information, see `Motion service <https://docs.viam.com/dev/reference/apis/services/motion/#stopplan>`_.
261
259
  """
@@ -264,7 +262,7 @@ class Motion(ServiceBase):
264
262
  @abc.abstractmethod
265
263
  async def get_plan(
266
264
  self,
267
- component_name: ResourceName,
265
+ component_name: str,
268
266
  last_plan_only: bool = False,
269
267
  execution_id: Optional[str] = None,
270
268
  *,
@@ -291,12 +289,12 @@ class Motion(ServiceBase):
291
289
  ::
292
290
 
293
291
  motion = MotionClient.from_robot(robot=machine, name="builtin")
294
- my_base_resource_name = Base.get_resource_name("my_base")
292
+ my_base_name = "my_base"
295
293
  # Get the plan(s) of the base component which was instructed to move by `MoveOnGlobe()` or `MoveOnMap()`
296
- resp = await motion.get_plan(component_name=my_base_resource_name)
294
+ resp = await motion.get_plan(component_name=my_base_name)
297
295
 
298
296
  Args:
299
- component_name (ResourceName): The component to stop
297
+ component_name (str): The component to stop
300
298
  last_plan_only (Optional[bool]): If supplied, the response will only return the last plan for the component / execution.
301
299
  execution_id (Optional[str]): If supplied, the response will only return plans with the provided execution_id.
302
300
 
@@ -343,7 +341,7 @@ class Motion(ServiceBase):
343
341
  @abc.abstractmethod
344
342
  async def get_pose(
345
343
  self,
346
- component_name: ResourceName,
344
+ component_name: str,
347
345
  destination_frame: str,
348
346
  supplemental_transforms: Optional[Sequence[Transform]] = None,
349
347
  *,
@@ -358,22 +356,18 @@ class Motion(ServiceBase):
358
356
  # Note that the example uses the ``Gripper`` class, but any component class that inherits from ``ComponentBase`` will work
359
357
  # (``Arm``, ``Base``, etc).
360
358
 
361
- # Create a `component_name`:
362
- component_name = Gripper.get_resource_name("my_gripper")
363
-
364
359
  from viam.components.gripper import Gripper
365
360
  from viam.services.motion import MotionClient
366
361
 
367
362
  # Assume that the connect function is written and will return a valid machine.
368
- robot = await connect()
363
+ machine = await connect()
369
364
 
370
365
  motion = MotionClient.from_robot(robot=machine, name="builtin")
371
- gripperName = Gripper.get_resource_name("my_gripper")
372
- gripperPoseInWorld = await motion.get_pose(component_name=gripperName,
373
- destination_frame="world")
366
+ gripperPoseInWorld = await motion.get_pose(component_name="my_gripper",
367
+ destination_frame="world")
374
368
 
375
369
  Args:
376
- component_name (viam.proto.common.ResourceName): Name of a component on a robot.
370
+ component_name (str): Name of a component on a robot.
377
371
  destination_frame (str): Name of the desired reference frame.
378
372
  supplemental_transforms (Optional[List[viam.proto.common.Transform]]): Transforms used to augment the robot's frame while
379
373
  calculating pose.
@@ -17,7 +17,7 @@ class WorldStateStore(ServiceBase):
17
17
  changes to world state transforms, which represent the pose of objects in different
18
18
  reference frames. This functionality can be used to create custom visualizations of the world state.
19
19
 
20
- For more information, see `WorldStateStore service <https://docs.viam.com/dev/reference/apis/services/worldstatestore/>`_.
20
+ For more information, see `WorldStateStore service <https://docs.viam.com/dev/reference/apis/services/world-state-store/>`_.
21
21
  """
22
22
 
23
23
  API: Final = API( # pyright: ignore [reportIncompatibleVariableOverride]
@@ -85,6 +85,6 @@ class WorldStateStore(ServiceBase):
85
85
  print(f"Transform {change.transform.uuid} {change.change_type}")
86
86
 
87
87
  Returns:
88
- AsyncIterator[StreamTransformChangesResponse]: A stream of transform changes
88
+ AsyncGenerator[StreamTransformChangesResponse, None]: A stream of transform changes
89
89
  """
90
90
  ...
viam/sessions_client.py CHANGED
@@ -2,6 +2,8 @@ import asyncio
2
2
  import importlib
3
3
  import pkgutil
4
4
  import sys
5
+ from concurrent.futures import ThreadPoolExecutor
6
+ from contextlib import asynccontextmanager
5
7
  from copy import deepcopy
6
8
  from datetime import timedelta
7
9
  from enum import IntEnum
@@ -46,6 +48,7 @@ class SessionsClient:
46
48
  _heartbeat_interval: Optional[timedelta]
47
49
  _supported: _SupportedState
48
50
  _thread: Optional[Thread]
51
+ _pool: ThreadPoolExecutor
49
52
 
50
53
  _HEARTBEAT_MONITORED_METHODS: MutableMapping[str, bool] = {}
51
54
 
@@ -71,6 +74,7 @@ class SessionsClient:
71
74
  self._heartbeat_interval = None
72
75
  self._supported = _SupportedState.UNKNOWN
73
76
  self._thread = None
77
+ self._pool = ThreadPoolExecutor()
74
78
 
75
79
  listen(self.channel, SendRequest, self._send_request)
76
80
  listen(self.channel, RecvTrailingMetadata, self._recv_trailers)
@@ -105,39 +109,45 @@ class SessionsClient:
105
109
  LOGGER.debug("Session expired")
106
110
  self.reset()
107
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
+
108
121
  @property
109
122
  async def metadata(self) -> _MetadataLike:
110
- with self._lock:
123
+ async with self._acquire_lock_async():
111
124
  if self._disabled or self._supported != _SupportedState.UNKNOWN:
112
125
  return self._metadata
113
126
 
114
- request = StartSessionRequest(resume=self._current_id)
115
- try:
116
- response: StartSessionResponse = await self.client.StartSession(request)
117
- except GRPCError as error:
118
- if error.status == Status.UNIMPLEMENTED:
119
- 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:
120
132
  self._reset()
121
133
  self._supported = _SupportedState.FALSE
122
134
  return self._metadata
123
- else:
124
- raise
135
+ else:
136
+ raise
125
137
 
126
- if response is None:
127
- raise GRPCError(status=Status.INTERNAL, message="Expected response to start session")
138
+ if response is None:
139
+ raise GRPCError(status=Status.INTERNAL, message="Expected response to start session")
128
140
 
129
- if response.heartbeat_window is None:
130
- raise GRPCError(status=Status.INTERNAL, message="Expected heartbeat window in response to start session")
141
+ if response.heartbeat_window is None:
142
+ raise GRPCError(status=Status.INTERNAL, message="Expected heartbeat window in response to start session")
131
143
 
132
- with self._lock:
133
144
  self._supported = _SupportedState.TRUE
134
145
  self._heartbeat_interval = response.heartbeat_window.ToTimedelta()
135
146
  self._current_id = response.id
136
147
 
137
- # tick once to ensure heartbeats are supported
138
- await self._heartbeat_tick(self.client)
148
+ # tick once to ensure heartbeats are supported
149
+ await self._heartbeat_tick(self.client)
139
150
 
140
- with self._lock:
141
151
  if self._thread is not None:
142
152
  self._reset()
143
153
  if self._supported == _SupportedState.TRUE:
@@ -156,17 +166,16 @@ class SessionsClient:
156
166
  return self._metadata
157
167
 
158
168
  async def _heartbeat_tick(self, client: RobotServiceStub):
159
- with self._lock:
160
- if not self._current_id:
161
- LOGGER.debug("Failed to send heartbeat, session client reset")
162
- return
163
- 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)
164
173
 
165
174
  try:
166
175
  await client.SendSessionHeartbeat(request)
167
176
  except (GRPCError, StreamTerminatedError):
168
177
  LOGGER.debug("Heartbeat terminated", exc_info=True)
169
- self.reset()
178
+ self._reset()
170
179
  else:
171
180
  LOGGER.debug("Sent heartbeat successfully")
172
181
 
@@ -185,10 +194,10 @@ class SessionsClient:
185
194
  channel = await dial(address=addr, options=self._dial_options)
186
195
  client = RobotServiceStub(channel.channel)
187
196
  while True:
188
- with self._lock:
197
+ async with self._acquire_lock_async():
189
198
  if self._supported != _SupportedState.TRUE:
190
199
  return
191
- await self._heartbeat_tick(client)
200
+ await self._heartbeat_tick(client)
192
201
  await asyncio.sleep(wait)
193
202
 
194
203
  @property
viam/version_metadata.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.55.1"
1
+ __version__ = "0.57.0"
2
2
 
3
- API_VERSION = "v0.1.475"
3
+ API_VERSION = "v0.1.479"
4
4
  SDK_VERSION = __version__
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: viam-sdk
3
- Version: 0.55.1
3
+ Version: 0.57.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