viam-sdk 0.3.0__py3-none-linux_armv6l.whl → 0.66.0__py3-none-linux_armv6l.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of viam-sdk might be problematic. Click here for more details.
- viam/__init__.py +29 -2
- viam/app/_logs.py +34 -0
- viam/app/app_client.py +2696 -0
- viam/app/billing_client.py +185 -0
- viam/app/data_client.py +2231 -0
- viam/app/ml_training_client.py +249 -0
- viam/app/provisioning_client.py +93 -0
- viam/app/viam_client.py +275 -0
- viam/components/arm/__init__.py +3 -26
- viam/components/arm/arm.py +123 -8
- viam/components/arm/client.py +37 -24
- viam/components/arm/service.py +35 -32
- viam/components/audio_in/__init__.py +24 -0
- viam/components/audio_in/audio_in.py +74 -0
- viam/components/audio_in/client.py +76 -0
- viam/components/audio_in/service.py +83 -0
- viam/components/audio_out/__init__.py +21 -0
- viam/components/audio_out/audio_out.py +72 -0
- viam/components/audio_out/client.py +67 -0
- viam/components/audio_out/service.py +63 -0
- viam/components/base/__init__.py +6 -11
- viam/components/base/base.py +134 -8
- viam/components/base/client.py +51 -23
- viam/components/base/service.py +33 -30
- viam/components/board/__init__.py +3 -12
- viam/components/board/board.py +247 -91
- viam/components/board/client.py +149 -83
- viam/components/board/service.py +63 -33
- viam/components/button/__init__.py +10 -0
- viam/components/button/button.py +41 -0
- viam/components/button/client.py +52 -0
- viam/components/button/service.py +46 -0
- viam/components/camera/__init__.py +3 -3
- viam/components/camera/camera.py +62 -27
- viam/components/camera/client.py +59 -27
- viam/components/camera/service.py +42 -65
- viam/components/component_base.py +28 -5
- viam/components/encoder/__init__.py +1 -1
- viam/components/encoder/client.py +25 -14
- viam/components/encoder/encoder.py +48 -10
- viam/components/encoder/service.py +14 -18
- viam/components/gantry/__init__.py +1 -13
- viam/components/gantry/client.py +80 -25
- viam/components/gantry/gantry.py +123 -9
- viam/components/gantry/service.py +51 -29
- viam/components/generic/__init__.py +1 -1
- viam/components/generic/client.py +21 -8
- viam/components/generic/generic.py +10 -2
- viam/components/generic/service.py +12 -7
- viam/components/gripper/__init__.py +3 -13
- viam/components/gripper/client.py +69 -21
- viam/components/gripper/gripper.py +123 -3
- viam/components/gripper/service.py +44 -22
- viam/components/input/__init__.py +1 -14
- viam/components/input/client.py +55 -23
- viam/components/input/input.py +106 -3
- viam/components/input/service.py +16 -21
- viam/components/motor/__init__.py +1 -21
- viam/components/motor/client.py +56 -33
- viam/components/motor/motor.py +127 -4
- viam/components/motor/service.py +33 -44
- viam/components/movement_sensor/__init__.py +1 -1
- viam/components/movement_sensor/client.py +102 -45
- viam/components/movement_sensor/movement_sensor.py +130 -61
- viam/components/movement_sensor/service.py +38 -41
- viam/components/pose_tracker/__init__.py +1 -1
- viam/components/pose_tracker/client.py +18 -7
- viam/components/pose_tracker/pose_tracker.py +4 -2
- viam/components/pose_tracker/service.py +12 -10
- viam/components/power_sensor/__init__.py +17 -0
- viam/components/power_sensor/client.py +86 -0
- viam/components/power_sensor/power_sensor.py +104 -0
- viam/components/power_sensor/service.py +72 -0
- viam/components/sensor/__init__.py +2 -1
- viam/components/sensor/client.py +26 -10
- viam/components/sensor/sensor.py +22 -4
- viam/components/sensor/service.py +20 -11
- viam/components/servo/__init__.py +1 -13
- viam/components/servo/client.py +47 -21
- viam/components/servo/service.py +15 -22
- viam/components/servo/servo.py +61 -2
- viam/components/switch/__init__.py +10 -0
- viam/components/switch/client.py +83 -0
- viam/components/switch/service.py +72 -0
- viam/components/switch/switch.py +98 -0
- viam/errors.py +10 -0
- viam/gen/app/agent/v1/agent_grpc.py +29 -0
- viam/gen/app/agent/v1/agent_pb2.py +47 -0
- viam/gen/app/agent/v1/agent_pb2.pyi +280 -0
- viam/gen/app/cloudslam/v1/__init__.py +0 -0
- viam/gen/app/cloudslam/v1/cloud_slam_grpc.py +70 -0
- viam/gen/app/cloudslam/v1/cloud_slam_pb2.py +54 -0
- viam/gen/app/cloudslam/v1/cloud_slam_pb2.pyi +384 -0
- viam/gen/app/data/v1/data_grpc.py +197 -8
- viam/gen/app/data/v1/data_pb2.py +238 -99
- viam/gen/app/data/v1/data_pb2.pyi +1222 -259
- viam/gen/app/datapipelines/__init__.py +0 -0
- viam/gen/app/datapipelines/v1/__init__.py +0 -0
- viam/gen/app/datapipelines/v1/data_pipelines_grpc.py +84 -0
- viam/gen/app/datapipelines/v1/data_pipelines_pb2.py +57 -0
- viam/gen/app/datapipelines/v1/data_pipelines_pb2.pyi +387 -0
- viam/gen/app/dataset/__init__.py +0 -0
- viam/gen/app/dataset/v1/__init__.py +0 -0
- viam/gen/app/dataset/v1/dataset_grpc.py +68 -0
- viam/gen/app/dataset/v1/dataset_pb2.py +44 -0
- viam/gen/app/dataset/v1/dataset_pb2.pyi +214 -0
- viam/gen/app/datasync/v1/data_sync_grpc.py +21 -4
- viam/gen/app/datasync/v1/data_sync_pb2.py +62 -128
- viam/gen/app/datasync/v1/data_sync_pb2.pyi +156 -199
- viam/gen/app/mlinference/__init__.py +0 -0
- viam/gen/app/mlinference/v1/__init__.py +0 -0
- viam/gen/app/mlinference/v1/ml_inference_grpc.py +28 -0
- viam/gen/app/mlinference/v1/ml_inference_pb2.py +23 -0
- viam/gen/app/mlinference/v1/ml_inference_pb2.pyi +63 -0
- viam/gen/app/mltraining/v1/ml_training_grpc.py +51 -3
- viam/gen/app/mltraining/v1/ml_training_pb2.py +135 -58
- viam/gen/app/mltraining/v1/ml_training_pb2.pyi +328 -39
- viam/gen/app/packages/v1/packages_grpc.py +15 -1
- viam/gen/app/packages/v1/packages_pb2.py +44 -64
- viam/gen/app/packages/v1/packages_pb2.pyi +75 -85
- viam/gen/app/v1/app_grpc.py +644 -3
- viam/gen/app/v1/app_pb2.py +695 -295
- viam/gen/app/v1/app_pb2.pyi +4488 -635
- viam/gen/app/v1/billing_grpc.py +53 -11
- viam/gen/app/v1/billing_pb2.py +94 -39
- viam/gen/app/v1/billing_pb2.pyi +391 -191
- viam/gen/app/v1/end_user_grpc.py +59 -0
- viam/gen/app/v1/end_user_pb2.py +55 -0
- viam/gen/app/v1/end_user_pb2.pyi +181 -0
- viam/gen/app/v1/robot_grpc.py +16 -1
- viam/gen/app/v1/robot_pb2.py +122 -94
- viam/gen/app/v1/robot_pb2.pyi +463 -123
- viam/gen/common/v1/common_pb2.py +87 -58
- viam/gen/common/v1/common_pb2.pyi +456 -149
- viam/gen/component/arm/v1/arm_grpc.py +58 -2
- viam/gen/component/arm/v1/arm_pb2.py +68 -51
- viam/gen/component/arm/v1/arm_pb2.pyi +108 -42
- viam/gen/component/audioin/__init__.py +0 -0
- viam/gen/component/audioin/v1/__init__.py +0 -0
- viam/gen/component/audioin/v1/audioin_grpc.py +54 -0
- viam/gen/component/audioin/v1/audioin_pb2.py +34 -0
- viam/gen/component/audioin/v1/audioin_pb2.pyi +94 -0
- viam/gen/component/audioinput/v1/audioinput_grpc.py +25 -2
- viam/gen/component/audioinput/v1/audioinput_pb2.py +36 -31
- viam/gen/component/audioinput/v1/audioinput_pb2.pyi +22 -22
- viam/gen/component/audioout/__init__.py +0 -0
- viam/gen/component/audioout/v1/__init__.py +0 -0
- viam/gen/component/audioout/v1/audioout_grpc.py +54 -0
- viam/gen/component/audioout/v1/audioout_pb2.py +32 -0
- viam/gen/component/audioout/v1/audioout_pb2.pyi +47 -0
- viam/gen/component/base/v1/base_grpc.py +42 -2
- viam/gen/component/base/v1/base_pb2.py +58 -47
- viam/gen/component/base/v1/base_pb2.pyi +65 -30
- viam/gen/component/board/v1/board_grpc.py +59 -7
- viam/gen/component/board/v1/board_pb2.py +94 -73
- viam/gen/component/board/v1/board_pb2.pyi +165 -68
- viam/gen/component/button/__init__.py +0 -0
- viam/gen/component/button/v1/__init__.py +0 -0
- viam/gen/component/button/v1/button_grpc.py +38 -0
- viam/gen/component/button/v1/button_pb2.py +28 -0
- viam/gen/component/button/v1/button_pb2.pyi +39 -0
- viam/gen/component/camera/v1/camera_grpc.py +38 -2
- viam/gen/component/camera/v1/camera_pb2.py +60 -43
- viam/gen/component/camera/v1/camera_pb2.pyi +191 -37
- viam/gen/component/encoder/v1/encoder_grpc.py +25 -2
- viam/gen/component/encoder/v1/encoder_pb2.py +36 -31
- viam/gen/component/encoder/v1/encoder_pb2.pyi +15 -15
- viam/gen/component/gantry/v1/gantry_grpc.py +47 -2
- viam/gen/component/gantry/v1/gantry_pb2.py +56 -43
- viam/gen/component/gantry/v1/gantry_pb2.pyi +67 -31
- viam/gen/component/generic/v1/generic_grpc.py +16 -2
- viam/gen/component/generic/v1/generic_pb2.py +16 -11
- viam/gen/component/gripper/v1/gripper_grpc.py +44 -2
- viam/gen/component/gripper/v1/gripper_pb2.py +48 -35
- viam/gen/component/gripper/v1/gripper_pb2.pyi +62 -24
- viam/gen/component/inputcontroller/v1/input_controller_grpc.py +28 -2
- viam/gen/component/inputcontroller/v1/input_controller_pb2.py +46 -41
- viam/gen/component/inputcontroller/v1/input_controller_pb2.pyi +32 -36
- viam/gen/component/motor/v1/motor_grpc.py +51 -2
- viam/gen/component/motor/v1/motor_pb2.py +78 -67
- viam/gen/component/motor/v1/motor_pb2.pyi +75 -46
- viam/gen/component/movementsensor/v1/movementsensor_grpc.py +48 -2
- viam/gen/component/movementsensor/v1/movementsensor_pb2.py +70 -63
- viam/gen/component/movementsensor/v1/movementsensor_pb2.pyi +84 -57
- viam/gen/component/posetracker/v1/pose_tracker_grpc.py +19 -2
- viam/gen/component/posetracker/v1/pose_tracker_pb2.py +26 -21
- viam/gen/component/posetracker/v1/pose_tracker_pb2.pyi +9 -13
- viam/gen/component/powersensor/__init__.py +0 -0
- viam/gen/component/powersensor/v1/__init__.py +0 -0
- viam/gen/component/powersensor/v1/powersensor_grpc.py +62 -0
- viam/gen/component/powersensor/v1/powersensor_pb2.py +42 -0
- viam/gen/component/powersensor/v1/powersensor_pb2.pyi +124 -0
- viam/gen/component/sensor/v1/sensor_grpc.py +21 -5
- viam/gen/component/sensor/v1/sensor_pb2.py +18 -22
- viam/gen/component/sensor/v1/sensor_pb2.pyi +1 -69
- viam/gen/component/servo/v1/servo_grpc.py +28 -2
- viam/gen/component/servo/v1/servo_pb2.py +42 -37
- viam/gen/component/servo/v1/servo_pb2.pyi +22 -26
- viam/gen/component/switch/__init__.py +0 -0
- viam/gen/component/switch/v1/__init__.py +0 -0
- viam/gen/component/switch/v1/switch_grpc.py +54 -0
- viam/gen/component/switch/v1/switch_pb2.py +40 -0
- viam/gen/component/switch/v1/switch_pb2.pyi +116 -0
- viam/gen/component/testecho/v1/testecho_grpc.py +15 -0
- viam/gen/component/testecho/v1/testecho_pb2.py +29 -26
- viam/gen/component/testecho/v1/testecho_pb2.pyi +16 -20
- viam/gen/module/v1/module_grpc.py +18 -0
- viam/gen/module/v1/module_pb2.py +36 -33
- viam/gen/module/v1/module_pb2.pyi +39 -34
- viam/gen/opentelemetry/__init__.py +0 -0
- viam/gen/opentelemetry/proto/__init__.py +0 -0
- viam/gen/opentelemetry/proto/common/__init__.py +0 -0
- viam/gen/opentelemetry/proto/common/v1/__init__.py +0 -0
- viam/gen/opentelemetry/proto/common/v1/common_grpc.py +0 -0
- viam/gen/opentelemetry/proto/common/v1/common_pb2.py +27 -0
- viam/gen/opentelemetry/proto/common/v1/common_pb2.pyi +208 -0
- viam/gen/opentelemetry/proto/resource/__init__.py +0 -0
- viam/gen/opentelemetry/proto/resource/v1/__init__.py +0 -0
- viam/gen/opentelemetry/proto/resource/v1/resource_grpc.py +0 -0
- viam/gen/opentelemetry/proto/resource/v1/resource_pb2.py +18 -0
- viam/gen/opentelemetry/proto/resource/v1/resource_pb2.pyi +59 -0
- viam/gen/opentelemetry/proto/trace/__init__.py +0 -0
- viam/gen/opentelemetry/proto/trace/v1/__init__.py +0 -0
- viam/gen/opentelemetry/proto/trace/v1/trace_grpc.py +0 -0
- viam/gen/opentelemetry/proto/trace/v1/trace_pb2.py +37 -0
- viam/gen/opentelemetry/proto/trace/v1/trace_pb2.pyi +402 -0
- viam/gen/proto/rpc/examples/echo/v1/echo_grpc.py +12 -0
- viam/gen/proto/rpc/examples/echo/v1/echo_pb2.py +25 -22
- viam/gen/proto/rpc/examples/echo/v1/echo_pb2.pyi +13 -17
- viam/gen/proto/rpc/examples/echoresource/v1/echoresource_grpc.py +12 -0
- viam/gen/proto/rpc/examples/echoresource/v1/echoresource_pb2.py +23 -20
- viam/gen/proto/rpc/examples/echoresource/v1/echoresource_pb2.pyi +13 -17
- viam/gen/proto/rpc/v1/auth_grpc.py +11 -0
- viam/gen/proto/rpc/v1/auth_pb2.py +27 -24
- viam/gen/proto/rpc/v1/auth_pb2.pyi +12 -16
- viam/gen/proto/rpc/webrtc/v1/grpc_pb2.py +35 -32
- viam/gen/proto/rpc/webrtc/v1/grpc_pb2.pyi +37 -41
- viam/gen/proto/rpc/webrtc/v1/signaling_grpc.py +15 -0
- viam/gen/proto/rpc/webrtc/v1/signaling_pb2.py +62 -57
- viam/gen/proto/rpc/webrtc/v1/signaling_pb2.pyi +78 -69
- viam/gen/provisioning/__init__.py +0 -0
- viam/gen/provisioning/v1/__init__.py +0 -0
- viam/gen/provisioning/v1/provisioning_grpc.py +59 -0
- viam/gen/provisioning/v1/provisioning_pb2.py +45 -0
- viam/gen/provisioning/v1/provisioning_pb2.pyi +229 -0
- viam/gen/robot/v1/robot_grpc.py +144 -15
- viam/gen/robot/v1/robot_pb2.py +193 -119
- viam/gen/robot/v1/robot_pb2.pyi +565 -137
- viam/gen/service/datamanager/v1/data_manager_grpc.py +20 -2
- viam/gen/service/datamanager/v1/data_manager_pb2.py +27 -17
- viam/gen/service/datamanager/v1/data_manager_pb2.pyi +52 -10
- viam/gen/service/discovery/__init__.py +0 -0
- viam/gen/service/discovery/v1/__init__.py +0 -0
- viam/gen/service/discovery/v1/discovery_grpc.py +39 -0
- viam/gen/service/discovery/v1/discovery_pb2.py +29 -0
- viam/gen/service/discovery/v1/discovery_pb2.pyi +51 -0
- viam/gen/service/generic/__init__.py +0 -0
- viam/gen/service/generic/v1/__init__.py +0 -0
- viam/gen/service/generic/v1/generic_grpc.py +29 -0
- viam/gen/service/generic/v1/generic_pb2.py +21 -0
- viam/gen/service/generic/v1/generic_pb2.pyi +6 -0
- viam/gen/service/mlmodel/v1/mlmodel_grpc.py +9 -0
- viam/gen/service/mlmodel/v1/mlmodel_pb2.py +76 -29
- viam/gen/service/mlmodel/v1/mlmodel_pb2.pyi +307 -28
- viam/gen/service/motion/v1/motion_grpc.py +42 -4
- viam/gen/service/motion/v1/motion_pb2.py +119 -51
- viam/gen/service/motion/v1/motion_pb2.pyi +595 -120
- viam/gen/service/navigation/v1/navigation_grpc.py +49 -1
- viam/gen/service/navigation/v1/navigation_pb2.py +76 -51
- viam/gen/service/navigation/v1/navigation_pb2.pyi +188 -33
- viam/gen/service/sensors/v1/sensors_grpc.py +12 -0
- viam/gen/service/sensors/v1/sensors_pb2.py +60 -29
- viam/gen/service/sensors/v1/sensors_pb2.pyi +18 -21
- viam/gen/service/shell/v1/shell_grpc.py +27 -1
- viam/gen/service/shell/v1/shell_pb2.py +37 -15
- viam/gen/service/shell/v1/shell_pb2.pyi +260 -7
- viam/gen/service/slam/v1/slam_grpc.py +24 -2
- viam/gen/service/slam/v1/slam_pb2.py +44 -30
- viam/gen/service/slam/v1/slam_pb2.pyi +128 -27
- viam/gen/service/video/__init__.py +0 -0
- viam/gen/service/video/v1/__init__.py +0 -0
- viam/gen/service/video/v1/video_grpc.py +39 -0
- viam/gen/service/video/v1/video_pb2.py +29 -0
- viam/gen/service/video/v1/video_pb2.pyi +72 -0
- viam/gen/service/vision/v1/vision_grpc.py +39 -1
- viam/gen/service/vision/v1/vision_pb2.py +61 -45
- viam/gen/service/vision/v1/vision_pb2.pyi +180 -41
- viam/gen/service/worldstatestore/__init__.py +0 -0
- viam/gen/service/worldstatestore/v1/__init__.py +0 -0
- viam/gen/service/worldstatestore/v1/world_state_store_grpc.py +55 -0
- viam/gen/service/worldstatestore/v1/world_state_store_pb2.py +39 -0
- viam/gen/service/worldstatestore/v1/world_state_store_pb2.pyi +171 -0
- viam/gen/stream/__init__.py +0 -0
- viam/gen/stream/v1/__init__.py +0 -0
- viam/gen/stream/v1/stream_grpc.py +59 -0
- viam/gen/stream/v1/stream_pb2.py +39 -0
- viam/gen/stream/v1/stream_pb2.pyi +161 -0
- viam/gen/tagger/v1/tagger_pb2.py +9 -8
- viam/logging.py +160 -17
- viam/media/__init__.py +0 -9
- viam/media/audio.py +22 -10
- viam/media/utils/__init__.py +0 -0
- viam/media/utils/pil/__init__.py +55 -0
- viam/media/{viam_rgba_plugin.py → utils/pil/viam_rgba_plugin.py} +10 -16
- viam/media/viam_rgba.py +10 -0
- viam/media/video.py +197 -73
- viam/module/module.py +191 -44
- viam/module/resource_data_consumer.py +41 -0
- viam/module/service.py +9 -1
- viam/module/types.py +4 -5
- viam/operations.py +4 -3
- viam/proto/app/__init__.py +361 -5
- viam/proto/app/agent/__init__.py +28 -0
- viam/proto/app/billing.py +51 -27
- viam/proto/app/cloudslam/__init__.py +48 -0
- viam/proto/app/data/__init__.py +103 -17
- viam/proto/app/datapipelines/__init__.py +56 -0
- viam/proto/app/dataset/__init__.py +40 -0
- viam/proto/app/datasync/__init__.py +11 -5
- viam/proto/app/end_user.py +34 -0
- viam/proto/app/mlinference/__init__.py +15 -0
- viam/proto/app/mltraining/__init__.py +25 -1
- viam/proto/app/packages/__init__.py +3 -3
- viam/proto/app/robot.py +19 -1
- viam/proto/common/__init__.py +35 -8
- viam/proto/component/arm/__init__.py +9 -1
- viam/proto/component/audioin/__init__.py +16 -0
- viam/proto/component/audioinput/__init__.py +3 -1
- viam/proto/component/audioout/__init__.py +15 -0
- viam/proto/component/base/__init__.py +7 -1
- viam/proto/component/board/__init__.py +13 -5
- viam/proto/component/button/__init__.py +15 -0
- viam/proto/component/camera/__init__.py +9 -1
- viam/proto/component/encoder/__init__.py +3 -1
- viam/proto/component/gantry/__init__.py +7 -1
- viam/proto/component/generic/__init__.py +3 -1
- viam/proto/component/gripper/__init__.py +7 -1
- viam/proto/component/inputcontroller/__init__.py +7 -1
- viam/proto/component/motor/__init__.py +7 -1
- viam/proto/component/movementsensor/__init__.py +7 -1
- viam/proto/component/posetracker/__init__.py +7 -1
- viam/proto/component/powersensor/__init__.py +30 -0
- viam/proto/component/sensor/__init__.py +3 -4
- viam/proto/component/servo/__init__.py +3 -1
- viam/proto/component/switch/__init__.py +26 -0
- viam/proto/component/testecho/__init__.py +3 -1
- viam/proto/module/__init__.py +3 -1
- viam/proto/opentelemetry/__init__.py +0 -0
- viam/proto/opentelemetry/proto/__init__.py +0 -0
- viam/proto/opentelemetry/proto/common/__init__.py +15 -0
- viam/proto/opentelemetry/proto/resource/__init__.py +10 -0
- viam/proto/opentelemetry/proto/trace/__init__.py +15 -0
- viam/proto/provisioning/__init__.py +42 -0
- viam/proto/robot/__init__.py +57 -9
- viam/proto/rpc/auth.py +11 -1
- viam/proto/rpc/examples/echo/__init__.py +3 -1
- viam/proto/rpc/examples/echoresource/__init__.py +7 -1
- viam/proto/rpc/webrtc/grpc.py +3 -1
- viam/proto/rpc/webrtc/signaling.py +5 -1
- viam/proto/service/datamanager/__init__.py +15 -2
- viam/proto/service/discovery/__init__.py +15 -0
- viam/proto/service/generic/__init__.py +12 -0
- viam/proto/service/mlmodel/__init__.py +27 -1
- viam/proto/service/motion/__init__.py +35 -5
- viam/proto/service/navigation/__init__.py +19 -1
- viam/proto/service/sensors/__init__.py +3 -1
- viam/proto/service/shell/__init__.py +25 -2
- viam/proto/service/slam/__init__.py +13 -1
- viam/proto/service/video/__init__.py +15 -0
- viam/proto/service/vision/__init__.py +11 -1
- viam/proto/service/worldstatestore/__init__.py +32 -0
- viam/proto/stream/__init__.py +36 -0
- viam/py.typed +0 -0
- viam/resource/base.py +45 -8
- viam/resource/easy_resource.py +149 -0
- viam/resource/manager.py +35 -14
- viam/resource/registry.py +40 -52
- viam/resource/rpc_client_base.py +33 -1
- viam/resource/rpc_service_base.py +15 -8
- viam/resource/types.py +39 -26
- viam/robot/client.py +458 -91
- viam/robot/service.py +13 -107
- viam/rpc/dial.py +133 -15
- viam/rpc/libviam_rust_utils.so +0 -0
- viam/rpc/server.py +59 -15
- viam/rpc/types.py +2 -4
- viam/services/discovery/__init__.py +12 -0
- viam/services/discovery/client.py +55 -0
- viam/services/discovery/discovery.py +52 -0
- viam/services/discovery/service.py +43 -0
- viam/services/generic/__init__.py +18 -0
- viam/services/generic/client.py +58 -0
- viam/services/generic/generic.py +58 -0
- viam/services/generic/service.py +29 -0
- viam/services/mlmodel/__init__.py +15 -1
- viam/services/mlmodel/client.py +20 -15
- viam/services/mlmodel/mlmodel.py +44 -7
- viam/services/mlmodel/service.py +9 -13
- viam/services/mlmodel/utils.py +101 -0
- viam/services/motion/__init__.py +15 -3
- viam/services/motion/client.py +109 -150
- viam/services/motion/motion.py +380 -0
- viam/services/motion/service.py +132 -0
- viam/services/navigation/__init__.py +11 -0
- viam/services/navigation/client.py +99 -0
- viam/services/navigation/navigation.py +250 -0
- viam/services/navigation/service.py +137 -0
- viam/services/service_base.py +43 -4
- viam/services/service_client_base.py +4 -4
- viam/services/slam/__init__.py +4 -1
- viam/services/slam/client.py +21 -11
- viam/services/slam/service.py +16 -19
- viam/services/slam/slam.py +66 -5
- viam/services/vision/__init__.py +8 -0
- viam/services/vision/client.py +115 -111
- viam/services/vision/service.py +143 -0
- viam/services/vision/vision.py +317 -0
- viam/services/worldstatestore/__init__.py +18 -0
- viam/services/worldstatestore/client.py +94 -0
- viam/services/worldstatestore/service.py +55 -0
- viam/services/worldstatestore/worldstatestore.py +90 -0
- viam/sessions_client.py +254 -0
- viam/streams.py +44 -0
- viam/utils.py +143 -15
- viam/version_metadata.py +4 -0
- viam_sdk-0.66.0.dist-info/METADATA +157 -0
- viam_sdk-0.66.0.dist-info/RECORD +531 -0
- {viam_sdk-0.3.0.dist-info → viam_sdk-0.66.0.dist-info}/WHEEL +1 -1
- viam/components/audio_input/__init__.py +0 -18
- viam/components/audio_input/audio_input.py +0 -79
- viam/components/audio_input/client.py +0 -60
- viam/components/audio_input/service.py +0 -118
- viam/components/types.py +0 -5
- viam/gen/app/model/v1/model_grpc.py +0 -39
- viam/gen/app/model/v1/model_pb2.py +0 -71
- viam/gen/app/model/v1/model_pb2.pyi +0 -285
- viam/gen/proto/rpc/examples/fileupload/v1/fileupload_grpc.py +0 -21
- viam/gen/proto/rpc/examples/fileupload/v1/fileupload_pb2.py +0 -18
- viam/gen/proto/rpc/examples/fileupload/v1/fileupload_pb2.pyi +0 -49
- viam/media/media.py +0 -53
- viam/proto/app/model/__init__.py +0 -40
- viam/proto/rpc/examples/fileupload/__init__.py +0 -13
- viam/services/sensors/__init__.py +0 -5
- viam/services/sensors/client.py +0 -63
- viam_sdk-0.3.0.dist-info/LICENSE +0 -202
- viam_sdk-0.3.0.dist-info/METADATA +0 -122
- viam_sdk-0.3.0.dist-info/RECORD +0 -372
- /viam/{gen/app/model → app}/__init__.py +0 -0
- /viam/gen/app/{model/v1 → agent}/__init__.py +0 -0
- /viam/gen/{proto/rpc/examples/fileupload → app/agent/v1}/__init__.py +0 -0
- /viam/gen/{proto/rpc/examples/fileupload/v1 → app/cloudslam}/__init__.py +0 -0
- /LICENSE → /viam_sdk-0.66.0.dist-info/licenses/LICENSE +0 -0
viam/sessions_client.py
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import importlib
|
|
3
|
+
import pkgutil
|
|
4
|
+
import sys
|
|
5
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
6
|
+
from contextlib import asynccontextmanager
|
|
7
|
+
from copy import deepcopy
|
|
8
|
+
from datetime import timedelta
|
|
9
|
+
from enum import IntEnum
|
|
10
|
+
from threading import Lock, Thread
|
|
11
|
+
from typing import MutableMapping, Optional
|
|
12
|
+
|
|
13
|
+
from grpclib import Status
|
|
14
|
+
from grpclib.client import Channel
|
|
15
|
+
from grpclib.events import RecvTrailingMetadata, SendRequest, listen
|
|
16
|
+
from grpclib.exceptions import GRPCError, StreamTerminatedError
|
|
17
|
+
from grpclib.metadata import _MetadataLike
|
|
18
|
+
|
|
19
|
+
from viam import logging
|
|
20
|
+
from viam.gen.common.v1.common_pb2 import safety_heartbeat_monitored
|
|
21
|
+
from viam.proto.robot import RobotServiceStub, SendSessionHeartbeatRequest, StartSessionRequest, StartSessionResponse
|
|
22
|
+
from viam.rpc.dial import DialOptions, dial
|
|
23
|
+
|
|
24
|
+
LOGGER = logging.getLogger(__name__)
|
|
25
|
+
SESSION_METADATA_KEY = "viam-sid"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class _SupportedState(IntEnum):
|
|
29
|
+
UNKNOWN = 0
|
|
30
|
+
TRUE = 1
|
|
31
|
+
FALSE = 2
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SessionsClient:
|
|
35
|
+
"""
|
|
36
|
+
A Session allows a client to express that it is actively connected and
|
|
37
|
+
supports stopping actuating components when it's not.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
channel: Channel
|
|
41
|
+
client: RobotServiceStub
|
|
42
|
+
_address: str # direct dial address, when using webRTC this is the local socket rather than a robot address
|
|
43
|
+
_robot_address: Optional[str] # the actual machine address on app.viam.com. important for creating a sessions client on Windows
|
|
44
|
+
_dial_options: DialOptions
|
|
45
|
+
_disabled: bool
|
|
46
|
+
_lock: Lock
|
|
47
|
+
_current_id: str
|
|
48
|
+
_heartbeat_interval: Optional[timedelta]
|
|
49
|
+
_supported: _SupportedState
|
|
50
|
+
_thread: Optional[Thread]
|
|
51
|
+
_pool: ThreadPoolExecutor
|
|
52
|
+
|
|
53
|
+
_HEARTBEAT_MONITORED_METHODS: MutableMapping[str, bool] = {}
|
|
54
|
+
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
channel: Channel,
|
|
58
|
+
direct_dial_address: str,
|
|
59
|
+
dial_options: Optional[DialOptions],
|
|
60
|
+
*,
|
|
61
|
+
disabled: bool = False,
|
|
62
|
+
robot_addr: Optional[str] = None,
|
|
63
|
+
):
|
|
64
|
+
self.channel = channel
|
|
65
|
+
self.client = RobotServiceStub(channel)
|
|
66
|
+
self._address = direct_dial_address
|
|
67
|
+
self._robot_address = robot_addr
|
|
68
|
+
self._disabled = disabled
|
|
69
|
+
self._dial_options = deepcopy(dial_options) if dial_options is not None else DialOptions()
|
|
70
|
+
if sys.platform != "win32" and sys.platform != "cygwin":
|
|
71
|
+
self._dial_options.disable_webrtc = True
|
|
72
|
+
self._lock = Lock()
|
|
73
|
+
self._current_id = ""
|
|
74
|
+
self._heartbeat_interval = None
|
|
75
|
+
self._supported = _SupportedState.UNKNOWN
|
|
76
|
+
self._thread = None
|
|
77
|
+
self._pool = ThreadPoolExecutor()
|
|
78
|
+
|
|
79
|
+
listen(self.channel, SendRequest, self._send_request)
|
|
80
|
+
listen(self.channel, RecvTrailingMetadata, self._recv_trailers)
|
|
81
|
+
|
|
82
|
+
def reset(self):
|
|
83
|
+
with self._lock:
|
|
84
|
+
self._reset()
|
|
85
|
+
|
|
86
|
+
def _reset(self):
|
|
87
|
+
LOGGER.debug("resetting session")
|
|
88
|
+
self._supported = _SupportedState.UNKNOWN
|
|
89
|
+
self._current_id = ""
|
|
90
|
+
self._heartbeat_interval = None
|
|
91
|
+
if self._thread is not None:
|
|
92
|
+
try:
|
|
93
|
+
self._thread.join(timeout=1)
|
|
94
|
+
except RuntimeError:
|
|
95
|
+
LOGGER.debug("failed to join session heartbeat thread")
|
|
96
|
+
self._thread = None
|
|
97
|
+
|
|
98
|
+
async def _send_request(self, event: SendRequest):
|
|
99
|
+
if self._disabled:
|
|
100
|
+
return
|
|
101
|
+
|
|
102
|
+
if not self._is_safety_heartbeat_monitored(event.method_name):
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
event.metadata.update(await self.metadata)
|
|
106
|
+
|
|
107
|
+
async def _recv_trailers(self, event: RecvTrailingMetadata):
|
|
108
|
+
if event.status == Status.INVALID_ARGUMENT and event.status_message == "SESSION_EXPIRED":
|
|
109
|
+
LOGGER.debug("Session expired")
|
|
110
|
+
self.reset()
|
|
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
|
+
|
|
121
|
+
@property
|
|
122
|
+
async def metadata(self) -> _MetadataLike:
|
|
123
|
+
async with self._acquire_lock_async():
|
|
124
|
+
if self._disabled or self._supported != _SupportedState.UNKNOWN:
|
|
125
|
+
return self._metadata
|
|
126
|
+
|
|
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:
|
|
132
|
+
self._reset()
|
|
133
|
+
self._supported = _SupportedState.FALSE
|
|
134
|
+
return self._metadata
|
|
135
|
+
else:
|
|
136
|
+
raise
|
|
137
|
+
|
|
138
|
+
if response is None:
|
|
139
|
+
raise GRPCError(status=Status.INTERNAL, message="Expected response to start session")
|
|
140
|
+
|
|
141
|
+
if response.heartbeat_window is None:
|
|
142
|
+
raise GRPCError(status=Status.INTERNAL, message="Expected heartbeat window in response to start session")
|
|
143
|
+
|
|
144
|
+
self._supported = _SupportedState.TRUE
|
|
145
|
+
self._heartbeat_interval = response.heartbeat_window.ToTimedelta()
|
|
146
|
+
self._current_id = response.id
|
|
147
|
+
|
|
148
|
+
# tick once to ensure heartbeats are supported
|
|
149
|
+
await self._heartbeat_tick(self.client)
|
|
150
|
+
|
|
151
|
+
if self._thread is not None:
|
|
152
|
+
self._reset()
|
|
153
|
+
if self._supported == _SupportedState.TRUE:
|
|
154
|
+
# We send heartbeats faster than the interval window to
|
|
155
|
+
# ensure that we don't fall outside of it and expire the session.
|
|
156
|
+
wait = self._heartbeat_interval.total_seconds() / 5
|
|
157
|
+
|
|
158
|
+
self._thread = Thread(
|
|
159
|
+
name="heartbeat-thread",
|
|
160
|
+
target=asyncio.run,
|
|
161
|
+
args=(self._heartbeat_process(wait),),
|
|
162
|
+
daemon=True,
|
|
163
|
+
)
|
|
164
|
+
self._thread.start()
|
|
165
|
+
|
|
166
|
+
return self._metadata
|
|
167
|
+
|
|
168
|
+
async def _heartbeat_tick(self, client: RobotServiceStub):
|
|
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)
|
|
173
|
+
|
|
174
|
+
try:
|
|
175
|
+
await client.SendSessionHeartbeat(request)
|
|
176
|
+
except (GRPCError, StreamTerminatedError):
|
|
177
|
+
LOGGER.debug("Heartbeat terminated", exc_info=True)
|
|
178
|
+
self._reset()
|
|
179
|
+
else:
|
|
180
|
+
LOGGER.debug("Sent heartbeat successfully")
|
|
181
|
+
|
|
182
|
+
def _get_local_addr(self) -> str:
|
|
183
|
+
if sys.platform != "win32" and sys.platform != "cygwin":
|
|
184
|
+
# if we're not on windows, we want the direct dial address
|
|
185
|
+
return self._address
|
|
186
|
+
|
|
187
|
+
# return `robot_address` if it exists, otherwise fallback
|
|
188
|
+
# when using TCP (i.e., on Windows), we need to create a connection to the actual
|
|
189
|
+
# robot address for a sessions client to maintain connectivity successfully
|
|
190
|
+
return self._robot_address if self._robot_address is not None else self._address
|
|
191
|
+
|
|
192
|
+
async def _heartbeat_process(self, wait: float):
|
|
193
|
+
addr = self._get_local_addr()
|
|
194
|
+
channel = await dial(address=addr, options=self._dial_options)
|
|
195
|
+
client = RobotServiceStub(channel.channel)
|
|
196
|
+
while True:
|
|
197
|
+
async with self._acquire_lock_async():
|
|
198
|
+
if self._supported != _SupportedState.TRUE:
|
|
199
|
+
return
|
|
200
|
+
await self._heartbeat_tick(client)
|
|
201
|
+
await asyncio.sleep(wait)
|
|
202
|
+
|
|
203
|
+
@property
|
|
204
|
+
def _metadata(self) -> _MetadataLike:
|
|
205
|
+
if self._supported == _SupportedState.TRUE and self._current_id != "":
|
|
206
|
+
return {SESSION_METADATA_KEY: self._current_id}
|
|
207
|
+
|
|
208
|
+
return {}
|
|
209
|
+
|
|
210
|
+
def _is_safety_heartbeat_monitored(self, method: str) -> bool:
|
|
211
|
+
if method in self._HEARTBEAT_MONITORED_METHODS:
|
|
212
|
+
return self._HEARTBEAT_MONITORED_METHODS[method]
|
|
213
|
+
|
|
214
|
+
parts = method.split("/")
|
|
215
|
+
if len(parts) != 3:
|
|
216
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
217
|
+
return False
|
|
218
|
+
service_path = parts[1]
|
|
219
|
+
method_name = parts[2]
|
|
220
|
+
|
|
221
|
+
parts = service_path.split(".")
|
|
222
|
+
if len(parts) < 5:
|
|
223
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
224
|
+
return False
|
|
225
|
+
if parts[0] != "viam":
|
|
226
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
227
|
+
return False
|
|
228
|
+
resource_type = parts[1]
|
|
229
|
+
resource_subtype = parts[2]
|
|
230
|
+
version = parts[3]
|
|
231
|
+
service_name = parts[4]
|
|
232
|
+
try:
|
|
233
|
+
module = importlib.import_module(f"viam.gen.{resource_type}.{resource_subtype}.{version}")
|
|
234
|
+
submods = pkgutil.iter_modules(module.__path__)
|
|
235
|
+
for mod in submods:
|
|
236
|
+
if "_pb2" in mod.name:
|
|
237
|
+
submod = getattr(module, mod.name)
|
|
238
|
+
DESCRIPTOR = getattr(submod, "DESCRIPTOR")
|
|
239
|
+
for service in DESCRIPTOR.services_by_name.values():
|
|
240
|
+
if service.name == service_name:
|
|
241
|
+
for method_actual in service.methods:
|
|
242
|
+
if method_actual.name == method_name:
|
|
243
|
+
options = method_actual.GetOptions()
|
|
244
|
+
if options.HasExtension(safety_heartbeat_monitored):
|
|
245
|
+
is_monitored = options.Extensions[safety_heartbeat_monitored]
|
|
246
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = is_monitored
|
|
247
|
+
return is_monitored
|
|
248
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
249
|
+
return False
|
|
250
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
251
|
+
return False
|
|
252
|
+
except Exception:
|
|
253
|
+
self._HEARTBEAT_MONITORED_METHODS[method] = False
|
|
254
|
+
return False
|
viam/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
CHANGED
|
@@ -3,16 +3,20 @@ import contextvars
|
|
|
3
3
|
import functools
|
|
4
4
|
import sys
|
|
5
5
|
import threading
|
|
6
|
-
from
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from typing import Any, Callable, Dict, List, Mapping, Optional, SupportsBytes, SupportsFloat, Type, TypeVar, Union
|
|
7
8
|
|
|
8
9
|
from google.protobuf.json_format import MessageToDict, ParseDict
|
|
9
10
|
from google.protobuf.message import Message
|
|
10
11
|
from google.protobuf.struct_pb2 import ListValue, Struct, Value
|
|
12
|
+
from google.protobuf.timestamp_pb2 import Timestamp
|
|
11
13
|
|
|
12
|
-
from viam.proto.
|
|
14
|
+
from viam.proto.app.data import CaptureInterval, Filter, TagsFilter
|
|
15
|
+
from viam.proto.common import Geometry, GeoPoint, GetGeometriesRequest, GetGeometriesResponse, Orientation, ResourceName, Vector3
|
|
13
16
|
from viam.resource.base import ResourceBase
|
|
14
17
|
from viam.resource.registry import Registry
|
|
15
|
-
from viam.resource.
|
|
18
|
+
from viam.resource.rpc_client_base import ResourceRPCClientBase
|
|
19
|
+
from viam.resource.types import API, SupportsGetGeometries
|
|
16
20
|
|
|
17
21
|
if sys.version_info >= (3, 9):
|
|
18
22
|
from collections.abc import Callable
|
|
@@ -28,6 +32,9 @@ else:
|
|
|
28
32
|
ValueTypes = Union[bool, SupportsBytes, SupportsFloat, List, Mapping, str, None]
|
|
29
33
|
"""Types that can be encoded into a protobuf `Value`"""
|
|
30
34
|
|
|
35
|
+
SensorReading = Union[ValueTypes, Vector3, GeoPoint, Orientation]
|
|
36
|
+
"""Types that can be returned from a sensor"""
|
|
37
|
+
|
|
31
38
|
|
|
32
39
|
def primitive_to_value(v: ValueTypes) -> Value:
|
|
33
40
|
"""
|
|
@@ -97,14 +104,10 @@ def resource_names_for_resource(resource: ResourceBase) -> List[ResourceName]:
|
|
|
97
104
|
rns: List[ResourceName] = []
|
|
98
105
|
|
|
99
106
|
for klass in resource.__class__.mro():
|
|
100
|
-
for registration in Registry.
|
|
107
|
+
for registration in Registry.REGISTERED_APIS().values():
|
|
101
108
|
if klass is registration.resource_type:
|
|
102
|
-
|
|
103
|
-
rns.append(
|
|
104
|
-
ResourceName(
|
|
105
|
-
namespace=subtype.namespace, type=subtype.resource_type, subtype=subtype.resource_subtype, name=resource.name
|
|
106
|
-
)
|
|
107
|
-
)
|
|
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))
|
|
108
111
|
return rns
|
|
109
112
|
|
|
110
113
|
|
|
@@ -113,8 +116,8 @@ def message_to_struct(message: Message) -> Struct:
|
|
|
113
116
|
struct.update(
|
|
114
117
|
MessageToDict(
|
|
115
118
|
message,
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
True,
|
|
120
|
+
True,
|
|
118
121
|
),
|
|
119
122
|
)
|
|
120
123
|
return struct
|
|
@@ -128,7 +131,7 @@ def struct_to_message(struct: Struct, message_type: Type[_T]) -> _T:
|
|
|
128
131
|
return ParseDict(dct, message_type())
|
|
129
132
|
|
|
130
133
|
|
|
131
|
-
def dict_to_struct(obj: Mapping[str, ValueTypes]) -> Struct:
|
|
134
|
+
def dict_to_struct(obj: Optional[Mapping[str, ValueTypes]]) -> Struct:
|
|
132
135
|
def _convert(v: ValueTypes) -> Any:
|
|
133
136
|
if isinstance(v, bool):
|
|
134
137
|
return v
|
|
@@ -142,6 +145,8 @@ def dict_to_struct(obj: Mapping[str, ValueTypes]) -> Struct:
|
|
|
142
145
|
return {k: _convert(vv) for (k, vv) in v.items()}
|
|
143
146
|
return v
|
|
144
147
|
|
|
148
|
+
if obj is None:
|
|
149
|
+
obj = {}
|
|
145
150
|
struct = Struct()
|
|
146
151
|
struct.update({k: _convert(v) for (k, v) in obj.items()})
|
|
147
152
|
return struct
|
|
@@ -151,7 +156,28 @@ def struct_to_dict(struct: Struct) -> Dict[str, ValueTypes]:
|
|
|
151
156
|
return {key: value_to_primitive(value) for (key, value) in struct.fields.items()}
|
|
152
157
|
|
|
153
158
|
|
|
154
|
-
def
|
|
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]:
|
|
155
181
|
prim_readings = dict(readings)
|
|
156
182
|
for key, reading in readings.items():
|
|
157
183
|
if isinstance(reading, Vector3):
|
|
@@ -169,7 +195,7 @@ def sensor_readings_native_to_value(readings: Mapping[str, Any]) -> Mapping[str,
|
|
|
169
195
|
return {key: primitive_to_value(value) for (key, value) in prim_readings.items()}
|
|
170
196
|
|
|
171
197
|
|
|
172
|
-
def sensor_readings_value_to_native(readings: Mapping[str, Value]) -> Mapping[str,
|
|
198
|
+
def sensor_readings_value_to_native(readings: Mapping[str, Value]) -> Mapping[str, SensorReading]:
|
|
173
199
|
prim_readings: Dict[str, Any] = {key: value_to_primitive(value) for (key, value) in readings.items()}
|
|
174
200
|
for key, reading in prim_readings.items():
|
|
175
201
|
if isinstance(reading, Mapping):
|
|
@@ -235,3 +261,105 @@ async def to_thread(func: Callable[_P, _R], *args: _P.args, **kwargs: _P.kwargs)
|
|
|
235
261
|
ctx = contextvars.copy_context()
|
|
236
262
|
func_call = functools.partial(ctx.run, func, *args, **kwargs)
|
|
237
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
|
viam/version_metadata.py
ADDED