viam-sdk 0.45.2__py3-none-win_amd64.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 (476) hide show
  1. viam/__init__.py +71 -0
  2. viam/app/__init__.py +0 -0
  3. viam/app/_logs.py +34 -0
  4. viam/app/app_client.py +2525 -0
  5. viam/app/billing_client.py +143 -0
  6. viam/app/data_client.py +1715 -0
  7. viam/app/ml_training_client.py +251 -0
  8. viam/app/provisioning_client.py +95 -0
  9. viam/app/viam_client.py +260 -0
  10. viam/components/__init__.py +0 -0
  11. viam/components/arm/__init__.py +16 -0
  12. viam/components/arm/arm.py +223 -0
  13. viam/components/arm/client.py +124 -0
  14. viam/components/arm/service.py +123 -0
  15. viam/components/audio_input/__init__.py +18 -0
  16. viam/components/audio_input/audio_input.py +81 -0
  17. viam/components/audio_input/client.py +70 -0
  18. viam/components/audio_input/service.py +114 -0
  19. viam/components/base/__init__.py +13 -0
  20. viam/components/base/base.py +260 -0
  21. viam/components/base/client.py +153 -0
  22. viam/components/base/service.py +138 -0
  23. viam/components/board/__init__.py +9 -0
  24. viam/components/board/board.py +414 -0
  25. viam/components/board/client.py +241 -0
  26. viam/components/board/service.py +223 -0
  27. viam/components/button/__init__.py +10 -0
  28. viam/components/button/button.py +41 -0
  29. viam/components/button/client.py +52 -0
  30. viam/components/button/service.py +46 -0
  31. viam/components/camera/__init__.py +22 -0
  32. viam/components/camera/camera.py +138 -0
  33. viam/components/camera/client.py +98 -0
  34. viam/components/camera/service.py +105 -0
  35. viam/components/component_base.py +65 -0
  36. viam/components/encoder/__init__.py +18 -0
  37. viam/components/encoder/client.py +83 -0
  38. viam/components/encoder/encoder.py +118 -0
  39. viam/components/encoder/service.py +72 -0
  40. viam/components/gantry/__init__.py +11 -0
  41. viam/components/gantry/client.py +115 -0
  42. viam/components/gantry/gantry.py +156 -0
  43. viam/components/gantry/service.py +113 -0
  44. viam/components/generic/__init__.py +18 -0
  45. viam/components/generic/client.py +62 -0
  46. viam/components/generic/generic.py +76 -0
  47. viam/components/generic/service.py +40 -0
  48. viam/components/gripper/__init__.py +11 -0
  49. viam/components/gripper/client.py +85 -0
  50. viam/components/gripper/gripper.py +114 -0
  51. viam/components/gripper/service.py +81 -0
  52. viam/components/input/__init__.py +15 -0
  53. viam/components/input/client.py +194 -0
  54. viam/components/input/input.py +297 -0
  55. viam/components/input/service.py +175 -0
  56. viam/components/motor/__init__.py +11 -0
  57. viam/components/motor/client.py +168 -0
  58. viam/components/motor/motor.py +301 -0
  59. viam/components/motor/service.py +150 -0
  60. viam/components/movement_sensor/__init__.py +21 -0
  61. viam/components/movement_sensor/client.py +161 -0
  62. viam/components/movement_sensor/movement_sensor.py +253 -0
  63. viam/components/movement_sensor/service.py +146 -0
  64. viam/components/pose_tracker/__init__.py +17 -0
  65. viam/components/pose_tracker/client.py +50 -0
  66. viam/components/pose_tracker/pose_tracker.py +40 -0
  67. viam/components/pose_tracker/service.py +45 -0
  68. viam/components/power_sensor/__init__.py +17 -0
  69. viam/components/power_sensor/client.py +86 -0
  70. viam/components/power_sensor/power_sensor.py +104 -0
  71. viam/components/power_sensor/service.py +72 -0
  72. viam/components/sensor/__init__.py +18 -0
  73. viam/components/sensor/client.py +49 -0
  74. viam/components/sensor/sensor.py +48 -0
  75. viam/components/sensor/service.py +51 -0
  76. viam/components/servo/__init__.py +11 -0
  77. viam/components/servo/client.py +86 -0
  78. viam/components/servo/service.py +80 -0
  79. viam/components/servo/servo.py +114 -0
  80. viam/components/switch/__init__.py +10 -0
  81. viam/components/switch/client.py +83 -0
  82. viam/components/switch/service.py +72 -0
  83. viam/components/switch/switch.py +95 -0
  84. viam/errors.py +105 -0
  85. viam/gen/__init__.py +0 -0
  86. viam/gen/app/__init__.py +0 -0
  87. viam/gen/app/agent/__init__.py +0 -0
  88. viam/gen/app/agent/v1/__init__.py +0 -0
  89. viam/gen/app/agent/v1/agent_grpc.py +29 -0
  90. viam/gen/app/agent/v1/agent_pb2.py +47 -0
  91. viam/gen/app/agent/v1/agent_pb2.pyi +280 -0
  92. viam/gen/app/cloudslam/__init__.py +0 -0
  93. viam/gen/app/cloudslam/v1/__init__.py +0 -0
  94. viam/gen/app/cloudslam/v1/cloud_slam_grpc.py +70 -0
  95. viam/gen/app/cloudslam/v1/cloud_slam_pb2.py +54 -0
  96. viam/gen/app/cloudslam/v1/cloud_slam_pb2.pyi +384 -0
  97. viam/gen/app/data/__init__.py +0 -0
  98. viam/gen/app/data/v1/__init__.py +0 -0
  99. viam/gen/app/data/v1/data_grpc.py +206 -0
  100. viam/gen/app/data/v1/data_pb2.py +178 -0
  101. viam/gen/app/data/v1/data_pb2.pyi +1485 -0
  102. viam/gen/app/datapipelines/__init__.py +0 -0
  103. viam/gen/app/datapipelines/v1/__init__.py +0 -0
  104. viam/gen/app/datapipelines/v1/data_pipelines_grpc.py +84 -0
  105. viam/gen/app/datapipelines/v1/data_pipelines_pb2.py +56 -0
  106. viam/gen/app/datapipelines/v1/data_pipelines_pb2.pyi +370 -0
  107. viam/gen/app/dataset/__init__.py +0 -0
  108. viam/gen/app/dataset/v1/__init__.py +0 -0
  109. viam/gen/app/dataset/v1/dataset_grpc.py +60 -0
  110. viam/gen/app/dataset/v1/dataset_pb2.py +40 -0
  111. viam/gen/app/dataset/v1/dataset_pb2.pyi +179 -0
  112. viam/gen/app/datasync/__init__.py +0 -0
  113. viam/gen/app/datasync/v1/__init__.py +0 -0
  114. viam/gen/app/datasync/v1/data_sync_grpc.py +47 -0
  115. viam/gen/app/datasync/v1/data_sync_pb2.py +70 -0
  116. viam/gen/app/datasync/v1/data_sync_pb2.pyi +425 -0
  117. viam/gen/app/mlinference/__init__.py +0 -0
  118. viam/gen/app/mlinference/v1/__init__.py +0 -0
  119. viam/gen/app/mlinference/v1/ml_inference_grpc.py +28 -0
  120. viam/gen/app/mlinference/v1/ml_inference_pb2.py +23 -0
  121. viam/gen/app/mlinference/v1/ml_inference_pb2.pyi +63 -0
  122. viam/gen/app/mltraining/__init__.py +0 -0
  123. viam/gen/app/mltraining/v1/__init__.py +0 -0
  124. viam/gen/app/mltraining/v1/ml_training_grpc.py +78 -0
  125. viam/gen/app/mltraining/v1/ml_training_pb2.py +124 -0
  126. viam/gen/app/mltraining/v1/ml_training_pb2.pyi +415 -0
  127. viam/gen/app/packages/__init__.py +0 -0
  128. viam/gen/app/packages/v1/__init__.py +0 -0
  129. viam/gen/app/packages/v1/packages_grpc.py +54 -0
  130. viam/gen/app/packages/v1/packages_pb2.py +52 -0
  131. viam/gen/app/packages/v1/packages_pb2.pyi +311 -0
  132. viam/gen/app/v1/__init__.py +0 -0
  133. viam/gen/app/v1/app_grpc.py +863 -0
  134. viam/gen/app/v1/app_pb2.py +649 -0
  135. viam/gen/app/v1/app_pb2.pyi +5279 -0
  136. viam/gen/app/v1/billing_grpc.py +76 -0
  137. viam/gen/app/v1/billing_pb2.py +92 -0
  138. viam/gen/app/v1/billing_pb2.pyi +463 -0
  139. viam/gen/app/v1/end_user_grpc.py +59 -0
  140. viam/gen/app/v1/end_user_pb2.py +55 -0
  141. viam/gen/app/v1/end_user_pb2.pyi +181 -0
  142. viam/gen/app/v1/robot_grpc.py +55 -0
  143. viam/gen/app/v1/robot_pb2.py +127 -0
  144. viam/gen/app/v1/robot_pb2.pyi +1202 -0
  145. viam/gen/common/__init__.py +0 -0
  146. viam/gen/common/v1/__init__.py +0 -0
  147. viam/gen/common/v1/common_grpc.py +0 -0
  148. viam/gen/common/v1/common_pb2.py +78 -0
  149. viam/gen/common/v1/common_pb2.pyi +687 -0
  150. viam/gen/component/__init__.py +0 -0
  151. viam/gen/component/arm/__init__.py +0 -0
  152. viam/gen/component/arm/v1/__init__.py +0 -0
  153. viam/gen/component/arm/v1/arm_grpc.py +102 -0
  154. viam/gen/component/arm/v1/arm_pb2.py +74 -0
  155. viam/gen/component/arm/v1/arm_pb2.pyi +344 -0
  156. viam/gen/component/audioinput/__init__.py +0 -0
  157. viam/gen/component/audioinput/v1/__init__.py +0 -0
  158. viam/gen/component/audioinput/v1/audioinput_grpc.py +63 -0
  159. viam/gen/component/audioinput/v1/audioinput_pb2.py +45 -0
  160. viam/gen/component/audioinput/v1/audioinput_pb2.pyi +179 -0
  161. viam/gen/component/base/__init__.py +0 -0
  162. viam/gen/component/base/v1/__init__.py +0 -0
  163. viam/gen/component/base/v1/base_grpc.py +94 -0
  164. viam/gen/component/base/v1/base_pb2.py +66 -0
  165. viam/gen/component/base/v1/base_pb2.pyi +258 -0
  166. viam/gen/component/board/__init__.py +0 -0
  167. viam/gen/component/board/v1/__init__.py +0 -0
  168. viam/gen/component/board/v1/board_grpc.py +127 -0
  169. viam/gen/component/board/v1/board_pb2.py +103 -0
  170. viam/gen/component/board/v1/board_pb2.pyi +496 -0
  171. viam/gen/component/button/__init__.py +0 -0
  172. viam/gen/component/button/v1/__init__.py +0 -0
  173. viam/gen/component/button/v1/button_grpc.py +38 -0
  174. viam/gen/component/button/v1/button_pb2.py +28 -0
  175. viam/gen/component/button/v1/button_pb2.pyi +39 -0
  176. viam/gen/component/camera/__init__.py +0 -0
  177. viam/gen/component/camera/v1/__init__.py +0 -0
  178. viam/gen/component/camera/v1/camera_grpc.py +79 -0
  179. viam/gen/component/camera/v1/camera_pb2.py +67 -0
  180. viam/gen/component/camera/v1/camera_pb2.pyi +373 -0
  181. viam/gen/component/encoder/__init__.py +0 -0
  182. viam/gen/component/encoder/v1/__init__.py +0 -0
  183. viam/gen/component/encoder/v1/encoder_grpc.py +62 -0
  184. viam/gen/component/encoder/v1/encoder_pb2.py +44 -0
  185. viam/gen/component/encoder/v1/encoder_pb2.pyi +147 -0
  186. viam/gen/component/gantry/__init__.py +0 -0
  187. viam/gen/component/gantry/v1/__init__.py +0 -0
  188. viam/gen/component/gantry/v1/gantry_grpc.py +86 -0
  189. viam/gen/component/gantry/v1/gantry_pb2.py +62 -0
  190. viam/gen/component/gantry/v1/gantry_pb2.pyi +239 -0
  191. viam/gen/component/generic/__init__.py +0 -0
  192. viam/gen/component/generic/v1/__init__.py +0 -0
  193. viam/gen/component/generic/v1/generic_grpc.py +37 -0
  194. viam/gen/component/generic/v1/generic_pb2.py +23 -0
  195. viam/gen/component/generic/v1/generic_pb2.pyi +6 -0
  196. viam/gen/component/gripper/__init__.py +0 -0
  197. viam/gen/component/gripper/v1/__init__.py +0 -0
  198. viam/gen/component/gripper/v1/gripper_grpc.py +70 -0
  199. viam/gen/component/gripper/v1/gripper_pb2.py +48 -0
  200. viam/gen/component/gripper/v1/gripper_pb2.pyi +137 -0
  201. viam/gen/component/inputcontroller/__init__.py +0 -0
  202. viam/gen/component/inputcontroller/v1/__init__.py +0 -0
  203. viam/gen/component/inputcontroller/v1/input_controller_grpc.py +71 -0
  204. viam/gen/component/inputcontroller/v1/input_controller_pb2.py +55 -0
  205. viam/gen/component/inputcontroller/v1/input_controller_pb2.pyi +243 -0
  206. viam/gen/component/motor/__init__.py +0 -0
  207. viam/gen/component/motor/v1/__init__.py +0 -0
  208. viam/gen/component/motor/v1/motor_grpc.py +118 -0
  209. viam/gen/component/motor/v1/motor_pb2.py +86 -0
  210. viam/gen/component/motor/v1/motor_pb2.pyi +368 -0
  211. viam/gen/component/movementsensor/__init__.py +0 -0
  212. viam/gen/component/movementsensor/v1/__init__.py +0 -0
  213. viam/gen/component/movementsensor/v1/movementsensor_grpc.py +110 -0
  214. viam/gen/component/movementsensor/v1/movementsensor_pb2.py +78 -0
  215. viam/gen/component/movementsensor/v1/movementsensor_pb2.pyi +384 -0
  216. viam/gen/component/posetracker/__init__.py +0 -0
  217. viam/gen/component/posetracker/v1/__init__.py +0 -0
  218. viam/gen/component/posetracker/v1/pose_tracker_grpc.py +46 -0
  219. viam/gen/component/posetracker/v1/pose_tracker_pb2.py +34 -0
  220. viam/gen/component/posetracker/v1/pose_tracker_pb2.pyi +79 -0
  221. viam/gen/component/powersensor/__init__.py +0 -0
  222. viam/gen/component/powersensor/v1/__init__.py +0 -0
  223. viam/gen/component/powersensor/v1/powersensor_grpc.py +62 -0
  224. viam/gen/component/powersensor/v1/powersensor_pb2.py +42 -0
  225. viam/gen/component/powersensor/v1/powersensor_pb2.pyi +124 -0
  226. viam/gen/component/sensor/__init__.py +0 -0
  227. viam/gen/component/sensor/v1/__init__.py +0 -0
  228. viam/gen/component/sensor/v1/sensor_grpc.py +45 -0
  229. viam/gen/component/sensor/v1/sensor_pb2.py +25 -0
  230. viam/gen/component/sensor/v1/sensor_pb2.pyi +6 -0
  231. viam/gen/component/servo/__init__.py +0 -0
  232. viam/gen/component/servo/v1/__init__.py +0 -0
  233. viam/gen/component/servo/v1/servo_grpc.py +70 -0
  234. viam/gen/component/servo/v1/servo_pb2.py +50 -0
  235. viam/gen/component/servo/v1/servo_pb2.pyi +150 -0
  236. viam/gen/component/switch/__init__.py +0 -0
  237. viam/gen/component/switch/v1/__init__.py +0 -0
  238. viam/gen/component/switch/v1/switch_grpc.py +54 -0
  239. viam/gen/component/switch/v1/switch_pb2.py +40 -0
  240. viam/gen/component/switch/v1/switch_pb2.pyi +109 -0
  241. viam/gen/component/testecho/__init__.py +0 -0
  242. viam/gen/component/testecho/v1/__init__.py +0 -0
  243. viam/gen/component/testecho/v1/testecho_grpc.py +52 -0
  244. viam/gen/component/testecho/v1/testecho_pb2.py +36 -0
  245. viam/gen/component/testecho/v1/testecho_pb2.pyi +114 -0
  246. viam/gen/module/__init__.py +0 -0
  247. viam/gen/module/v1/__init__.py +0 -0
  248. viam/gen/module/v1/module_grpc.py +61 -0
  249. viam/gen/module/v1/module_pb2.py +43 -0
  250. viam/gen/module/v1/module_pb2.pyi +211 -0
  251. viam/gen/proto/__init__.py +0 -0
  252. viam/gen/proto/rpc/__init__.py +0 -0
  253. viam/gen/proto/rpc/examples/__init__.py +0 -0
  254. viam/gen/proto/rpc/examples/echo/__init__.py +0 -0
  255. viam/gen/proto/rpc/examples/echo/v1/__init__.py +0 -0
  256. viam/gen/proto/rpc/examples/echo/v1/echo_grpc.py +44 -0
  257. viam/gen/proto/rpc/examples/echo/v1/echo_pb2.py +32 -0
  258. viam/gen/proto/rpc/examples/echo/v1/echo_pb2.pyi +87 -0
  259. viam/gen/proto/rpc/examples/echoresource/__init__.py +0 -0
  260. viam/gen/proto/rpc/examples/echoresource/v1/__init__.py +0 -0
  261. viam/gen/proto/rpc/examples/echoresource/v1/echoresource_grpc.py +43 -0
  262. viam/gen/proto/rpc/examples/echoresource/v1/echoresource_pb2.py +29 -0
  263. viam/gen/proto/rpc/examples/echoresource/v1/echoresource_pb2.pyi +93 -0
  264. viam/gen/proto/rpc/v1/__init__.py +0 -0
  265. viam/gen/proto/rpc/v1/auth_grpc.py +47 -0
  266. viam/gen/proto/rpc/v1/auth_pb2.py +34 -0
  267. viam/gen/proto/rpc/v1/auth_pb2.pyi +92 -0
  268. viam/gen/proto/rpc/webrtc/__init__.py +0 -0
  269. viam/gen/proto/rpc/webrtc/v1/__init__.py +0 -0
  270. viam/gen/proto/rpc/webrtc/v1/grpc_grpc.py +0 -0
  271. viam/gen/proto/rpc/webrtc/v1/grpc_pb2.py +43 -0
  272. viam/gen/proto/rpc/webrtc/v1/grpc_pb2.pyi +304 -0
  273. viam/gen/proto/rpc/webrtc/v1/signaling_grpc.py +54 -0
  274. viam/gen/proto/rpc/webrtc/v1/signaling_pb2.py +70 -0
  275. viam/gen/proto/rpc/webrtc/v1/signaling_pb2.pyi +496 -0
  276. viam/gen/provisioning/__init__.py +0 -0
  277. viam/gen/provisioning/v1/__init__.py +0 -0
  278. viam/gen/provisioning/v1/provisioning_grpc.py +51 -0
  279. viam/gen/provisioning/v1/provisioning_pb2.py +39 -0
  280. viam/gen/provisioning/v1/provisioning_pb2.pyi +188 -0
  281. viam/gen/robot/__init__.py +0 -0
  282. viam/gen/robot/v1/__init__.py +0 -0
  283. viam/gen/robot/v1/robot_grpc.py +208 -0
  284. viam/gen/robot/v1/robot_pb2.py +188 -0
  285. viam/gen/robot/v1/robot_pb2.pyi +1020 -0
  286. viam/gen/service/__init__.py +0 -0
  287. viam/gen/service/datamanager/__init__.py +0 -0
  288. viam/gen/service/datamanager/v1/__init__.py +0 -0
  289. viam/gen/service/datamanager/v1/data_manager_grpc.py +38 -0
  290. viam/gen/service/datamanager/v1/data_manager_pb2.py +28 -0
  291. viam/gen/service/datamanager/v1/data_manager_pb2.pyi +39 -0
  292. viam/gen/service/discovery/__init__.py +0 -0
  293. viam/gen/service/discovery/v1/__init__.py +0 -0
  294. viam/gen/service/discovery/v1/discovery_grpc.py +39 -0
  295. viam/gen/service/discovery/v1/discovery_pb2.py +29 -0
  296. viam/gen/service/discovery/v1/discovery_pb2.pyi +51 -0
  297. viam/gen/service/generic/__init__.py +0 -0
  298. viam/gen/service/generic/v1/__init__.py +0 -0
  299. viam/gen/service/generic/v1/generic_grpc.py +29 -0
  300. viam/gen/service/generic/v1/generic_pb2.py +21 -0
  301. viam/gen/service/generic/v1/generic_pb2.pyi +6 -0
  302. viam/gen/service/mlmodel/__init__.py +0 -0
  303. viam/gen/service/mlmodel/v1/__init__.py +0 -0
  304. viam/gen/service/mlmodel/v1/mlmodel_grpc.py +37 -0
  305. viam/gen/service/mlmodel/v1/mlmodel_pb2.py +83 -0
  306. viam/gen/service/mlmodel/v1/mlmodel_pb2.pyi +480 -0
  307. viam/gen/service/motion/__init__.py +0 -0
  308. viam/gen/service/motion/v1/__init__.py +0 -0
  309. viam/gen/service/motion/v1/motion_grpc.py +87 -0
  310. viam/gen/service/motion/v1/motion_pb2.py +97 -0
  311. viam/gen/service/motion/v1/motion_pb2.pyi +838 -0
  312. viam/gen/service/navigation/__init__.py +0 -0
  313. viam/gen/service/navigation/v1/__init__.py +0 -0
  314. viam/gen/service/navigation/v1/navigation_grpc.py +102 -0
  315. viam/gen/service/navigation/v1/navigation_pb2.py +84 -0
  316. viam/gen/service/navigation/v1/navigation_pb2.pyi +419 -0
  317. viam/gen/service/sensors/__init__.py +0 -0
  318. viam/gen/service/sensors/v1/__init__.py +0 -0
  319. viam/gen/service/sensors/v1/sensors_grpc.py +46 -0
  320. viam/gen/service/sensors/v1/sensors_pb2.py +68 -0
  321. viam/gen/service/sensors/v1/sensors_pb2.pyi +137 -0
  322. viam/gen/service/shell/__init__.py +0 -0
  323. viam/gen/service/shell/v1/__init__.py +0 -0
  324. viam/gen/service/shell/v1/shell_grpc.py +55 -0
  325. viam/gen/service/shell/v1/shell_pb2.py +45 -0
  326. viam/gen/service/shell/v1/shell_pb2.pyi +307 -0
  327. viam/gen/service/slam/__init__.py +0 -0
  328. viam/gen/service/slam/v1/__init__.py +0 -0
  329. viam/gen/service/slam/v1/slam_grpc.py +61 -0
  330. viam/gen/service/slam/v1/slam_pb2.py +51 -0
  331. viam/gen/service/slam/v1/slam_pb2.pyi +213 -0
  332. viam/gen/service/vision/__init__.py +0 -0
  333. viam/gen/service/vision/v1/__init__.py +0 -0
  334. viam/gen/service/vision/v1/vision_grpc.py +87 -0
  335. viam/gen/service/vision/v1/vision_pb2.py +69 -0
  336. viam/gen/service/vision/v1/vision_pb2.pyi +454 -0
  337. viam/gen/stream/__init__.py +0 -0
  338. viam/gen/stream/v1/__init__.py +0 -0
  339. viam/gen/stream/v1/stream_grpc.py +59 -0
  340. viam/gen/stream/v1/stream_pb2.py +39 -0
  341. viam/gen/stream/v1/stream_pb2.pyi +161 -0
  342. viam/gen/tagger/__init__.py +0 -0
  343. viam/gen/tagger/v1/__init__.py +0 -0
  344. viam/gen/tagger/v1/tagger_grpc.py +0 -0
  345. viam/gen/tagger/v1/tagger_pb2.py +16 -0
  346. viam/gen/tagger/v1/tagger_pb2.pyi +15 -0
  347. viam/logging.py +216 -0
  348. viam/media/__init__.py +0 -0
  349. viam/media/audio.py +16 -0
  350. viam/media/utils/__init__.py +0 -0
  351. viam/media/utils/pil/__init__.py +51 -0
  352. viam/media/utils/pil/viam_rgba_plugin.py +73 -0
  353. viam/media/viam_rgba.py +10 -0
  354. viam/media/video.py +217 -0
  355. viam/module/__init__.py +5 -0
  356. viam/module/module.py +281 -0
  357. viam/module/service.py +66 -0
  358. viam/module/types.py +23 -0
  359. viam/operations.py +124 -0
  360. viam/proto/__init__.py +0 -0
  361. viam/proto/app/__init__.py +554 -0
  362. viam/proto/app/agent/__init__.py +28 -0
  363. viam/proto/app/billing.py +58 -0
  364. viam/proto/app/cloudslam/__init__.py +48 -0
  365. viam/proto/app/data/__init__.py +138 -0
  366. viam/proto/app/datapipelines/__init__.py +56 -0
  367. viam/proto/app/dataset/__init__.py +36 -0
  368. viam/proto/app/datasync/__init__.py +44 -0
  369. viam/proto/app/end_user.py +34 -0
  370. viam/proto/app/mlinference/__init__.py +15 -0
  371. viam/proto/app/mltraining/__init__.py +52 -0
  372. viam/proto/app/packages/__init__.py +38 -0
  373. viam/proto/app/robot.py +84 -0
  374. viam/proto/common/__init__.py +66 -0
  375. viam/proto/component/__init__.py +0 -0
  376. viam/proto/component/arm/__init__.py +48 -0
  377. viam/proto/component/audioinput/__init__.py +30 -0
  378. viam/proto/component/base/__init__.py +42 -0
  379. viam/proto/component/board/__init__.py +62 -0
  380. viam/proto/component/button/__init__.py +15 -0
  381. viam/proto/component/camera/__init__.py +46 -0
  382. viam/proto/component/encoder/__init__.py +28 -0
  383. viam/proto/component/gantry/__init__.py +40 -0
  384. viam/proto/component/generic/__init__.py +12 -0
  385. viam/proto/component/gripper/__init__.py +30 -0
  386. viam/proto/component/inputcontroller/__init__.py +38 -0
  387. viam/proto/component/motor/__init__.py +56 -0
  388. viam/proto/component/movementsensor/__init__.py +50 -0
  389. viam/proto/component/posetracker/__init__.py +19 -0
  390. viam/proto/component/powersensor/__init__.py +30 -0
  391. viam/proto/component/sensor/__init__.py +12 -0
  392. viam/proto/component/servo/__init__.py +32 -0
  393. viam/proto/component/switch/__init__.py +26 -0
  394. viam/proto/component/testecho/__init__.py +30 -0
  395. viam/proto/module/__init__.py +38 -0
  396. viam/proto/provisioning/__init__.py +36 -0
  397. viam/proto/robot/__init__.py +130 -0
  398. viam/proto/rpc/__init__.py +0 -0
  399. viam/proto/rpc/auth.py +34 -0
  400. viam/proto/rpc/examples/__init__.py +0 -0
  401. viam/proto/rpc/examples/echo/__init__.py +26 -0
  402. viam/proto/rpc/examples/echoresource/__init__.py +30 -0
  403. viam/proto/rpc/webrtc/__init__.py +0 -0
  404. viam/proto/rpc/webrtc/grpc.py +36 -0
  405. viam/proto/rpc/webrtc/signaling.py +58 -0
  406. viam/proto/service/__init__.py +0 -0
  407. viam/proto/service/datamanager/__init__.py +19 -0
  408. viam/proto/service/discovery/__init__.py +15 -0
  409. viam/proto/service/generic/__init__.py +12 -0
  410. viam/proto/service/mlmodel/__init__.py +54 -0
  411. viam/proto/service/motion/__init__.py +68 -0
  412. viam/proto/service/navigation/__init__.py +58 -0
  413. viam/proto/service/sensors/__init__.py +18 -0
  414. viam/proto/service/shell/__init__.py +36 -0
  415. viam/proto/service/slam/__init__.py +36 -0
  416. viam/proto/service/vision/__init__.py +46 -0
  417. viam/proto/stream/__init__.py +36 -0
  418. viam/proto/tagger/__init__.py +6 -0
  419. viam/py.typed +0 -0
  420. viam/resource/__init__.py +0 -0
  421. viam/resource/base.py +123 -0
  422. viam/resource/easy_resource.py +153 -0
  423. viam/resource/manager.py +126 -0
  424. viam/resource/registry.py +199 -0
  425. viam/resource/rpc_client_base.py +65 -0
  426. viam/resource/rpc_service_base.py +48 -0
  427. viam/resource/types.py +213 -0
  428. viam/robot/__init__.py +0 -0
  429. viam/robot/client.py +909 -0
  430. viam/robot/service.py +69 -0
  431. viam/rpc/__init__.py +0 -0
  432. viam/rpc/dial.py +420 -0
  433. viam/rpc/libviam_rust_utils.dll +0 -0
  434. viam/rpc/server.py +201 -0
  435. viam/rpc/signaling.py +29 -0
  436. viam/rpc/types.py +22 -0
  437. viam/services/__init__.py +0 -0
  438. viam/services/discovery/__init__.py +12 -0
  439. viam/services/discovery/client.py +55 -0
  440. viam/services/discovery/discovery.py +52 -0
  441. viam/services/discovery/service.py +43 -0
  442. viam/services/generic/__init__.py +18 -0
  443. viam/services/generic/client.py +58 -0
  444. viam/services/generic/generic.py +58 -0
  445. viam/services/generic/service.py +29 -0
  446. viam/services/mlmodel/__init__.py +24 -0
  447. viam/services/mlmodel/client.py +37 -0
  448. viam/services/mlmodel/mlmodel.py +78 -0
  449. viam/services/mlmodel/service.py +38 -0
  450. viam/services/mlmodel/utils.py +101 -0
  451. viam/services/motion/__init__.py +17 -0
  452. viam/services/motion/client.py +215 -0
  453. viam/services/motion/motion.py +378 -0
  454. viam/services/motion/service.py +132 -0
  455. viam/services/navigation/__init__.py +11 -0
  456. viam/services/navigation/client.py +99 -0
  457. viam/services/navigation/navigation.py +250 -0
  458. viam/services/navigation/service.py +137 -0
  459. viam/services/service_base.py +78 -0
  460. viam/services/service_client_base.py +46 -0
  461. viam/services/slam/__init__.py +17 -0
  462. viam/services/slam/client.py +62 -0
  463. viam/services/slam/service.py +75 -0
  464. viam/services/slam/slam.py +111 -0
  465. viam/services/vision/__init__.py +15 -0
  466. viam/services/vision/client.py +206 -0
  467. viam/services/vision/service.py +146 -0
  468. viam/services/vision/vision.py +315 -0
  469. viam/sessions_client.py +245 -0
  470. viam/streams.py +44 -0
  471. viam/utils.py +365 -0
  472. viam/version_metadata.py +4 -0
  473. viam_sdk-0.45.2.dist-info/METADATA +157 -0
  474. viam_sdk-0.45.2.dist-info/RECORD +476 -0
  475. viam_sdk-0.45.2.dist-info/WHEEL +4 -0
  476. viam_sdk-0.45.2.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,245 @@
