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.

Files changed (225) hide show
  1. viam/app/app_client.py +225 -51
  2. viam/app/billing_client.py +47 -5
  3. viam/app/data_client.py +771 -234
  4. viam/app/ml_training_client.py +3 -5
  5. viam/app/provisioning_client.py +3 -5
  6. viam/app/viam_client.py +58 -11
  7. viam/components/arm/arm.py +1 -1
  8. viam/components/arm/service.py +1 -1
  9. viam/components/audio_in/__init__.py +24 -0
  10. viam/components/audio_in/audio_in.py +74 -0
  11. viam/components/audio_in/client.py +76 -0
  12. viam/components/audio_in/service.py +83 -0
  13. viam/components/audio_out/__init__.py +21 -0
  14. viam/components/audio_out/audio_out.py +72 -0
  15. viam/components/audio_out/client.py +67 -0
  16. viam/components/audio_out/service.py +63 -0
  17. viam/components/base/base.py +1 -1
  18. viam/components/board/board.py +8 -2
  19. viam/components/board/client.py +2 -1
  20. viam/components/board/service.py +1 -0
  21. viam/components/button/__init__.py +10 -0
  22. viam/components/button/button.py +41 -0
  23. viam/components/button/client.py +52 -0
  24. viam/components/button/service.py +46 -0
  25. viam/components/camera/camera.py +15 -30
  26. viam/components/camera/client.py +10 -21
  27. viam/components/camera/service.py +15 -28
  28. viam/components/component_base.py +2 -2
  29. viam/components/gantry/client.py +17 -2
  30. viam/components/gantry/gantry.py +32 -1
  31. viam/components/gantry/service.py +21 -5
  32. viam/components/gripper/__init__.py +2 -0
  33. viam/components/gripper/client.py +25 -2
  34. viam/components/gripper/gripper.py +76 -1
  35. viam/components/gripper/service.py +32 -3
  36. viam/components/input/input.py +1 -1
  37. viam/components/motor/motor.py +1 -1
  38. viam/components/power_sensor/power_sensor.py +1 -1
  39. viam/components/switch/__init__.py +10 -0
  40. viam/components/switch/client.py +83 -0
  41. viam/components/switch/service.py +72 -0
  42. viam/components/switch/switch.py +98 -0
  43. viam/gen/app/agent/v1/agent_pb2.py +1 -1
  44. viam/gen/app/cloudslam/v1/cloud_slam_pb2.py +1 -1
  45. viam/gen/app/data/v1/data_grpc.py +74 -2
  46. viam/gen/app/data/v1/data_pb2.py +198 -104
  47. viam/gen/app/data/v1/data_pb2.pyi +563 -31
  48. viam/gen/app/datapipelines/__init__.py +0 -0
  49. viam/gen/app/datapipelines/v1/__init__.py +0 -0
  50. viam/gen/app/datapipelines/v1/data_pipelines_grpc.py +84 -0
  51. viam/gen/app/datapipelines/v1/data_pipelines_pb2.py +57 -0
  52. viam/gen/app/datapipelines/v1/data_pipelines_pb2.pyi +387 -0
  53. viam/gen/app/dataset/v1/dataset_grpc.py +10 -2
  54. viam/gen/app/dataset/v1/dataset_pb2.py +8 -4
  55. viam/gen/app/dataset/v1/dataset_pb2.pyi +36 -1
  56. viam/gen/app/datasync/v1/data_sync_pb2.py +39 -35
  57. viam/gen/app/datasync/v1/data_sync_pb2.pyi +21 -8
  58. viam/gen/app/mlinference/v1/ml_inference_pb2.py +7 -7
  59. viam/gen/app/mlinference/v1/ml_inference_pb2.pyi +4 -2
  60. viam/gen/app/mltraining/v1/ml_training_grpc.py +10 -2
  61. viam/gen/app/mltraining/v1/ml_training_pb2.py +63 -43
  62. viam/gen/app/mltraining/v1/ml_training_pb2.pyi +112 -7
  63. viam/gen/app/packages/v1/packages_pb2.py +1 -1
  64. viam/gen/app/v1/app_grpc.py +74 -3
  65. viam/gen/app/v1/app_pb2.py +600 -545
  66. viam/gen/app/v1/app_pb2.pyi +1108 -258
  67. viam/gen/app/v1/billing_grpc.py +26 -2
  68. viam/gen/app/v1/billing_pb2.py +52 -36
  69. viam/gen/app/v1/billing_pb2.pyi +158 -4
  70. viam/gen/app/v1/end_user_pb2.py +1 -1
  71. viam/gen/app/v1/robot_pb2.py +95 -89
  72. viam/gen/app/v1/robot_pb2.pyi +121 -9
  73. viam/gen/common/v1/common_pb2.py +76 -58
  74. viam/gen/common/v1/common_pb2.pyi +186 -17
  75. viam/gen/component/arm/v1/arm_grpc.py +10 -2
  76. viam/gen/component/arm/v1/arm_pb2.py +5 -3
  77. viam/gen/component/audioin/__init__.py +0 -0
  78. viam/gen/component/audioin/v1/__init__.py +0 -0
  79. viam/gen/component/audioin/v1/audioin_grpc.py +54 -0
  80. viam/gen/component/audioin/v1/audioin_pb2.py +34 -0
  81. viam/gen/component/audioin/v1/audioin_pb2.pyi +94 -0
  82. viam/gen/component/audioinput/v1/audioinput_pb2.py +1 -1
  83. viam/gen/component/audioout/__init__.py +0 -0
  84. viam/gen/component/audioout/v1/__init__.py +0 -0
  85. viam/gen/component/audioout/v1/audioout_grpc.py +54 -0
  86. viam/gen/component/audioout/v1/audioout_pb2.py +32 -0
  87. viam/gen/component/audioout/v1/audioout_pb2.pyi +47 -0
  88. viam/gen/component/base/v1/base_pb2.py +1 -1
  89. viam/gen/component/board/v1/board_pb2.py +1 -1
  90. viam/gen/component/button/v1/button_pb2.py +1 -1
  91. viam/gen/component/camera/v1/camera_grpc.py +1 -0
  92. viam/gen/component/camera/v1/camera_pb2.py +37 -36
  93. viam/gen/component/camera/v1/camera_pb2.pyi +31 -4
  94. viam/gen/component/encoder/v1/encoder_pb2.py +1 -1
  95. viam/gen/component/gantry/v1/gantry_grpc.py +9 -1
  96. viam/gen/component/gantry/v1/gantry_pb2.py +5 -3
  97. viam/gen/component/generic/v1/generic_pb2.py +1 -1
  98. viam/gen/component/gripper/v1/gripper_grpc.py +18 -2
  99. viam/gen/component/gripper/v1/gripper_pb2.py +12 -4
  100. viam/gen/component/gripper/v1/gripper_pb2.pyi +43 -1
  101. viam/gen/component/inputcontroller/v1/input_controller_pb2.py +1 -1
  102. viam/gen/component/motor/v1/motor_pb2.py +1 -1
  103. viam/gen/component/movementsensor/v1/movementsensor_pb2.py +1 -1
  104. viam/gen/component/posetracker/v1/pose_tracker_pb2.py +1 -1
  105. viam/gen/component/powersensor/v1/powersensor_pb2.py +1 -1
  106. viam/gen/component/sensor/v1/sensor_pb2.py +1 -1
  107. viam/gen/component/servo/v1/servo_pb2.py +1 -1
  108. viam/gen/component/switch/v1/switch_pb2.py +5 -5
  109. viam/gen/component/switch/v1/switch_pb2.pyi +9 -2
  110. viam/gen/component/testecho/v1/testecho_pb2.py +1 -1
  111. viam/gen/module/v1/module_pb2.py +5 -5
  112. viam/gen/module/v1/module_pb2.pyi +7 -2
  113. viam/gen/opentelemetry/__init__.py +0 -0
  114. viam/gen/opentelemetry/proto/__init__.py +0 -0
  115. viam/gen/opentelemetry/proto/common/__init__.py +0 -0
  116. viam/gen/opentelemetry/proto/common/v1/__init__.py +0 -0
  117. viam/gen/opentelemetry/proto/common/v1/common_grpc.py +0 -0
  118. viam/gen/opentelemetry/proto/common/v1/common_pb2.py +27 -0
  119. viam/gen/opentelemetry/proto/common/v1/common_pb2.pyi +208 -0
  120. viam/gen/opentelemetry/proto/resource/__init__.py +0 -0
  121. viam/gen/opentelemetry/proto/resource/v1/__init__.py +0 -0
  122. viam/gen/opentelemetry/proto/resource/v1/resource_grpc.py +0 -0
  123. viam/gen/opentelemetry/proto/resource/v1/resource_pb2.py +18 -0
  124. viam/gen/opentelemetry/proto/resource/v1/resource_pb2.pyi +59 -0
  125. viam/gen/opentelemetry/proto/trace/__init__.py +0 -0
  126. viam/gen/opentelemetry/proto/trace/v1/__init__.py +0 -0
  127. viam/gen/opentelemetry/proto/trace/v1/trace_grpc.py +0 -0
  128. viam/gen/opentelemetry/proto/trace/v1/trace_pb2.py +37 -0
  129. viam/gen/opentelemetry/proto/trace/v1/trace_pb2.pyi +402 -0
  130. viam/gen/proto/rpc/examples/echo/v1/echo_pb2.py +1 -1
  131. viam/gen/proto/rpc/examples/echoresource/v1/echoresource_pb2.py +1 -1
  132. viam/gen/proto/rpc/v1/auth_pb2.py +1 -1
  133. viam/gen/proto/rpc/webrtc/v1/grpc_pb2.py +1 -1
  134. viam/gen/proto/rpc/webrtc/v1/signaling_pb2.py +1 -1
  135. viam/gen/provisioning/v1/provisioning_grpc.py +10 -2
  136. viam/gen/provisioning/v1/provisioning_pb2.py +32 -26
  137. viam/gen/provisioning/v1/provisioning_pb2.pyi +46 -5
  138. viam/gen/robot/v1/robot_grpc.py +51 -34
  139. viam/gen/robot/v1/robot_pb2.py +147 -142
  140. viam/gen/robot/v1/robot_pb2.pyi +153 -86
  141. viam/gen/service/datamanager/v1/data_manager_grpc.py +11 -2
  142. viam/gen/service/datamanager/v1/data_manager_pb2.py +15 -8
  143. viam/gen/service/datamanager/v1/data_manager_pb2.pyi +47 -1
  144. viam/gen/service/discovery/v1/discovery_pb2.py +1 -1
  145. viam/gen/service/generic/v1/generic_pb2.py +1 -1
  146. viam/gen/service/mlmodel/v1/mlmodel_pb2.py +1 -1
  147. viam/gen/service/motion/v1/motion_pb2.py +92 -62
  148. viam/gen/service/motion/v1/motion_pb2.pyi +130 -68
  149. viam/gen/service/navigation/v1/navigation_pb2.py +1 -1
  150. viam/gen/service/sensors/v1/sensors_pb2.py +1 -1
  151. viam/gen/service/shell/v1/shell_pb2.py +1 -1
  152. viam/gen/service/slam/v1/slam_pb2.py +1 -1
  153. viam/gen/service/slam/v1/slam_pb2.pyi +1 -1
  154. viam/gen/service/video/__init__.py +0 -0
  155. viam/gen/service/video/v1/__init__.py +0 -0
  156. viam/gen/service/video/v1/video_grpc.py +39 -0
  157. viam/gen/service/video/v1/video_pb2.py +29 -0
  158. viam/gen/service/video/v1/video_pb2.pyi +72 -0
  159. viam/gen/service/vision/v1/vision_pb2.py +27 -27
  160. viam/gen/service/vision/v1/vision_pb2.pyi +28 -3
  161. viam/gen/service/worldstatestore/__init__.py +0 -0
  162. viam/gen/service/worldstatestore/v1/__init__.py +0 -0
  163. viam/gen/service/worldstatestore/v1/world_state_store_grpc.py +55 -0
  164. viam/gen/service/worldstatestore/v1/world_state_store_pb2.py +39 -0
  165. viam/gen/service/worldstatestore/v1/world_state_store_pb2.pyi +171 -0
  166. viam/gen/stream/v1/stream_pb2.py +1 -1
  167. viam/gen/tagger/v1/tagger_pb2.py +1 -1
  168. viam/logging.py +9 -8
  169. viam/media/audio.py +22 -10
  170. viam/media/utils/pil/__init__.py +5 -1
  171. viam/media/video.py +54 -40
  172. viam/module/module.py +85 -16
  173. viam/module/resource_data_consumer.py +41 -0
  174. viam/module/service.py +9 -1
  175. viam/proto/app/__init__.py +68 -0
  176. viam/proto/app/billing.py +16 -0
  177. viam/proto/app/data/__init__.py +48 -0
  178. viam/proto/app/datapipelines/__init__.py +56 -0
  179. viam/proto/app/dataset/__init__.py +4 -0
  180. viam/proto/app/mltraining/__init__.py +6 -0
  181. viam/proto/app/robot.py +6 -0
  182. viam/proto/common/__init__.py +14 -0
  183. viam/proto/component/audioin/__init__.py +16 -0
  184. viam/proto/component/audioout/__init__.py +15 -0
  185. viam/proto/component/camera/__init__.py +0 -2
  186. viam/proto/component/gripper/__init__.py +4 -0
  187. viam/proto/opentelemetry/__init__.py +0 -0
  188. viam/proto/opentelemetry/proto/__init__.py +0 -0
  189. viam/proto/opentelemetry/proto/common/__init__.py +15 -0
  190. viam/proto/opentelemetry/proto/resource/__init__.py +10 -0
  191. viam/proto/opentelemetry/proto/trace/__init__.py +15 -0
  192. viam/proto/provisioning/__init__.py +6 -0
  193. viam/proto/robot/__init__.py +16 -8
  194. viam/proto/service/datamanager/__init__.py +8 -1
  195. viam/proto/service/motion/__init__.py +2 -0
  196. viam/proto/service/video/__init__.py +15 -0
  197. viam/proto/service/worldstatestore/__init__.py +32 -0
  198. viam/resource/easy_resource.py +5 -9
  199. viam/resource/manager.py +4 -3
  200. viam/resource/registry.py +2 -2
  201. viam/resource/types.py +2 -2
  202. viam/robot/client.py +38 -59
  203. viam/rpc/dial.py +48 -5
  204. viam/rpc/libviam_rust_utils.so +0 -0
  205. viam/rpc/server.py +24 -10
  206. viam/services/motion/client.py +8 -9
  207. viam/services/motion/motion.py +48 -46
  208. viam/services/navigation/navigation.py +2 -2
  209. viam/services/vision/client.py +1 -1
  210. viam/services/vision/service.py +5 -8
  211. viam/services/vision/vision.py +5 -3
  212. viam/services/worldstatestore/__init__.py +18 -0
  213. viam/services/worldstatestore/client.py +94 -0
  214. viam/services/worldstatestore/service.py +55 -0
  215. viam/services/worldstatestore/worldstatestore.py +90 -0
  216. viam/sessions_client.py +115 -46
  217. viam/version_metadata.py +2 -2
  218. {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/METADATA +10 -6
  219. {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/RECORD +221 -152
  220. {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/WHEEL +1 -1
  221. viam/components/audio_input/__init__.py +0 -18
  222. viam/components/audio_input/audio_input.py +0 -81
  223. viam/components/audio_input/client.py +0 -70
  224. viam/components/audio_input/service.py +0 -114
  225. {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,7 +1,7 @@
1
1
  import inspect
2
2
  import re
3
3
  from abc import ABCMeta
4
- from typing import Callable, ClassVar, Mapping, Sequence, Union
4
+ from typing import Callable, ClassVar, Mapping, Sequence, Tuple, Union
5
5
 
6
6
  from viam.proto.app.robot import ComponentConfig
7
7
  from viam.proto.common import ResourceName
@@ -113,16 +113,15 @@ class EasyResource:
113
113
  @classmethod
114
114
  def new(cls, config: ComponentConfig, dependencies: Mapping[ResourceName, ResourceBase]):
115
115
  """
116
- This is passed to register_resource_creator; the default implementation calls reconfigure()
116
+ This is passed to register_resource_creator. The default implementation only sets the resource name
117
117
  when an instance of your model is instantiated. You can override this in your subclass.
118
118
  """
119
119
  self = cls(config.name)
120
120
  logger.debug("created %s %s %s", cls.API, cls.MODEL, config.name)
121
- self.reconfigure(config, dependencies)
122
121
  return self
123
122
 
124
123
  @classmethod
125
- def validate_config(cls, config: ComponentConfig) -> Sequence[str]:
124
+ def validate_config(cls, config: ComponentConfig) -> Tuple[Sequence[str], Sequence[str]]:
126
125
  """This method allows you to validate the configuration object received from the machine,
127
126
  as well as to return any implicit dependencies based on that `config`.
128
127
 
@@ -130,9 +129,9 @@ class EasyResource:
130
129
  config (ComponentConfig): The configuration for this resource
131
130
 
132
131
  Returns:
133
- Sequence[str]: A list of implicit dependencies
132
+ Tuple[Sequence[str], Sequence[str]]: One list of required implicit dependencies and one of optional deps.
134
133
  """
135
- return []
134
+ return [], []
136
135
 
137
136
  @classmethod
138
137
  def register(cls):
@@ -148,6 +147,3 @@ class EasyResource:
148
147
  cls.MODEL,
149
148
  ResourceCreatorRegistration(cls.new, cls.validate_config), # pyright: ignore [reportArgumentType]
150
149
  )
151
-
152
- def reconfigure(self, config: ComponentConfig, dependencies: Mapping[ResourceName, ResourceBase]):
153
- logger.debug("reconfigure %s %s", self.API, self.MODEL)
viam/resource/manager.py CHANGED
@@ -103,10 +103,11 @@ class ResourceManager:
103
103
  try:
104
104
  resource = self.resources[name]
105
105
  await resource.close()
106
- except Exception as e:
107
- raise e
108
106
  finally:
109
- del self.resources[name]
107
+ try:
108
+ del self.resources[name]
109
+ except KeyError:
110
+ pass
110
111
 
111
112
  async def close(self):
112
113
  """Close the resourcce manager by removing all resources.
viam/resource/registry.py CHANGED
@@ -27,7 +27,7 @@ class ResourceCreatorRegistration:
27
27
  """A function that can create a resource given a mapping of dependencies (``ResourceName`` to ``ResourceBase``
28
28
  """
29
29
 
30
- validator: "Validator" = lambda x: []
30
+ validator: "Validator" = lambda x: ([], [])
31
31
  """A function that can validate a resource and return implicit dependencies.
32
32
 
33
33
  If called without a validator function, default to a function returning an empty Sequence
@@ -170,7 +170,7 @@ class Registry:
170
170
  try:
171
171
  return cls._RESOURCES[f"{api}/{model}"].validator
172
172
  except AttributeError:
173
- return lambda x: []
173
+ return lambda x: ([], [])
174
174
  except KeyError:
175
175
  raise ResourceNotFoundError(api.resource_type, api.resource_subtype)
176
176
 
viam/resource/types.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import re
2
2
  import sys
3
- from typing import TYPE_CHECKING, Callable, ClassVar, Mapping, Optional, Protocol, Sequence, runtime_checkable
3
+ from typing import TYPE_CHECKING, Callable, ClassVar, Mapping, Optional, Protocol, Sequence, Tuple, runtime_checkable
4
4
 
5
5
  if sys.version_info >= (3, 10):
6
6
  from typing import TypeAlias
@@ -203,7 +203,7 @@ def resource_name_from_string(string: str) -> ResourceName:
203
203
 
204
204
 
205
205
  ResourceCreator: TypeAlias = Callable[[ComponentConfig, Mapping[ResourceName, "ResourceBase"]], "ResourceBase"]
206
- Validator: TypeAlias = Callable[[ComponentConfig], Sequence[str]]
206
+ Validator: TypeAlias = Callable[[ComponentConfig], Tuple[Sequence[str], Sequence[str]]]
207
207
 
208
208
 
209
209
  @runtime_checkable
viam/robot/client.py CHANGED
@@ -1,6 +1,5 @@
1
1
  import asyncio
2
2
  import sys
3
- import warnings
4
3
  from dataclasses import dataclass
5
4
  from datetime import datetime
6
5
  from threading import RLock
@@ -18,10 +17,6 @@ from viam.proto.common import LogEntry, PoseInFrame, ResourceName, Transform
18
17
  from viam.proto.robot import (
19
18
  BlockForOperationRequest,
20
19
  CancelOperationRequest,
21
- DiscoverComponentsRequest,
22
- DiscoverComponentsResponse,
23
- Discovery,
24
- DiscoveryQuery,
25
20
  FrameSystemConfig,
26
21
  FrameSystemConfigRequest,
27
22
  FrameSystemConfigResponse,
@@ -40,6 +35,7 @@ from viam.proto.robot import (
40
35
  Operation,
41
36
  ResourceNamesRequest,
42
37
  ResourceNamesResponse,
38
+ RestartModuleRequest,
43
39
  RobotServiceStub,
44
40
  ShutdownRequest,
45
41
  StopAllRequest,
@@ -52,7 +48,7 @@ from viam.resource.manager import ResourceManager
52
48
  from viam.resource.registry import Registry
53
49
  from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase, ResourceRPCClientBase
54
50
  from viam.resource.types import API, RESOURCE_TYPE_COMPONENT, RESOURCE_TYPE_SERVICE
55
- from viam.rpc.dial import DialOptions, ViamChannel, dial
51
+ from viam.rpc.dial import DialOptions, ViamChannel, _dial_inner, dial
56
52
  from viam.services.service_base import ServiceBase
57
53
  from viam.sessions_client import SessionsClient
58
54
  from viam.utils import datetime_to_timestamp, dict_to_struct
@@ -189,7 +185,7 @@ class RobotClient:
189
185
  # Replace "<API-KEY-ID>" (including brackets) with your machine's API key ID
190
186
  api_key_id='<API-KEY-ID>'
191
187
  )
192
- return await RobotClient.at_address('ADDRESS FROM THE VIAM APP', opts)
188
+ return await RobotClient.at_address('MACHINE ADDRESS', opts)
193
189
 
194
190
 
195
191
  async def main():
@@ -207,7 +203,7 @@ class RobotClient:
207
203
  """
208
204
  logging.setLevel(options.log_level)
209
205
  channel = await dial(address, options.dial_options)
210
- machine = await cls._with_channel(channel, options, True)
206
+ machine = await cls._with_channel(channel, options, True, robot_addr=address)
211
207
  machine._address = address
212
208
  return machine
213
209
 
@@ -242,7 +238,9 @@ class RobotClient:
242
238
  return await cls._with_channel(channel, options, False)
243
239
 
244
240
  @classmethod
245
- async def _with_channel(cls, channel: Union[Channel, ViamChannel], options: Options, close_channel: bool):
241
+ async def _with_channel(
242
+ cls, channel: Union[Channel, ViamChannel], options: Options, close_channel: bool, robot_addr: Optional[str] = None
243
+ ):
246
244
  """INTERNAL USE ONLY"""
247
245
 
248
246
  self = cls()
@@ -263,7 +261,7 @@ class RobotClient:
263
261
  self._options = options
264
262
  self._address = self._channel._path if self._channel._path else f"{self._channel._host}:{self._channel._port}"
265
263
  self._sessions_client = SessionsClient(
266
- self._channel, self._address, self._options.dial_options, disabled=self._options.disable_sessions
264
+ self._channel, self._address, self._options.dial_options, disabled=self._options.disable_sessions, robot_addr=robot_addr
267
265
  )
268
266
 
269
267
  try:
@@ -403,7 +401,7 @@ class RobotClient:
403
401
  try:
404
402
  self._sessions_client.reset()
405
403
 
406
- channel = await dial(self._address, self._options.dial_options)
404
+ channel = await _dial_inner(self._address, self._options.dial_options)
407
405
 
408
406
  client: RobotServiceStub
409
407
  if isinstance(channel, Channel):
@@ -425,6 +423,7 @@ class RobotClient:
425
423
  direct_dial_address=direct_dial_address,
426
424
  dial_options=self._options.dial_options,
427
425
  disabled=self._options.disable_sessions,
426
+ robot_addr=self._address,
428
427
  )
429
428
 
430
429
  await self.refresh()
@@ -727,53 +726,6 @@ class RobotClient:
727
726
  async def transform_point_cloud(self):
728
727
  raise NotImplementedError()
729
728
 
730
- #######################
731
- # COMPONENT DISCOVERY #
732
- #######################
733
-
734
- async def discover_components(
735
- self,
736
- queries: List[DiscoveryQuery],
737
- ) -> List[Discovery]:
738
- """
739
- Deprecated: v0.38.0, use the Discovery Service APIs instead.
740
- Get a list of discovered potential component configurations, for example listing different supported resolutions. Currently only works for some cameras.
741
- Returns module names for modules.
742
-
743
- ::
744
-
745
- from viam.proto.robot import DiscoveryQuery
746
-
747
- # Define a new discovery query.
748
- q = DiscoveryQuery(subtype="camera", model="webcam")
749
-
750
- # Define a list of discovery queries.
751
- qs = [q]
752
-
753
- # Get component configurations with these queries.
754
- component_configs = await machine.discover_components(qs)
755
-
756
- Args:
757
-
758
- queries (List[viam.proto.robot.DiscoveryQuery]): The list of component models to lookup potential configurations for.
759
-
760
- Returns:
761
- List[Discovery]: A list of discovered potential component configurations.
762
-
763
- For more information, see `Machine Management API <https://docs.viam.com/appendix/apis/robot/>`_.
764
- """
765
- request = DiscoverComponentsRequest(queries=queries)
766
- response: DiscoverComponentsResponse = await self._client.DiscoverComponents(request)
767
- warnings.warn(
768
- "RobotClient.discover_components is deprecated. It will be removed on March 10 2025. Use the DiscoveryService APIs instead.",
769
- DeprecationWarning,
770
- stacklevel=2,
771
- )
772
- LOGGER.warning(
773
- "RobotClient.discover_components is deprecated. It will be removed on March 10 2025. Use the DiscoveryService APIs instead."
774
- )
775
- return list(response.discovery)
776
-
777
729
  #################
778
730
  # MODULE MODELS #
779
731
  #################
@@ -949,10 +901,37 @@ class RobotClient:
949
901
  config_status = machine_status.config
950
902
 
951
903
  Returns:
952
- viam.proto.robot.GetMachineStatusResponse: current status of the machine (initializing or running), resources (List[ResourceStatus]) and config of the machine.
904
+ viam.proto.robot.GetMachineStatusResponse: current status of the machine (initializing or running), current status of the resources (List[ResourceStatus]) and the revision of the config of the machine.
953
905
 
954
906
  For more information, see `Machine Management API <https://docs.viam.com/appendix/apis/robot/>`_.
955
907
  """
956
908
 
957
909
  request = GetMachineStatusRequest()
958
910
  return await self._client.GetMachineStatus(request)
911
+
912
+ ##################
913
+ # Restart Module #
914
+ ##################
915
+
916
+ async def restart_module(self, id: Optional[str] = None, name: Optional[str] = None):
917
+ """
918
+ Restarts a module running on the machine with the given id or name.
919
+
920
+ ::
921
+
922
+ await machine.restart_module(id="namespace:module:model", name="my_model")
923
+
924
+ Args:
925
+ id (str): The id matching the module_id field of the registry module in your part configuration.
926
+ name (str): The name matching the name field of the local/registry module in your part configuration.
927
+
928
+ Raises:
929
+ GRPCError: If a module can't be found matching the provided ID or name.
930
+
931
+ For more information, see `Machine Management API <https://docs.viam.com/appendix/apis/robot/>`_.
932
+ """
933
+
934
+ id = id if id else ""
935
+ name = name if name else ""
936
+ request = RestartModuleRequest(module_id=id, module_name=name)
937
+ await self._client.RestartModule(request)
viam/rpc/dial.py CHANGED
@@ -29,9 +29,9 @@ LOGGER = logging.getLogger(__name__)
29
29
 
30
30
  @dataclass
31
31
  class Credentials:
32
- """Credentials to connect to the robot and the Viam app."""
32
+ """Credentials to connect to the machine and app.viam.com."""
33
33
 
34
- type: Union[Literal["robot-location-secret"], Literal["robot-secret"], Literal["api-key"]]
34
+ type: Union[Literal["robot-secret"], Literal["api-key"]]
35
35
  """The type of credential
36
36
  """
37
37
 
@@ -70,6 +70,14 @@ class DialOptions:
70
70
  max_reconnect_attempts: int = 3
71
71
  """Max number of times the client attempts to reconnect when connection is lost"""
72
72
 
73
+ initial_connection_attempts: int = 3
74
+ """Max number of times the client will attempt to establish an initial connection
75
+ If set to a non-positive integer, then there will be no limit to initial connection attempts"""
76
+
77
+ initial_connection_attempt_timeout: float
78
+ """Number of seconds before dial connection times out on initial connection attempts
79
+ Defaults to whatever value is set in the `timeout` field"""
80
+
73
81
  timeout: float = 20
74
82
  """Number of seconds before the dial connection times out
75
83
  Set to 20sec to match _defaultOfferDeadline in goutils/rpc/wrtc_call_queue.go"""
@@ -85,6 +93,8 @@ class DialOptions:
85
93
  allow_insecure_with_creds_downgrade: bool = False,
86
94
  max_reconnect_attempts: int = 3,
87
95
  timeout: float = 20,
96
+ initial_connection_attempts: int = 3,
97
+ initial_connection_attempt_timeout: Optional[float] = None,
88
98
  ) -> None:
89
99
  self.disable_webrtc = disable_webrtc
90
100
  self.auth_entity = auth_entity
@@ -94,6 +104,8 @@ class DialOptions:
94
104
  self.allow_insecure_with_creds_downgrade = allow_insecure_with_creds_downgrade
95
105
  self.max_reconnect_attempts = max_reconnect_attempts
96
106
  self.timeout = timeout
107
+ self.initial_connection_attempts = initial_connection_attempts
108
+ self.initial_connection_attempt_timeout = initial_connection_attempt_timeout if initial_connection_attempt_timeout else timeout
97
109
 
98
110
  @classmethod
99
111
  def with_api_key(cls, api_key: str, api_key_id: str) -> Self:
@@ -220,8 +232,9 @@ class _Runtime:
220
232
  _ptr: ctypes.c_void_p
221
233
 
222
234
  def __init__(self) -> None:
235
+ suffix = "dylib" if sys.platform == "darwin" else "so" if "linux" in sys.platform else "dll"
223
236
  LOGGER.debug("Creating new viam-rust-utils runtime")
224
- libname = pathlib.Path(__file__).parent.absolute() / f"libviam_rust_utils.{'dylib' if sys.platform == 'darwin' else 'so'}"
237
+ libname = pathlib.Path(__file__).parent.absolute() / f"libviam_rust_utils.{suffix}"
225
238
  self._lib = ctypes.CDLL(libname.__str__())
226
239
  self._lib.init_rust_runtime.argtypes = ()
227
240
  self._lib.init_rust_runtime.restype = ctypes.c_void_p
@@ -279,8 +292,38 @@ class _Runtime:
279
292
 
280
293
 
281
294
  async def dial(address: str, options: Optional[DialOptions] = None) -> ViamChannel:
295
+ options = options if options else DialOptions()
296
+ timeout = options.timeout
297
+ options.timeout = options.initial_connection_attempt_timeout
298
+ if options.initial_connection_attempts == 0:
299
+ options.initial_connection_attempts = -1
300
+ attempt_countdown = options.initial_connection_attempts
301
+ exception: Exception
302
+ while attempt_countdown != 0:
303
+ try:
304
+ chan = await _dial_inner(address, options)
305
+ options.timeout = timeout
306
+ return chan
307
+ except Exception as e:
308
+ exception = e
309
+ attempt_countdown -= 1
310
+ # the only way we could get here is if we failed at least once which means we've set the
311
+ # exception, so typechecker concerns about a possibly unbounded variable are unfounded
312
+ raise exception # type: ignore
313
+
314
+
315
+ def _create_chan(path: str) -> Channel:
316
+ if sys.platform == "win32" or sys.platform == "cygwin":
317
+ # we have to use a TCP connection, so we want a host and port for our channel.
318
+ host, port = _host_port_from_url(path)
319
+ return Channel(host=host, port=port, ssl=None)
320
+ # we're not on windows and so can use a UDS
321
+ return Channel(path=path, ssl=None)
322
+
323
+
324
+ async def _dial_inner(address: str, options: Optional[DialOptions] = None) -> ViamChannel:
282
325
  async def send_request(event: SendRequest):
283
- event.metadata["viam-client"] = f"python;v{SDK_VERSION};v{API_VERSION}"
326
+ event.metadata["viam_client"] = f"python;v{SDK_VERSION};v{API_VERSION}"
284
327
 
285
328
  opts = options if options else DialOptions()
286
329
  if opts.disable_webrtc:
@@ -291,7 +334,7 @@ async def dial(address: str, options: Optional[DialOptions] = None) -> ViamChann
291
334
  path, path_ptr = await runtime.dial(address, opts)
292
335
  if path:
293
336
  LOGGER.info(f"Connecting to socket: {path}")
294
- chan = Channel(path=path, ssl=None)
337
+ chan = _create_chan(path)
295
338
  listen(chan, SendRequest, send_request)
296
339
 
297
340
  def release():
Binary file
viam/rpc/server.py CHANGED
@@ -1,3 +1,4 @@
1
+ import sys
1
2
  from typing import TYPE_CHECKING, Callable, List, Optional
2
3
 
3
4
  from grpclib import GRPCError, Status
@@ -82,6 +83,24 @@ class Server(ResourceManager):
82
83
 
83
84
  event.method_func = log_resource_name
84
85
 
86
+ async def _serve(
87
+ self,
88
+ host: Optional[str] = "localhost",
89
+ port: Optional[int] = 9090,
90
+ log_level: Optional[int] = logging.INFO,
91
+ *,
92
+ path: Optional[str] = None,
93
+ ):
94
+ if path:
95
+ await self._server.start(path=path)
96
+ LOGGER.info(f"Serving on {path}")
97
+ else:
98
+ await self._server.start(host, port)
99
+ LOGGER.info(f"Serving on {host}:{port}")
100
+ await self._server.wait_closed()
101
+ await self.close()
102
+ LOGGER.debug("gRPC server closed")
103
+
85
104
  async def serve(
86
105
  self,
87
106
  host: Optional[str] = "localhost",
@@ -105,16 +124,11 @@ class Server(ResourceManager):
105
124
  logging.setLevel(log_level)
106
125
  listen(self._server, RecvRequest, self._grpc_recvrequest_handler)
107
126
 
108
- with graceful_exit([self._server]):
109
- if path:
110
- await self._server.start(path=path)
111
- LOGGER.info(f"Serving on {path}")
112
- else:
113
- await self._server.start(host, port)
114
- LOGGER.info(f"Serving on {host}:{port}")
115
- await self._server.wait_closed()
116
- await self.close()
117
- LOGGER.debug("gRPC server closed")
127
+ if sys.platform != "win32":
128
+ with graceful_exit([self._server]):
129
+ await self._serve(host=host, port=port, log_level=log_level, path=path)
130
+ else:
131
+ await self._serve(host=host, port=port, log_level=log_level, path=path)
118
132
 
119
133
  @classmethod
120
134
  async def create_and_serve(
@@ -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
  *,