1
+ import asyncio
2
+ import importlib
3
+ import pkgutil
4
+ import sys
5
+ from copy import deepcopy
6
+ from datetime import timedelta
7
+ from enum import IntEnum
8
+ from threading import Lock, Thread
9
+ from typing import MutableMapping, Optional
10
+
11
+ from grpclib import Status
12
+ from grpclib.client import Channel
13
+ from grpclib.events import RecvTrailingMetadata, SendRequest, listen
14
+ from grpclib.exceptions import GRPCError, StreamTerminatedError
15
+ from grpclib.metadata import _MetadataLike
16
+
17
+ from viam import logging
18
+ from viam.gen.common.v1.common_pb2 import safety_heartbeat_monitored
19
+ from viam.proto.robot import RobotServiceStub, SendSessionHeartbeatRequest, StartSessionRequest, StartSessionResponse
20
+ from viam.rpc.dial import DialOptions, dial
21
+
22
+ LOGGER = logging.getLogger(__name__)
23
+ SESSION_METADATA_KEY = "viam-sid"
24
+
25
+
26
+ class _SupportedState(IntEnum):
27
+ UNKNOWN = 0
28
+ TRUE = 1
29
+ FALSE = 2
30
+
31
+
32
+ class SessionsClient:
33
+ """
34
+ A Session allows a client to express that it is actively connected and
35
+ supports stopping actuating components when it's not.
36
+ """
37
+
38
+ channel: Channel
39
+ client: RobotServiceStub
40
+ _address: str # direct dial address, when using webRTC this is the local socket rather than a robot address
41
+ _robot_address: Optional[str] # the actual machine address on app.viam.com. important for creating a sessions client on Windows
42
+ _dial_options: DialOptions
43
+ _disabled: bool
44
+ _lock: Lock
45
+ _current_id: str
46
+ _heartbeat_interval: Optional[timedelta]
47
+ _supported: _SupportedState
48
+ _thread: Optional[Thread]
49
+
50
+ _HEARTBEAT_MONITORED_METHODS: MutableMapping[str, bool] = {}
51
+
52
+ def __init__(
53
+ self,
54
+ channel: Channel,
55
+ direct_dial_address: str,
56
+ dial_options: Optional[DialOptions],
57
+ *,
58
+ disabled: bool = False,
59
+ robot_addr: Optional[str] = None,
60
+ ):
61
+ self.channel = channel
62
+ self.client = RobotServiceStub(channel)
63
+ self._address = direct_dial_address
64
+ self._robot_address = robot_addr
65
+ self._disabled = disabled
66
+ self._dial_options = deepcopy(dial_options) if dial_options is not None else DialOptions()
67
+ if sys.platform != "win32" and sys.platform != "cygwin":
68
+ self._dial_options.disable_webrtc = True
69
+ self._lock = Lock()
70
+ self._current_id = ""
71
+ self._heartbeat_interval = None
72
+ self._supported = _SupportedState.UNKNOWN
73
+ self._thread = None
74
+
75
+ listen(self.channel, SendRequest, self._send_request)
76
+ listen(self.channel, RecvTrailingMetadata, self._recv_trailers)
77
+
78
+ def reset(self):
79
+ with self._lock:
80
+ self._reset()
81
+
82
+ def _reset(self):
83
+ LOGGER.debug("resetting session")
84
+ self._supported = _SupportedState.UNKNOWN
85
+ self._current_id = ""
86
+ self._heartbeat_interval = None
87
+ if self._thread is not None:
88
+ try:
89
+ self._thread.join(timeout=1)
90
+ except RuntimeError:
91
+ LOGGER.debug("failed to join session heartbeat thread")
92
+ self._thread = None
93
+
94
+ async def _send_request(self, event: SendRequest):
95
+ if self._disabled:
96
+ return
97
+
98
+ if not self._is_safety_heartbeat_monitored(event.method_name):
99
+ return
100
+
101
+ event.metadata.update(await self.metadata)
102
+
103
+ async def _recv_trailers(self, event: RecvTrailingMetadata):
104
+ if event.status == Status.INVALID_ARGUMENT and event.status_message == "SESSION_EXPIRED":
105
+ LOGGER.debug("Session expired")
106
+ self.reset()
107
+
108
+ @property
109
+ async def metadata(self) -> _MetadataLike:
110
+ with self._lock:
111
+ if self._disabled or self._supported != _SupportedState.UNKNOWN:
112
+ return self._metadata
113
+
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:
120
+ self._reset()
121
+ self._supported = _SupportedState.FALSE
122
+ return self._metadata
123
+ else:
124
+ raise
125
+
126
+ if response is None:
127
+ raise GRPCError(status=Status.INTERNAL, message="Expected response to start session")
128
+
129
+ if response.heartbeat_window is None:
130
+ raise GRPCError(status=Status.INTERNAL, message="Expected heartbeat window in response to start session")
131
+
132
+ with self._lock:
133
+ self._supported = _SupportedState.TRUE
134
+ self._heartbeat_interval = response.heartbeat_window.ToTimedelta()
135
+ self._current_id = response.id
136
+
137
+ # tick once to ensure heartbeats are supported
138
+ await self._heartbeat_tick(self.client)
139
+
140
+ with self._lock:
141
+ if self._thread is not None:
142
+ self._reset()
143
+ if self._supported == _SupportedState.TRUE:
144
+ # We send heartbeats faster than the interval window to
145
+ # ensure that we don't fall outside of it and expire the session.
146
+ wait = self._heartbeat_interval.total_seconds() / 5
147
+
148
+ self._thread = Thread(
149
+ name="heartbeat-thread",
150
+ target=asyncio.run,
151
+ args=(self._heartbeat_process(wait),),
152
+ daemon=True,
153
+ )
154
+ self._thread.start()
155
+
156
+ return self._metadata
157
+
158
+ 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)
164
+
165
+ try:
166
+ await client.SendSessionHeartbeat(request)
167
+ except (GRPCError, StreamTerminatedError):
168
+ LOGGER.debug("Heartbeat terminated", exc_info=True)
169
+ self.reset()
170
+ else:
171
+ LOGGER.debug("Sent heartbeat successfully")
172
+
173
+ def _get_local_addr(self) -> str:
174
+ if sys.platform != "win32" and sys.platform != "cygwin":
175
+ # if we're not on windows, we want the direct dial address
176
+ return self._address
177
+
178
+ # return `robot_address` if it exists, otherwise fallback
179
+ # when using TCP (i.e., on Windows), we need to create a connection to the actual
180
+ # robot address for a sessions client to maintain connectivity successfully
181
+ return self._robot_address if self._robot_address is not None else self._address
182
+
183
+ async def _heartbeat_process(self, wait: float):
184
+ addr = self._get_local_addr()
185
+ channel = await dial(address=addr, options=self._dial_options)
186
+ client = RobotServiceStub(channel.channel)
187
+ while True:
188
+ with self._lock:
189
+ if self._supported != _SupportedState.TRUE:
190
+ return
191
+ await self._heartbeat_tick(client)
192
+ await asyncio.sleep(wait)
193
+
194
+ @property
195
+ def _metadata(self) -> _MetadataLike:
196
+ if self._supported == _SupportedState.TRUE and self._current_id != "":
197
+ return {SESSION_METADATA_KEY: self._current_id}
198
+
199
+ return {}
200
+
201
+ def _is_safety_heartbeat_monitored(self, method: str) -> bool:
202
+ if method in self._HEARTBEAT_MONITORED_METHODS:
203
+ return self._HEARTBEAT_MONITORED_METHODS[method]
204
+
205
+ parts = method.split("/")
206
+ if len(parts) != 3:
207
+ self._HEARTBEAT_MONITORED_METHODS[method] = False
208
+ return False
209
+ service_path = parts[1]
210
+ method_name = parts[2]
211
+
212
+ parts = service_path.split(".")
213
+ if len(parts) < 5:
214
+ self._HEARTBEAT_MONITORED_METHODS[method] = False
215
+ return False
216
+ if parts[0] != "viam":
217
+ self._HEARTBEAT_MONITORED_METHODS[method] = False
218
+ return False
219
+ resource_type = parts[1]
220
+ resource_subtype = parts[2]
221
+ version = parts[3]
222
+ service_name = parts[4]
223
+ try:
224
+ module = importlib.import_module(f"viam.gen.{resource_type}.{resource_subtype}.{version}")
225
+ submods = pkgutil.iter_modules(module.__path__)
226
+ for mod in submods:
227
+ if "_pb2" in mod.name:
228
+ submod = getattr(module, mod.name)
229
+ DESCRIPTOR = getattr(submod, "DESCRIPTOR")
230
+ for service in DESCRIPTOR.services_by_name.values():
231
+ if service.name == service_name:
232
+ for method_actual in service.methods:
233
+ if method_actual.name == method_name:
234
+ options = method_actual.GetOptions()
235
+ if options.HasExtension(safety_heartbeat_monitored):
236
+ is_monitored = options.Extensions[safety_heartbeat_monitored]
237
+ self._HEARTBEAT_MONITORED_METHODS[method] = is_monitored
238
+ return is_monitored
239
+ self._HEARTBEAT_MONITORED_METHODS[method] = False
240
+ return False
241
+ self._HEARTBEAT_MONITORED_METHODS[method] = False
242
+ return False
243
+ except Exception:
244
+ self._HEARTBEAT_MONITORED_METHODS[method] = False
245
+ return False
viam/streams.py ADDED
@@ -0,0 +1,44 @@
1
+ import sys
2
+
3
+ if sys.version_info >= (3, 9):
4
+ from collections.abc import AsyncIterator
5
+ else:
6
+ from typing import AsyncIterator
7
+
8
+ from typing import Protocol, TypeVar
9
+
10
+ StreamType = TypeVar("StreamType", covariant=True)
11
+
12
+
13
+ class Stream(Protocol[StreamType]):
14
+ async def next(self) -> StreamType: ...
15
+
16
+ def __aiter__(self) -> AsyncIterator:
17
+ return self
18
+
19
+ async def __anext__(self) -> StreamType:
20
+ return await self.next()
21
+
22
+
23
+ class StreamReader(Protocol[StreamType]):
24
+ async def read(self) -> StreamType: ...
25
+
26
+
27
+ class StreamSource(Protocol[StreamType]):
28
+ async def stream(self) -> Stream[StreamType]: ...
29
+
30
+
31
+ class StreamWithIterator(Stream[StreamType]):
32
+ _stream: AsyncIterator[StreamType]
33
+
34
+ def __init__(self, stream: AsyncIterator[StreamType]):
35
+ self._stream = stream
36
+
37
+ async def next(self) -> StreamType:
38
+ return await self._stream.__anext__()
39
+
40
+ def __aiter__(self):
41
+ return self._stream
42
+
43
+ async def __anext__(self) -> StreamType:
44
+ return await self._stream.__anext__()
viam/utils.py ADDED
@@ -0,0 +1,365 @@
1
+ import asyncio
2
+ import contextvars
3
+ import functools
4
+ import sys
5
+ import threading
6
+ from datetime import datetime
7
+ from typing import Any, Callable, Dict, List, Mapping, Optional, SupportsBytes, SupportsFloat, Type, TypeVar, Union
8
+
9
+ from google.protobuf.json_format import MessageToDict, ParseDict
10
+ from google.protobuf.message import Message
11
+ from google.protobuf.struct_pb2 import ListValue, Struct, Value
12
+ from google.protobuf.timestamp_pb2 import Timestamp
13
+
14
+ from viam.proto.app.data import CaptureInterval, Filter, TagsFilter
15
+ from viam.proto.common import Geometry, GeoPoint, GetGeometriesRequest, GetGeometriesResponse, Orientation, ResourceName, Vector3
16
+ from viam.resource.base import ResourceBase
17
+ from viam.resource.registry import Registry
18
+ from viam.resource.rpc_client_base import ResourceRPCClientBase
19
+ from viam.resource.types import API, SupportsGetGeometries
20
+
21
+ if sys.version_info >= (3, 9):
22
+ from collections.abc import Callable
23
+ else:
24
+ from typing import Callable
25
+
26
+ if sys.version_info >= (3, 10):
27
+ from typing import ParamSpec
28
+ else:
29
+ from typing_extensions import ParamSpec
30
+
31
+
32
+ ValueTypes = Union[bool, SupportsBytes, SupportsFloat, List, Mapping, str, None]
33
+ """Types that can be encoded into a protobuf `Value`"""
34
+
35
+ SensorReading = Union[ValueTypes, Vector3, GeoPoint, Orientation]
36
+ """Types that can be returned from a sensor"""
37
+
38
+
39
+ def primitive_to_value(v: ValueTypes) -> Value:
40
+ """
41
+ Create a new google.protobuf.struct_pb2.Value
42
+ Supports primitive types of
43
+ - None
44
+ - Number
45
+ - Bool
46
+ - String
47
+ - Dict
48
+ - List
49
+ - Bytes
50
+
51
+ Args:
52
+ v (ValueTypes): object to convert to a Value
53
+
54
+ Raises:
55
+ TypeError: If the object cannot be converted
56
+
57
+ Returns:
58
+ Value: a protobuf Value instance of the object
59
+ """
60
+ if v is None:
61
+ return Value(null_value=v)
62
+ if isinstance(v, bool):
63
+ return Value(bool_value=v)
64
+ if isinstance(v, SupportsFloat):
65
+ return Value(number_value=float(v))
66
+ if isinstance(v, str):
67
+ return Value(string_value=v)
68
+ if isinstance(v, Dict):
69
+ sv: Dict[str, Value] = {}
70
+ for key, value in v.items():
71
+ if not isinstance(key, str):
72
+ raise TypeError(f"Invalid UTF-8 in string: {key}")
73
+ sv[key] = primitive_to_value(value)
74
+ struct = Struct(fields=sv)
75
+ return Value(struct_value=struct)
76
+ if isinstance(v, List):
77
+ lv = []
78
+ for vv in v:
79
+ lv.append(primitive_to_value(vv))
80
+ list_value = ListValue(values=lv)
81
+ return Value(list_value=list_value)
82
+ if isinstance(v, (bytes, bytearray)):
83
+ return Value(string_value=v.decode())
84
+ raise TypeError(f"Invalid type {type(v)}")
85
+
86
+
87
+ def value_to_primitive(value: Value) -> ValueTypes:
88
+ if value.HasField("list_value"):
89
+ return [value_to_primitive(v) for v in value.list_value.values]
90
+ if value.HasField("struct_value"):
91
+ return {k: value_to_primitive(v) for (k, v) in value.struct_value.fields.items()}
92
+ if value.HasField("string_value"):
93
+ return value.string_value
94
+ if value.HasField("number_value"):
95
+ return value.number_value
96
+ if value.HasField("bool_value"):
97
+ return value.bool_value
98
+ if value.HasField("null_value"):
99
+ return value.null_value
100
+ return None
101
+
102
+
103
+ def resource_names_for_resource(resource: ResourceBase) -> List[ResourceName]:
104
+ rns: List[ResourceName] = []
105
+
106
+ for klass in resource.__class__.mro():
107
+ for registration in Registry.REGISTERED_APIS().values():
108
+ if klass is registration.resource_type:
109
+ api: API = registration.resource_type.API
110
+ rns.append(ResourceName(namespace=api.namespace, type=api.resource_type, subtype=api.resource_subtype, name=resource.name))
111
+ return rns
112
+
113
+
114
+ def message_to_struct(message: Message) -> Struct:
115
+ struct = Struct()
116
+ struct.update(
117
+ MessageToDict(
118
+ message,
119
+ True,
120
+ True,
121
+ ),
122
+ )
123
+ return struct
124
+
125
+
126
+ _T = TypeVar("_T", bound=Message)
127
+
128
+
129
+ def struct_to_message(struct: Struct, message_type: Type[_T]) -> _T:
130
+ dct = struct_to_dict(struct)
131
+ return ParseDict(dct, message_type())
132
+
133
+
134
+ def dict_to_struct(obj: Optional[Mapping[str, ValueTypes]]) -> Struct:
135
+ def _convert(v: ValueTypes) -> Any:
136
+ if isinstance(v, bool):
137
+ return v
138
+ if isinstance(v, SupportsFloat):
139
+ return float(v)
140
+ if isinstance(v, SupportsBytes):
141
+ return bytes(v)
142
+ if isinstance(v, List):
143
+ return [_convert(vv) for vv in v]
144
+ if isinstance(v, Mapping):
145
+ return {k: _convert(vv) for (k, vv) in v.items()}
146
+ return v
147
+
148
+ if obj is None:
149
+ obj = {}
150
+ struct = Struct()
151
+ struct.update({k: _convert(v) for (k, v) in obj.items()})
152
+ return struct
153
+
154
+
155
+ def struct_to_dict(struct: Struct) -> Dict[str, ValueTypes]:
156
+ return {key: value_to_primitive(value) for (key, value) in struct.fields.items()}
157
+
158
+
159
+ def datetime_to_timestamp(dt: Optional[datetime]) -> Optional[Timestamp]:
160
+ if dt is None:
161
+ return None
162
+ timestamp = Timestamp()
163
+ timestamp.FromDatetime(dt)
164
+ return timestamp
165
+
166
+
167
+ async def get_geometries(
168
+ client: SupportsGetGeometries,
169
+ name: str,
170
+ extra: Optional[Dict[str, Any]] = None,
171
+ timeout: Optional[float] = None,
172
+ metadata: ResourceRPCClientBase.Metadata = ResourceRPCClientBase.Metadata(),
173
+ ) -> List[Geometry]:
174
+ md = metadata.proto
175
+ request = GetGeometriesRequest(name=name, extra=dict_to_struct(extra))
176
+ response: GetGeometriesResponse = await client.GetGeometries(request, timeout=timeout, metadata=md)
177
+ return [geometry for geometry in response.geometries]
178
+
179
+
180
+ def sensor_readings_native_to_value(readings: Mapping[str, Any]) -> Mapping[str, Value]:
181
+ prim_readings = dict(readings)
182
+ for key, reading in readings.items():
183
+ if isinstance(reading, Vector3):
184
+ prim_readings[key] = {"x": reading.x, "y": reading.y, "z": reading.z, "_type": "vector3"}
185
+ elif isinstance(reading, GeoPoint):
186
+ prim_readings[key] = {"lat": reading.latitude, "lng": reading.longitude, "_type": "geopoint"}
187
+ elif isinstance(reading, Orientation):
188
+ prim_readings[key] = {
189
+ "ox": reading.o_x,
190
+ "oy": reading.o_y,
191
+ "oz": reading.o_z,
192
+ "theta": reading.theta,
193
+ "_type": "orientation_vector_degrees",
194
+ }
195
+ return {key: primitive_to_value(value) for (key, value) in prim_readings.items()}
196
+
197
+
198
+ def sensor_readings_value_to_native(readings: Mapping[str, Value]) -> Mapping[str, SensorReading]:
199
+ prim_readings: Dict[str, Any] = {key: value_to_primitive(value) for (key, value) in readings.items()}
200
+ for key, reading in prim_readings.items():
201
+ if isinstance(reading, Mapping):
202
+ kind = reading.get("_type", "")
203
+ if kind == "angular_velocity":
204
+ prim_readings[key] = Vector3(x=reading["x"], y=reading["y"], z=reading["z"])
205
+ elif kind == "vector3":
206
+ prim_readings[key] = Vector3(x=reading["x"], y=reading["y"], z=reading["z"])
207
+ elif kind == "geopoint":
208
+ prim_readings[key] = GeoPoint(latitude=reading["lat"], longitude=reading["lng"])
209
+ elif kind == "orientation_vector_degrees":
210
+ prim_readings[key] = Orientation(o_x=reading["ox"], o_y=reading["oy"], o_z=reading["oz"], theta=reading["theta"])
211
+ return prim_readings
212
+
213
+
214
+ class PointerCounter:
215
+ def __init__(self) -> None:
216
+ self._event = asyncio.Event()
217
+ self._lock = threading.Lock()
218
+ self._count = 0
219
+ self._event.set()
220
+
221
+ def increment(self) -> int:
222
+ self._lock.acquire()
223
+ self._count += 1
224
+ self._event.clear()
225
+ self._lock.release()
226
+ return self._count
227
+
228
+ def decrement(self) -> int:
229
+ self._lock.acquire()
230
+ assert self._count > 0, "Pointer count cannot go below zero"
231
+ self._count -= 1
232
+ if self._count == 0:
233
+ self._event.set()
234
+ self._lock.release()
235
+ return self._count
236
+
237
+ async def wait(self) -> None:
238
+ await self._event.wait()
239
+
240
+ @property
241
+ def count(self) -> int:
242
+ with self._lock:
243
+ return self._count
244
+
245
+
246
+ _P = ParamSpec("_P")
247
+ _R = TypeVar("_R")
248
+
249
+
250
+ async def to_thread(func: Callable[_P, _R], *args: _P.args, **kwargs: _P.kwargs) -> _R:
251
+ """Asynchronously run a function in a separate thread.
252
+
253
+ This is a copy of the function defined in the python source,
254
+ which is only available in python >= 3.9.
255
+
256
+ See: https://github.com/python/cpython/blob/main/Lib/asyncio/threads.py
257
+ """
258
+ if sys.version_info >= (3, 9):
259
+ return await asyncio.to_thread(func, *args, **kwargs)
260
+ loop = asyncio.events.get_running_loop()
261
+ ctx = contextvars.copy_context()
262
+ func_call = functools.partial(ctx.run, func, *args, **kwargs)
263
+ return await loop.run_in_executor(None, func_call) # type: ignore
264
+
265
+
266
+ def from_dm_from_extra(extra: Optional[Dict[str, Any]]) -> bool:
267
+ """Used in modular filter components to get the 'fromDataManagement' value from an extra map."""
268
+ if extra is None:
269
+ return False
270
+
271
+ return bool(extra.get("fromDataManagement", False))
272
+
273
+
274
+ def create_filter(
275
+ component_name: Optional[str] = None,
276
+ component_type: Optional[str] = None,
277
+ method: Optional[str] = None,
278
+ robot_name: Optional[str] = None,
279
+ robot_id: Optional[str] = None,
280
+ part_name: Optional[str] = None,
281
+ part_id: Optional[str] = None,
282
+ location_ids: Optional[List[str]] = None,
283
+ organization_ids: Optional[List[str]] = None,
284
+ mime_type: Optional[List[str]] = None,
285
+ start_time: Optional[datetime] = None,
286
+ end_time: Optional[datetime] = None,
287
+ tags: Optional[List[str]] = None,
288
+ bbox_labels: Optional[List[str]] = None,
289
+ dataset_id: Optional[str] = None,
290
+ ) -> Filter:
291
+ """Create a `Filter`.
292
+
293
+ Args:
294
+ component_name (Optional[str]): Optional name of the component that captured the data being filtered (for example, "left_motor").
295
+ component_type (Optional[str]): Optional type of the componenet that captured the data being filtered (for example, "motor").
296
+ method (Optional[str]): Optional name of the method used to capture the data being filtered (for example, "IsPowered").
297
+ robot_name (Optional[str]): Optional name of the robot associated with the data being filtered (for example, "viam_rover_1").
298
+ robot_id (Optional[str]): Optional ID of the robot associated with the data being filtered.
299
+ part_name (Optional[str]): Optional name of the system part associated with the data being filtered (for example,
300
+ "viam_rover_1-main").
301
+ part_id (Optional[str]): Optional ID of the system part associated with the data being filtered.
302
+ location_ids (Optional[List[str]]): Optional list of location IDs associated with the data being filtered.
303
+ organization_ids (Optional[List[str]]): Optional list of organization IDs associated with the data being filtered.
304
+ mime_type (Optional[List[str]]): Optional mime type of data being filtered (for example, "image/png").
305
+ start_time (Optional[datetime.datetime]): Optional start time of an interval to filter data by.
306
+ end_time (Optional[datetime.datetime]): Optional end time of an interval to filter data by.
307
+ tags (Optional[List[str]]): Optional list of tags attached to the data being filtered (for example, ["test"]).
308
+ bbox_labels (Optional[List[str]]): Optional list of bounding box labels attached to the data being filtered (for example, ["square",
309
+ "circle"]).
310
+ dataset_id (Optional[str]): Optional ID of dataset associated with data being filtered
311
+
312
+ Returns:
313
+ viam.proto.app.data.Filter: The `Filter` object.
314
+ """
315
+ return Filter(
316
+ component_name=component_name if component_name else "",
317
+ component_type=component_type if component_type else "",
318
+ method=method if method else "",
319
+ robot_name=robot_name if robot_name else "",
320
+ robot_id=robot_id if robot_id else "",
321
+ part_name=part_name if part_name else "",
322
+ part_id=part_id if part_id else "",
323
+ location_ids=location_ids,
324
+ organization_ids=organization_ids,
325
+ mime_type=mime_type,
326
+ interval=(
327
+ CaptureInterval(
328
+ start=datetime_to_timestamp(start_time),
329
+ end=datetime_to_timestamp(end_time),
330
+ )
331
+ )
332
+ if start_time or end_time
333
+ else None,
334
+ tags_filter=TagsFilter(tags=tags),
335
+ bbox_labels=bbox_labels,
336
+ dataset_id=dataset_id if dataset_id else "",
337
+ )
338
+
339
+
340
+ def _alias_param(param_name: str, param_alias: str) -> Callable:
341
+ """
342
+ Decorator for aliasing a param in a function. Intended for providing backwards compatibility on params with name changes.
343
+
344
+ Args:
345
+ param_name: name of param in function to alias
346
+ param_alias: alias that can be used for this param
347
+ Returns:
348
+ The input function, plus param alias.
349
+ """
350
+
351
+ def decorator(func: Callable):
352
+ @functools.wraps(func)
353
+ def wrapper(*args, **kwargs):
354
+ alias_param_value = kwargs.get(param_alias)
355
+ if alias_param_value:
356
+ # Only use alias value if param is not given.
357
+ if not kwargs.get(param_name):
358
+ kwargs[param_name] = alias_param_value
359
+ del kwargs[param_alias]
360
+ result = func(*args, **kwargs)
361
+ return result
362
+
363
+ return wrapper
364
+
365
+ return decorator
@@ -0,0 +1,4 @@
1
+ __version__ = "0.45.2"
2
+
3
+ API_VERSION = "v0.1.432"
4
+ SDK_VERSION = __version__