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.
- viam/__init__.py +71 -0
- viam/app/__init__.py +0 -0
- viam/app/_logs.py +34 -0
- viam/app/app_client.py +2525 -0
- viam/app/billing_client.py +143 -0
- viam/app/data_client.py +1715 -0
- viam/app/ml_training_client.py +251 -0
- viam/app/provisioning_client.py +95 -0
- viam/app/viam_client.py +260 -0
- viam/components/__init__.py +0 -0
- viam/components/arm/__init__.py +16 -0
- viam/components/arm/arm.py +223 -0
- viam/components/arm/client.py +124 -0
- viam/components/arm/service.py +123 -0
- viam/components/audio_input/__init__.py +18 -0
- viam/components/audio_input/audio_input.py +81 -0
- viam/components/audio_input/client.py +70 -0
- viam/components/audio_input/service.py +114 -0
- viam/components/base/__init__.py +13 -0
- viam/components/base/base.py +260 -0
- viam/components/base/client.py +153 -0
- viam/components/base/service.py +138 -0
- viam/components/board/__init__.py +9 -0
- viam/components/board/board.py +414 -0
- viam/components/board/client.py +241 -0
- viam/components/board/service.py +223 -0
- viam/components/button/__init__.py +10 -0
- viam/components/button/button.py +41 -0
- viam/components/button/client.py +52 -0
- viam/components/button/service.py +46 -0
- viam/components/camera/__init__.py +22 -0
- viam/components/camera/camera.py +138 -0
- viam/components/camera/client.py +98 -0
- viam/components/camera/service.py +105 -0
- viam/components/component_base.py +65 -0
- viam/components/encoder/__init__.py +18 -0
- viam/components/encoder/client.py +83 -0
- viam/components/encoder/encoder.py +118 -0
- viam/components/encoder/service.py +72 -0
- viam/components/gantry/__init__.py +11 -0
- viam/components/gantry/client.py +115 -0
- viam/components/gantry/gantry.py +156 -0
- viam/components/gantry/service.py +113 -0
- viam/components/generic/__init__.py +18 -0
- viam/components/generic/client.py +62 -0
- viam/components/generic/generic.py +76 -0
- viam/components/generic/service.py +40 -0
- viam/components/gripper/__init__.py +11 -0
- viam/components/gripper/client.py +85 -0
- viam/components/gripper/gripper.py +114 -0
- viam/components/gripper/service.py +81 -0
- viam/components/input/__init__.py +15 -0
- viam/components/input/client.py +194 -0
- viam/components/input/input.py +297 -0
- viam/components/input/service.py +175 -0
- viam/components/motor/__init__.py +11 -0
- viam/components/motor/client.py +168 -0
- viam/components/motor/motor.py +301 -0
- viam/components/motor/service.py +150 -0
- viam/components/movement_sensor/__init__.py +21 -0
- viam/components/movement_sensor/client.py +161 -0
- viam/components/movement_sensor/movement_sensor.py +253 -0
- viam/components/movement_sensor/service.py +146 -0
- viam/components/pose_tracker/__init__.py +17 -0
- viam/components/pose_tracker/client.py +50 -0
- viam/components/pose_tracker/pose_tracker.py +40 -0
- viam/components/pose_tracker/service.py +45 -0
- 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 +18 -0
- viam/components/sensor/client.py +49 -0
- viam/components/sensor/sensor.py +48 -0
- viam/components/sensor/service.py +51 -0
- viam/components/servo/__init__.py +11 -0
- viam/components/servo/client.py +86 -0
- viam/components/servo/service.py +80 -0
- viam/components/servo/servo.py +114 -0
- 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 +95 -0
- viam/errors.py +105 -0
- viam/gen/__init__.py +0 -0
- viam/gen/app/__init__.py +0 -0
- viam/gen/app/agent/__init__.py +0 -0
- viam/gen/app/agent/v1/__init__.py +0 -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/__init__.py +0 -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/__init__.py +0 -0
- viam/gen/app/data/v1/__init__.py +0 -0
- viam/gen/app/data/v1/data_grpc.py +206 -0
- viam/gen/app/data/v1/data_pb2.py +178 -0
- viam/gen/app/data/v1/data_pb2.pyi +1485 -0
- 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 +56 -0
- viam/gen/app/datapipelines/v1/data_pipelines_pb2.pyi +370 -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 +60 -0
- viam/gen/app/dataset/v1/dataset_pb2.py +40 -0
- viam/gen/app/dataset/v1/dataset_pb2.pyi +179 -0
- viam/gen/app/datasync/__init__.py +0 -0
- viam/gen/app/datasync/v1/__init__.py +0 -0
- viam/gen/app/datasync/v1/data_sync_grpc.py +47 -0
- viam/gen/app/datasync/v1/data_sync_pb2.py +70 -0
- viam/gen/app/datasync/v1/data_sync_pb2.pyi +425 -0
- 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/__init__.py +0 -0
- viam/gen/app/mltraining/v1/__init__.py +0 -0
- viam/gen/app/mltraining/v1/ml_training_grpc.py +78 -0
- viam/gen/app/mltraining/v1/ml_training_pb2.py +124 -0
- viam/gen/app/mltraining/v1/ml_training_pb2.pyi +415 -0
- viam/gen/app/packages/__init__.py +0 -0
- viam/gen/app/packages/v1/__init__.py +0 -0
- viam/gen/app/packages/v1/packages_grpc.py +54 -0
- viam/gen/app/packages/v1/packages_pb2.py +52 -0
- viam/gen/app/packages/v1/packages_pb2.pyi +311 -0
- viam/gen/app/v1/__init__.py +0 -0
- viam/gen/app/v1/app_grpc.py +863 -0
- viam/gen/app/v1/app_pb2.py +649 -0
- viam/gen/app/v1/app_pb2.pyi +5279 -0
- viam/gen/app/v1/billing_grpc.py +76 -0
- viam/gen/app/v1/billing_pb2.py +92 -0
- viam/gen/app/v1/billing_pb2.pyi +463 -0
- 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 +55 -0
- viam/gen/app/v1/robot_pb2.py +127 -0
- viam/gen/app/v1/robot_pb2.pyi +1202 -0
- viam/gen/common/__init__.py +0 -0
- viam/gen/common/v1/__init__.py +0 -0
- viam/gen/common/v1/common_grpc.py +0 -0
- viam/gen/common/v1/common_pb2.py +78 -0
- viam/gen/common/v1/common_pb2.pyi +687 -0
- viam/gen/component/__init__.py +0 -0
- viam/gen/component/arm/__init__.py +0 -0
- viam/gen/component/arm/v1/__init__.py +0 -0
- viam/gen/component/arm/v1/arm_grpc.py +102 -0
- viam/gen/component/arm/v1/arm_pb2.py +74 -0
- viam/gen/component/arm/v1/arm_pb2.pyi +344 -0
- viam/gen/component/audioinput/__init__.py +0 -0
- viam/gen/component/audioinput/v1/__init__.py +0 -0
- viam/gen/component/audioinput/v1/audioinput_grpc.py +63 -0
- viam/gen/component/audioinput/v1/audioinput_pb2.py +45 -0
- viam/gen/component/audioinput/v1/audioinput_pb2.pyi +179 -0
- viam/gen/component/base/__init__.py +0 -0
- viam/gen/component/base/v1/__init__.py +0 -0
- viam/gen/component/base/v1/base_grpc.py +94 -0
- viam/gen/component/base/v1/base_pb2.py +66 -0
- viam/gen/component/base/v1/base_pb2.pyi +258 -0
- viam/gen/component/board/__init__.py +0 -0
- viam/gen/component/board/v1/__init__.py +0 -0
- viam/gen/component/board/v1/board_grpc.py +127 -0
- viam/gen/component/board/v1/board_pb2.py +103 -0
- viam/gen/component/board/v1/board_pb2.pyi +496 -0
- 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/__init__.py +0 -0
- viam/gen/component/camera/v1/__init__.py +0 -0
- viam/gen/component/camera/v1/camera_grpc.py +79 -0
- viam/gen/component/camera/v1/camera_pb2.py +67 -0
- viam/gen/component/camera/v1/camera_pb2.pyi +373 -0
- viam/gen/component/encoder/__init__.py +0 -0
- viam/gen/component/encoder/v1/__init__.py +0 -0
- viam/gen/component/encoder/v1/encoder_grpc.py +62 -0
- viam/gen/component/encoder/v1/encoder_pb2.py +44 -0
- viam/gen/component/encoder/v1/encoder_pb2.pyi +147 -0
- viam/gen/component/gantry/__init__.py +0 -0
- viam/gen/component/gantry/v1/__init__.py +0 -0
- viam/gen/component/gantry/v1/gantry_grpc.py +86 -0
- viam/gen/component/gantry/v1/gantry_pb2.py +62 -0
- viam/gen/component/gantry/v1/gantry_pb2.pyi +239 -0
- viam/gen/component/generic/__init__.py +0 -0
- viam/gen/component/generic/v1/__init__.py +0 -0
- viam/gen/component/generic/v1/generic_grpc.py +37 -0
- viam/gen/component/generic/v1/generic_pb2.py +23 -0
- viam/gen/component/generic/v1/generic_pb2.pyi +6 -0
- viam/gen/component/gripper/__init__.py +0 -0
- viam/gen/component/gripper/v1/__init__.py +0 -0
- viam/gen/component/gripper/v1/gripper_grpc.py +70 -0
- viam/gen/component/gripper/v1/gripper_pb2.py +48 -0
- viam/gen/component/gripper/v1/gripper_pb2.pyi +137 -0
- viam/gen/component/inputcontroller/__init__.py +0 -0
- viam/gen/component/inputcontroller/v1/__init__.py +0 -0
- viam/gen/component/inputcontroller/v1/input_controller_grpc.py +71 -0
- viam/gen/component/inputcontroller/v1/input_controller_pb2.py +55 -0
- viam/gen/component/inputcontroller/v1/input_controller_pb2.pyi +243 -0
- viam/gen/component/motor/__init__.py +0 -0
- viam/gen/component/motor/v1/__init__.py +0 -0
- viam/gen/component/motor/v1/motor_grpc.py +118 -0
- viam/gen/component/motor/v1/motor_pb2.py +86 -0
- viam/gen/component/motor/v1/motor_pb2.pyi +368 -0
- viam/gen/component/movementsensor/__init__.py +0 -0
- viam/gen/component/movementsensor/v1/__init__.py +0 -0
- viam/gen/component/movementsensor/v1/movementsensor_grpc.py +110 -0
- viam/gen/component/movementsensor/v1/movementsensor_pb2.py +78 -0
- viam/gen/component/movementsensor/v1/movementsensor_pb2.pyi +384 -0
- viam/gen/component/posetracker/__init__.py +0 -0
- viam/gen/component/posetracker/v1/__init__.py +0 -0
- viam/gen/component/posetracker/v1/pose_tracker_grpc.py +46 -0
- viam/gen/component/posetracker/v1/pose_tracker_pb2.py +34 -0
- viam/gen/component/posetracker/v1/pose_tracker_pb2.pyi +79 -0
- 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/__init__.py +0 -0
- viam/gen/component/sensor/v1/__init__.py +0 -0
- viam/gen/component/sensor/v1/sensor_grpc.py +45 -0
- viam/gen/component/sensor/v1/sensor_pb2.py +25 -0
- viam/gen/component/sensor/v1/sensor_pb2.pyi +6 -0
- viam/gen/component/servo/__init__.py +0 -0
- viam/gen/component/servo/v1/__init__.py +0 -0
- viam/gen/component/servo/v1/servo_grpc.py +70 -0
- viam/gen/component/servo/v1/servo_pb2.py +50 -0
- viam/gen/component/servo/v1/servo_pb2.pyi +150 -0
- 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 +109 -0
- viam/gen/component/testecho/__init__.py +0 -0
- viam/gen/component/testecho/v1/__init__.py +0 -0
- viam/gen/component/testecho/v1/testecho_grpc.py +52 -0
- viam/gen/component/testecho/v1/testecho_pb2.py +36 -0
- viam/gen/component/testecho/v1/testecho_pb2.pyi +114 -0
- viam/gen/module/__init__.py +0 -0
- viam/gen/module/v1/__init__.py +0 -0
- viam/gen/module/v1/module_grpc.py +61 -0
- viam/gen/module/v1/module_pb2.py +43 -0
- viam/gen/module/v1/module_pb2.pyi +211 -0
- viam/gen/proto/__init__.py +0 -0
- viam/gen/proto/rpc/__init__.py +0 -0
- viam/gen/proto/rpc/examples/__init__.py +0 -0
- viam/gen/proto/rpc/examples/echo/__init__.py +0 -0
- viam/gen/proto/rpc/examples/echo/v1/__init__.py +0 -0
- viam/gen/proto/rpc/examples/echo/v1/echo_grpc.py +44 -0
- viam/gen/proto/rpc/examples/echo/v1/echo_pb2.py +32 -0
- viam/gen/proto/rpc/examples/echo/v1/echo_pb2.pyi +87 -0
- viam/gen/proto/rpc/examples/echoresource/__init__.py +0 -0
- viam/gen/proto/rpc/examples/echoresource/v1/__init__.py +0 -0
- viam/gen/proto/rpc/examples/echoresource/v1/echoresource_grpc.py +43 -0
- viam/gen/proto/rpc/examples/echoresource/v1/echoresource_pb2.py +29 -0
- viam/gen/proto/rpc/examples/echoresource/v1/echoresource_pb2.pyi +93 -0
- viam/gen/proto/rpc/v1/__init__.py +0 -0
- viam/gen/proto/rpc/v1/auth_grpc.py +47 -0
- viam/gen/proto/rpc/v1/auth_pb2.py +34 -0
- viam/gen/proto/rpc/v1/auth_pb2.pyi +92 -0
- viam/gen/proto/rpc/webrtc/__init__.py +0 -0
- viam/gen/proto/rpc/webrtc/v1/__init__.py +0 -0
- viam/gen/proto/rpc/webrtc/v1/grpc_grpc.py +0 -0
- viam/gen/proto/rpc/webrtc/v1/grpc_pb2.py +43 -0
- viam/gen/proto/rpc/webrtc/v1/grpc_pb2.pyi +304 -0
- viam/gen/proto/rpc/webrtc/v1/signaling_grpc.py +54 -0
- viam/gen/proto/rpc/webrtc/v1/signaling_pb2.py +70 -0
- viam/gen/proto/rpc/webrtc/v1/signaling_pb2.pyi +496 -0
- viam/gen/provisioning/__init__.py +0 -0
- viam/gen/provisioning/v1/__init__.py +0 -0
- viam/gen/provisioning/v1/provisioning_grpc.py +51 -0
- viam/gen/provisioning/v1/provisioning_pb2.py +39 -0
- viam/gen/provisioning/v1/provisioning_pb2.pyi +188 -0
- viam/gen/robot/__init__.py +0 -0
- viam/gen/robot/v1/__init__.py +0 -0
- viam/gen/robot/v1/robot_grpc.py +208 -0
- viam/gen/robot/v1/robot_pb2.py +188 -0
- viam/gen/robot/v1/robot_pb2.pyi +1020 -0
- viam/gen/service/__init__.py +0 -0
- viam/gen/service/datamanager/__init__.py +0 -0
- viam/gen/service/datamanager/v1/__init__.py +0 -0
- viam/gen/service/datamanager/v1/data_manager_grpc.py +38 -0
- viam/gen/service/datamanager/v1/data_manager_pb2.py +28 -0
- viam/gen/service/datamanager/v1/data_manager_pb2.pyi +39 -0
- 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/__init__.py +0 -0
- viam/gen/service/mlmodel/v1/__init__.py +0 -0
- viam/gen/service/mlmodel/v1/mlmodel_grpc.py +37 -0
- viam/gen/service/mlmodel/v1/mlmodel_pb2.py +83 -0
- viam/gen/service/mlmodel/v1/mlmodel_pb2.pyi +480 -0
- viam/gen/service/motion/__init__.py +0 -0
- viam/gen/service/motion/v1/__init__.py +0 -0
- viam/gen/service/motion/v1/motion_grpc.py +87 -0
- viam/gen/service/motion/v1/motion_pb2.py +97 -0
- viam/gen/service/motion/v1/motion_pb2.pyi +838 -0
- viam/gen/service/navigation/__init__.py +0 -0
- viam/gen/service/navigation/v1/__init__.py +0 -0
- viam/gen/service/navigation/v1/navigation_grpc.py +102 -0
- viam/gen/service/navigation/v1/navigation_pb2.py +84 -0
- viam/gen/service/navigation/v1/navigation_pb2.pyi +419 -0
- viam/gen/service/sensors/__init__.py +0 -0
- viam/gen/service/sensors/v1/__init__.py +0 -0
- viam/gen/service/sensors/v1/sensors_grpc.py +46 -0
- viam/gen/service/sensors/v1/sensors_pb2.py +68 -0
- viam/gen/service/sensors/v1/sensors_pb2.pyi +137 -0
- viam/gen/service/shell/__init__.py +0 -0
- viam/gen/service/shell/v1/__init__.py +0 -0
- viam/gen/service/shell/v1/shell_grpc.py +55 -0
- viam/gen/service/shell/v1/shell_pb2.py +45 -0
- viam/gen/service/shell/v1/shell_pb2.pyi +307 -0
- viam/gen/service/slam/__init__.py +0 -0
- viam/gen/service/slam/v1/__init__.py +0 -0
- viam/gen/service/slam/v1/slam_grpc.py +61 -0
- viam/gen/service/slam/v1/slam_pb2.py +51 -0
- viam/gen/service/slam/v1/slam_pb2.pyi +213 -0
- viam/gen/service/vision/__init__.py +0 -0
- viam/gen/service/vision/v1/__init__.py +0 -0
- viam/gen/service/vision/v1/vision_grpc.py +87 -0
- viam/gen/service/vision/v1/vision_pb2.py +69 -0
- viam/gen/service/vision/v1/vision_pb2.pyi +454 -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/__init__.py +0 -0
- viam/gen/tagger/v1/__init__.py +0 -0
- viam/gen/tagger/v1/tagger_grpc.py +0 -0
- viam/gen/tagger/v1/tagger_pb2.py +16 -0
- viam/gen/tagger/v1/tagger_pb2.pyi +15 -0
- viam/logging.py +216 -0
- viam/media/__init__.py +0 -0
- viam/media/audio.py +16 -0
- viam/media/utils/__init__.py +0 -0
- viam/media/utils/pil/__init__.py +51 -0
- viam/media/utils/pil/viam_rgba_plugin.py +73 -0
- viam/media/viam_rgba.py +10 -0
- viam/media/video.py +217 -0
- viam/module/__init__.py +5 -0
- viam/module/module.py +281 -0
- viam/module/service.py +66 -0
- viam/module/types.py +23 -0
- viam/operations.py +124 -0
- viam/proto/__init__.py +0 -0
- viam/proto/app/__init__.py +554 -0
- viam/proto/app/agent/__init__.py +28 -0
- viam/proto/app/billing.py +58 -0
- viam/proto/app/cloudslam/__init__.py +48 -0
- viam/proto/app/data/__init__.py +138 -0
- viam/proto/app/datapipelines/__init__.py +56 -0
- viam/proto/app/dataset/__init__.py +36 -0
- viam/proto/app/datasync/__init__.py +44 -0
- viam/proto/app/end_user.py +34 -0
- viam/proto/app/mlinference/__init__.py +15 -0
- viam/proto/app/mltraining/__init__.py +52 -0
- viam/proto/app/packages/__init__.py +38 -0
- viam/proto/app/robot.py +84 -0
- viam/proto/common/__init__.py +66 -0
- viam/proto/component/__init__.py +0 -0
- viam/proto/component/arm/__init__.py +48 -0
- viam/proto/component/audioinput/__init__.py +30 -0
- viam/proto/component/base/__init__.py +42 -0
- viam/proto/component/board/__init__.py +62 -0
- viam/proto/component/button/__init__.py +15 -0
- viam/proto/component/camera/__init__.py +46 -0
- viam/proto/component/encoder/__init__.py +28 -0
- viam/proto/component/gantry/__init__.py +40 -0
- viam/proto/component/generic/__init__.py +12 -0
- viam/proto/component/gripper/__init__.py +30 -0
- viam/proto/component/inputcontroller/__init__.py +38 -0
- viam/proto/component/motor/__init__.py +56 -0
- viam/proto/component/movementsensor/__init__.py +50 -0
- viam/proto/component/posetracker/__init__.py +19 -0
- viam/proto/component/powersensor/__init__.py +30 -0
- viam/proto/component/sensor/__init__.py +12 -0
- viam/proto/component/servo/__init__.py +32 -0
- viam/proto/component/switch/__init__.py +26 -0
- viam/proto/component/testecho/__init__.py +30 -0
- viam/proto/module/__init__.py +38 -0
- viam/proto/provisioning/__init__.py +36 -0
- viam/proto/robot/__init__.py +130 -0
- viam/proto/rpc/__init__.py +0 -0
- viam/proto/rpc/auth.py +34 -0
- viam/proto/rpc/examples/__init__.py +0 -0
- viam/proto/rpc/examples/echo/__init__.py +26 -0
- viam/proto/rpc/examples/echoresource/__init__.py +30 -0
- viam/proto/rpc/webrtc/__init__.py +0 -0
- viam/proto/rpc/webrtc/grpc.py +36 -0
- viam/proto/rpc/webrtc/signaling.py +58 -0
- viam/proto/service/__init__.py +0 -0
- viam/proto/service/datamanager/__init__.py +19 -0
- viam/proto/service/discovery/__init__.py +15 -0
- viam/proto/service/generic/__init__.py +12 -0
- viam/proto/service/mlmodel/__init__.py +54 -0
- viam/proto/service/motion/__init__.py +68 -0
- viam/proto/service/navigation/__init__.py +58 -0
- viam/proto/service/sensors/__init__.py +18 -0
- viam/proto/service/shell/__init__.py +36 -0
- viam/proto/service/slam/__init__.py +36 -0
- viam/proto/service/vision/__init__.py +46 -0
- viam/proto/stream/__init__.py +36 -0
- viam/proto/tagger/__init__.py +6 -0
- viam/py.typed +0 -0
- viam/resource/__init__.py +0 -0
- viam/resource/base.py +123 -0
- viam/resource/easy_resource.py +153 -0
- viam/resource/manager.py +126 -0
- viam/resource/registry.py +199 -0
- viam/resource/rpc_client_base.py +65 -0
- viam/resource/rpc_service_base.py +48 -0
- viam/resource/types.py +213 -0
- viam/robot/__init__.py +0 -0
- viam/robot/client.py +909 -0
- viam/robot/service.py +69 -0
- viam/rpc/__init__.py +0 -0
- viam/rpc/dial.py +420 -0
- viam/rpc/libviam_rust_utils.dll +0 -0
- viam/rpc/server.py +201 -0
- viam/rpc/signaling.py +29 -0
- viam/rpc/types.py +22 -0
- viam/services/__init__.py +0 -0
- 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 +24 -0
- viam/services/mlmodel/client.py +37 -0
- viam/services/mlmodel/mlmodel.py +78 -0
- viam/services/mlmodel/service.py +38 -0
- viam/services/mlmodel/utils.py +101 -0
- viam/services/motion/__init__.py +17 -0
- viam/services/motion/client.py +215 -0
- viam/services/motion/motion.py +378 -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 +78 -0
- viam/services/service_client_base.py +46 -0
- viam/services/slam/__init__.py +17 -0
- viam/services/slam/client.py +62 -0
- viam/services/slam/service.py +75 -0
- viam/services/slam/slam.py +111 -0
- viam/services/vision/__init__.py +15 -0
- viam/services/vision/client.py +206 -0
- viam/services/vision/service.py +146 -0
- viam/services/vision/vision.py +315 -0
- viam/sessions_client.py +245 -0
- viam/streams.py +44 -0
- viam/utils.py +365 -0
- viam/version_metadata.py +4 -0
- viam_sdk-0.45.2.dist-info/METADATA +157 -0
- viam_sdk-0.45.2.dist-info/RECORD +476 -0
- viam_sdk-0.45.2.dist-info/WHEEL +4 -0
- viam_sdk-0.45.2.dist-info/licenses/LICENSE +202 -0
viam/rpc/signaling.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from grpclib.const import Status
|
|
2
|
+
from grpclib.exceptions import GRPCError
|
|
3
|
+
from grpclib.server import Stream
|
|
4
|
+
|
|
5
|
+
from viam.proto.rpc.webrtc.signaling import (
|
|
6
|
+
AnswerRequest,
|
|
7
|
+
AnswerResponse,
|
|
8
|
+
CallRequest,
|
|
9
|
+
CallResponse,
|
|
10
|
+
CallUpdateRequest,
|
|
11
|
+
CallUpdateResponse,
|
|
12
|
+
OptionalWebRTCConfigRequest,
|
|
13
|
+
OptionalWebRTCConfigResponse,
|
|
14
|
+
SignalingServiceBase,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SignalingService(SignalingServiceBase):
|
|
19
|
+
async def Call(self, stream: Stream[CallRequest, CallResponse]) -> None:
|
|
20
|
+
raise GRPCError(Status.UNIMPLEMENTED, "SignalingService is unimplemented")
|
|
21
|
+
|
|
22
|
+
async def CallUpdate(self, stream: Stream[CallUpdateRequest, CallUpdateResponse]) -> None:
|
|
23
|
+
raise GRPCError(Status.UNIMPLEMENTED, "SignalingService is unimplemented")
|
|
24
|
+
|
|
25
|
+
async def Answer(self, stream: Stream[AnswerResponse, AnswerRequest]) -> None:
|
|
26
|
+
raise GRPCError(Status.UNIMPLEMENTED, "SignalingService is unimplemented")
|
|
27
|
+
|
|
28
|
+
async def OptionalWebRTCConfig(self, stream: Stream[OptionalWebRTCConfigRequest, OptionalWebRTCConfigResponse]) -> None:
|
|
29
|
+
raise GRPCError(Status.UNIMPLEMENTED, "SignalingService is unimplemented")
|
viam/rpc/types.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
from typing import Mapping, Protocol, runtime_checkable
|
|
3
|
+
|
|
4
|
+
import grpclib
|
|
5
|
+
from grpclib._typing import IServable
|
|
6
|
+
from grpclib.client import Channel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RPCServiceBase(IServable):
|
|
10
|
+
"""The base requirements for an RPC Service.
|
|
11
|
+
|
|
12
|
+
An RPC Service is a service that can handle incoming RPC requests.
|
|
13
|
+
Services that implement the service bases generated by grpclib will automatically conform to this protocol.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
@abstractmethod
|
|
17
|
+
def __mapping__(self) -> Mapping[str, grpclib.const.Handler]: ...
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@runtime_checkable
|
|
21
|
+
class RPCServiceStubBase(Protocol):
|
|
22
|
+
def __init__(self, channel: Channel) -> None: ...
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from viam.resource.registry import Registry, ResourceRegistration
|
|
2
|
+
from viam.services.discovery.service import DiscoveryRPCService
|
|
3
|
+
|
|
4
|
+
from .client import DiscoveryClient
|
|
5
|
+
from .discovery import Discovery
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"DiscoveryClient",
|
|
9
|
+
"Discovery",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
Registry.register_api(ResourceRegistration(Discovery, DiscoveryRPCService, lambda name, channel: DiscoveryClient(name, channel)))
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from typing import Any, List, Mapping, Optional
|
|
2
|
+
|
|
3
|
+
from grpclib.client import Channel
|
|
4
|
+
|
|
5
|
+
from viam.proto.app.robot import ComponentConfig
|
|
6
|
+
from viam.proto.common import DoCommandRequest, DoCommandResponse
|
|
7
|
+
from viam.proto.service.discovery import (
|
|
8
|
+
DiscoverResourcesRequest,
|
|
9
|
+
DiscoverResourcesResponse,
|
|
10
|
+
DiscoveryServiceStub,
|
|
11
|
+
)
|
|
12
|
+
from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase
|
|
13
|
+
from viam.utils import ValueTypes, dict_to_struct, struct_to_dict
|
|
14
|
+
|
|
15
|
+
from .discovery import Discovery
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class DiscoveryClient(Discovery, ReconfigurableResourceRPCClientBase):
|
|
19
|
+
"""
|
|
20
|
+
Connect to the Discovery service, which allows you to discover resources on a machine.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
client: DiscoveryServiceStub
|
|
24
|
+
|
|
25
|
+
def __init__(self, name: str, channel: Channel):
|
|
26
|
+
super().__init__(name)
|
|
27
|
+
self.channel = channel
|
|
28
|
+
self.client = DiscoveryServiceStub(channel)
|
|
29
|
+
|
|
30
|
+
async def discover_resources(
|
|
31
|
+
self,
|
|
32
|
+
*,
|
|
33
|
+
extra: Optional[Mapping[str, Any]] = None,
|
|
34
|
+
timeout: Optional[float] = None,
|
|
35
|
+
**kwargs,
|
|
36
|
+
) -> List[ComponentConfig]:
|
|
37
|
+
md = kwargs.get("metadata", self.Metadata()).proto
|
|
38
|
+
request = DiscoverResourcesRequest(
|
|
39
|
+
name=self.name,
|
|
40
|
+
extra=dict_to_struct(extra),
|
|
41
|
+
)
|
|
42
|
+
response: DiscoverResourcesResponse = await self.client.DiscoverResources(request, timeout=timeout, metadata=md)
|
|
43
|
+
return list(response.discoveries)
|
|
44
|
+
|
|
45
|
+
async def do_command(
|
|
46
|
+
self,
|
|
47
|
+
command: Mapping[str, ValueTypes],
|
|
48
|
+
*,
|
|
49
|
+
timeout: Optional[float] = None,
|
|
50
|
+
**kwargs,
|
|
51
|
+
) -> Mapping[str, ValueTypes]:
|
|
52
|
+
md = kwargs.get("metadata", self.Metadata()).proto
|
|
53
|
+
request = DoCommandRequest(name=self.name, command=dict_to_struct(command))
|
|
54
|
+
response: DoCommandResponse = await self.client.DoCommand(request, timeout=timeout, metadata=md)
|
|
55
|
+
return struct_to_dict(response.result)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
from typing import Final, List, Mapping, Optional
|
|
3
|
+
|
|
4
|
+
from viam.proto.app.robot import ComponentConfig
|
|
5
|
+
from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_SERVICE
|
|
6
|
+
from viam.utils import ValueTypes
|
|
7
|
+
|
|
8
|
+
from ..service_base import ServiceBase
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Discovery(ServiceBase):
|
|
12
|
+
"""
|
|
13
|
+
Discovery represents a Discovery service.
|
|
14
|
+
|
|
15
|
+
This acts as an abstract base class for any drivers representing specific
|
|
16
|
+
discovery implementations. This cannot be used on its own. If the ``__init__()`` function is
|
|
17
|
+
overridden, it must call the ``super().__init__()`` function.
|
|
18
|
+
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
API: Final = API( # pyright: ignore [reportIncompatibleVariableOverride]
|
|
22
|
+
RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_SERVICE, "discovery"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
@abc.abstractmethod
|
|
26
|
+
async def discover_resources(
|
|
27
|
+
self,
|
|
28
|
+
*,
|
|
29
|
+
extra: Optional[Mapping[str, ValueTypes]] = None,
|
|
30
|
+
timeout: Optional[float] = None,
|
|
31
|
+
) -> List[ComponentConfig]:
|
|
32
|
+
"""Get all component configs of discovered resources on a machine
|
|
33
|
+
|
|
34
|
+
::
|
|
35
|
+
|
|
36
|
+
my_discovery = DiscoveryClient.from_robot(machine, "my_discovery")
|
|
37
|
+
|
|
38
|
+
# Get the discovered resources
|
|
39
|
+
result = await my_discovery.discover_resources(
|
|
40
|
+
"my_discovery",
|
|
41
|
+
)
|
|
42
|
+
discoveries = result.discoveries
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
name (str): The name of the discover service
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
List[ComponentConfig]: A list of ComponentConfigs that describe
|
|
49
|
+
the components found by a discover service
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
...
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from grpclib.server import Stream
|
|
2
|
+
|
|
3
|
+
from viam.proto.common import DoCommandRequest, DoCommandResponse
|
|
4
|
+
from viam.proto.service.discovery import (
|
|
5
|
+
DiscoverResourcesRequest,
|
|
6
|
+
DiscoverResourcesResponse,
|
|
7
|
+
UnimplementedDiscoveryServiceBase,
|
|
8
|
+
)
|
|
9
|
+
from viam.resource.rpc_service_base import ResourceRPCServiceBase
|
|
10
|
+
from viam.utils import dict_to_struct, struct_to_dict
|
|
11
|
+
|
|
12
|
+
from .discovery import Discovery
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DiscoveryRPCService(UnimplementedDiscoveryServiceBase, ResourceRPCServiceBase):
|
|
16
|
+
"""
|
|
17
|
+
gRPC service for a Discovery service
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
RESOURCE_TYPE = Discovery
|
|
21
|
+
|
|
22
|
+
async def DiscoverResources(self, stream: Stream[DiscoverResourcesRequest, DiscoverResourcesResponse]) -> None:
|
|
23
|
+
request = await stream.recv_message()
|
|
24
|
+
assert request is not None
|
|
25
|
+
discovery = self.get_resource(request.name)
|
|
26
|
+
extra = struct_to_dict(request.extra)
|
|
27
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
28
|
+
result = await discovery.discover_resources(
|
|
29
|
+
extra=extra,
|
|
30
|
+
timeout=timeout,
|
|
31
|
+
)
|
|
32
|
+
response = DiscoverResourcesResponse(
|
|
33
|
+
discoveries=result,
|
|
34
|
+
)
|
|
35
|
+
await stream.send_message(response)
|
|
36
|
+
|
|
37
|
+
async def DoCommand(self, stream: Stream[DoCommandRequest, DoCommandResponse]) -> None:
|
|
38
|
+
request = await stream.recv_message()
|
|
39
|
+
assert request is not None
|
|
40
|
+
discovery = self.get_resource(request.name)
|
|
41
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
42
|
+
result = await discovery.do_command(struct_to_dict(request.command), timeout=timeout)
|
|
43
|
+
await stream.send_message(DoCommandResponse(result=dict_to_struct(result)))
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import viam.gen.service.generic.v1.generic_pb2 # Need this import for Generic service descriptors to resolve
|
|
2
|
+
from viam.resource.registry import Registry, ResourceRegistration
|
|
3
|
+
|
|
4
|
+
from .client import GenericClient
|
|
5
|
+
from .generic import Generic
|
|
6
|
+
from .service import GenericRPCService
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"Generic",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
Registry.register_api(
|
|
13
|
+
ResourceRegistration(
|
|
14
|
+
Generic,
|
|
15
|
+
GenericRPCService,
|
|
16
|
+
lambda name, channel: GenericClient(name, channel),
|
|
17
|
+
)
|
|
18
|
+
)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from typing import Any, Mapping, Optional
|
|
2
|
+
|
|
3
|
+
from grpclib import GRPCError, Status
|
|
4
|
+
from grpclib.client import Channel
|
|
5
|
+
|
|
6
|
+
from viam.proto.common import DoCommandRequest, DoCommandResponse
|
|
7
|
+
from viam.proto.service.generic import GenericServiceStub
|
|
8
|
+
from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase, ResourceRPCClientBase
|
|
9
|
+
from viam.utils import ValueTypes, dict_to_struct, struct_to_dict
|
|
10
|
+
|
|
11
|
+
from .generic import Generic
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class GenericClient(Generic, ReconfigurableResourceRPCClientBase):
|
|
15
|
+
"""
|
|
16
|
+
gRPC client for the Generic service.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, name: str, channel: Channel):
|
|
20
|
+
self.channel = channel
|
|
21
|
+
self.client = GenericServiceStub(channel)
|
|
22
|
+
super().__init__(name)
|
|
23
|
+
|
|
24
|
+
async def do_command(
|
|
25
|
+
self,
|
|
26
|
+
command: Mapping[str, Any],
|
|
27
|
+
*,
|
|
28
|
+
timeout: Optional[float] = None,
|
|
29
|
+
**kwargs,
|
|
30
|
+
) -> Mapping[str, Any]:
|
|
31
|
+
md = kwargs.get("metadata", self.Metadata()).proto
|
|
32
|
+
request = DoCommandRequest(name=self.name, command=dict_to_struct(command))
|
|
33
|
+
try:
|
|
34
|
+
response: DoCommandResponse = await self.client.DoCommand(request, timeout=timeout, metadata=md)
|
|
35
|
+
except GRPCError as e:
|
|
36
|
+
if e.status == Status.UNIMPLEMENTED:
|
|
37
|
+
raise NotImplementedError()
|
|
38
|
+
raise e
|
|
39
|
+
|
|
40
|
+
return struct_to_dict(response.result)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
async def do_command(
|
|
44
|
+
channel: Channel, name: str, command: Mapping[str, ValueTypes], *, timeout: Optional[float] = None, **kwargs
|
|
45
|
+
) -> Mapping[str, ValueTypes]:
|
|
46
|
+
"""Convenience method to allow service clients to execute ``do_command`` functions
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
channel (Channel): A gRPC channel
|
|
50
|
+
name (str): The name of the component
|
|
51
|
+
command (Dict[str, Any]): The command to execute
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
Dict[str, Any]: The result of the executed command
|
|
55
|
+
"""
|
|
56
|
+
md = kwargs.get("metadata", ResourceRPCClientBase.Metadata()).proto
|
|
57
|
+
client = GenericClient(name, channel)
|
|
58
|
+
return await client.do_command(command, timeout=timeout, metadata=md)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from typing import Final
|
|
2
|
+
|
|
3
|
+
from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_SERVICE
|
|
4
|
+
|
|
5
|
+
from ..service_base import ServiceBase
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Generic(ServiceBase):
|
|
9
|
+
"""
|
|
10
|
+
Generic service, which represents any type of service that can execute arbitrary commands
|
|
11
|
+
|
|
12
|
+
This acts as an abstract base class for any drivers representing generic services.
|
|
13
|
+
This cannot be used on its own. If the ``__init__()`` function is overridden, it must call the ``super().__init__()`` function.
|
|
14
|
+
|
|
15
|
+
To create a Generic service (an arbitrary service that can process commands), this ``Generic`` service should be subclassed
|
|
16
|
+
and the ``do_command`` function implemented.
|
|
17
|
+
|
|
18
|
+
Example::
|
|
19
|
+
|
|
20
|
+
class ComplexService(Generic):
|
|
21
|
+
|
|
22
|
+
async def do_command(
|
|
23
|
+
self,
|
|
24
|
+
command: Mapping[str, ValueTypes],
|
|
25
|
+
*,
|
|
26
|
+
timeout: Optional[float] = None,
|
|
27
|
+
**kwargs
|
|
28
|
+
) -> Mapping[str, ValueTypes]:
|
|
29
|
+
result = {key: False for key in command.keys()}
|
|
30
|
+
for (name, args) in command.items():
|
|
31
|
+
if name == 'set_val':
|
|
32
|
+
self.set_val(*args)
|
|
33
|
+
result[name] = True
|
|
34
|
+
if name == 'get_val':
|
|
35
|
+
result[name] = self.val
|
|
36
|
+
if name == 'complex_command':
|
|
37
|
+
self.complex_command(*args)
|
|
38
|
+
result[name] = True
|
|
39
|
+
return result
|
|
40
|
+
|
|
41
|
+
def set_val(self, val: int):
|
|
42
|
+
self.val = val
|
|
43
|
+
|
|
44
|
+
def complex_command(self, arg1, arg2, arg3):
|
|
45
|
+
...
|
|
46
|
+
|
|
47
|
+
To execute commands, simply call the ``do_command`` function with the appropriate parameters.
|
|
48
|
+
::
|
|
49
|
+
|
|
50
|
+
await service.do_command({'set_val': 10})
|
|
51
|
+
service.val # 10
|
|
52
|
+
await service.do_command({'set_val': 5})
|
|
53
|
+
service.val # 5
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
API: Final = API( # pyright: ignore [reportIncompatibleVariableOverride]
|
|
57
|
+
RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_SERVICE, "generic"
|
|
58
|
+
)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from grpclib import GRPCError, Status
|
|
2
|
+
from grpclib.server import Stream
|
|
3
|
+
|
|
4
|
+
from viam.proto.common import DoCommandRequest, DoCommandResponse
|
|
5
|
+
from viam.proto.service.generic import GenericServiceBase
|
|
6
|
+
from viam.resource.rpc_service_base import ResourceRPCServiceBase
|
|
7
|
+
from viam.services.service_base import ServiceBase
|
|
8
|
+
from viam.utils import dict_to_struct, struct_to_dict
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GenericRPCService(GenericServiceBase, ResourceRPCServiceBase):
|
|
12
|
+
"""
|
|
13
|
+
gRPC Service for a Generic service
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
RESOURCE_TYPE = ServiceBase
|
|
17
|
+
|
|
18
|
+
async def DoCommand(self, stream: Stream[DoCommandRequest, DoCommandResponse]) -> None:
|
|
19
|
+
request = await stream.recv_message()
|
|
20
|
+
assert request is not None
|
|
21
|
+
name = request.name
|
|
22
|
+
service = self.get_resource(name)
|
|
23
|
+
try:
|
|
24
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
25
|
+
result = await service.do_command(struct_to_dict(request.command), timeout=timeout, metadata=stream.metadata)
|
|
26
|
+
except NotImplementedError:
|
|
27
|
+
raise GRPCError(Status.UNIMPLEMENTED, f"``DO`` command is unimplemented for service named: {name}")
|
|
28
|
+
response = DoCommandResponse(result=dict_to_struct(result))
|
|
29
|
+
await stream.send_message(response)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
try:
|
|
2
|
+
import numpy
|
|
3
|
+
except ImportError:
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
warnings.warn(
|
|
7
|
+
(
|
|
8
|
+
"""MLModel support in the Viam Python SDK requires the installation of an
|
|
9
|
+
additional dependency: numpy. Update your package using the extra [mlmodel]
|
|
10
|
+
for example `pip install viam-sdk[mlmodel]` or the equivalent update in your dependency manager."""
|
|
11
|
+
),
|
|
12
|
+
)
|
|
13
|
+
raise
|
|
14
|
+
|
|
15
|
+
from viam.proto.service.mlmodel import File, LabelType, Metadata, TensorInfo
|
|
16
|
+
from viam.resource.registry import Registry, ResourceRegistration
|
|
17
|
+
|
|
18
|
+
from .client import MLModelClient
|
|
19
|
+
from .mlmodel import MLModel
|
|
20
|
+
from .service import MLModelRPCService
|
|
21
|
+
|
|
22
|
+
__all__ = ["File", "LabelType", "Metadata", "MLModel", "MLModelClient", "TensorInfo"]
|
|
23
|
+
|
|
24
|
+
Registry.register_api(ResourceRegistration(MLModel, MLModelRPCService, lambda name, channel: MLModelClient(name, channel)))
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from typing import Dict, Mapping, Optional
|
|
2
|
+
|
|
3
|
+
from grpclib.client import Channel
|
|
4
|
+
from numpy.typing import NDArray
|
|
5
|
+
|
|
6
|
+
from viam.proto.service.mlmodel import InferRequest, InferResponse, MetadataRequest, MetadataResponse, MLModelServiceStub
|
|
7
|
+
from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase
|
|
8
|
+
from viam.services.mlmodel.utils import flat_tensors_to_ndarrays, ndarrays_to_flat_tensors
|
|
9
|
+
from viam.utils import ValueTypes, dict_to_struct
|
|
10
|
+
|
|
11
|
+
from .mlmodel import Metadata, MLModel
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MLModelClient(MLModel, ReconfigurableResourceRPCClientBase):
|
|
15
|
+
def __init__(self, name: str, channel: Channel):
|
|
16
|
+
self.channel = channel
|
|
17
|
+
self.client = MLModelServiceStub(channel)
|
|
18
|
+
super().__init__(name)
|
|
19
|
+
|
|
20
|
+
async def infer(
|
|
21
|
+
self,
|
|
22
|
+
input_tensors: Dict[str, NDArray],
|
|
23
|
+
*,
|
|
24
|
+
extra: Optional[Mapping[str, ValueTypes]] = None,
|
|
25
|
+
timeout: Optional[float] = None,
|
|
26
|
+
**kwargs,
|
|
27
|
+
) -> Dict[str, NDArray]:
|
|
28
|
+
md = kwargs.get("metadata", self.Metadata()).proto
|
|
29
|
+
request = InferRequest(name=self.name, input_tensors=ndarrays_to_flat_tensors(input_tensors), extra=dict_to_struct(extra))
|
|
30
|
+
response: InferResponse = await self.client.Infer(request, timeout=timeout, metadata=md)
|
|
31
|
+
return flat_tensors_to_ndarrays(response.output_tensors)
|
|
32
|
+
|
|
33
|
+
async def metadata(self, *, extra: Optional[Mapping[str, ValueTypes]] = None, timeout: Optional[float] = None, **kwargs) -> Metadata:
|
|
34
|
+
md = kwargs.get("metadata", self.Metadata()).proto
|
|
35
|
+
request = MetadataRequest(name=self.name, extra=dict_to_struct(extra))
|
|
36
|
+
response: MetadataResponse = await self.client.Metadata(request, timeout=timeout, metadata=md)
|
|
37
|
+
return response.metadata
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
from typing import Dict, Final, Mapping, Optional
|
|
3
|
+
|
|
4
|
+
from numpy.typing import NDArray
|
|
5
|
+
|
|
6
|
+
from viam.proto.service.mlmodel import Metadata
|
|
7
|
+
from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_SERVICE
|
|
8
|
+
from viam.utils import ValueTypes
|
|
9
|
+
|
|
10
|
+
from ..service_base import ServiceBase
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MLModel(ServiceBase):
|
|
14
|
+
"""
|
|
15
|
+
MLModel represents a Machine Learning Model service.
|
|
16
|
+
|
|
17
|
+
This acts as an abstract base class for any drivers representing specific
|
|
18
|
+
arm implementations. This cannot be used on its own. If the ``__init__()`` function is
|
|
19
|
+
overridden, it must call the ``super().__init__()`` function.
|
|
20
|
+
|
|
21
|
+
For more information, see `ML model service <https://docs.viam.com/dev/reference/apis/services/ml/>`_.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
API: Final = API( # pyright: ignore [reportIncompatibleVariableOverride]
|
|
25
|
+
RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_SERVICE, "mlmodel"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
@abc.abstractmethod
|
|
29
|
+
async def infer(
|
|
30
|
+
self,
|
|
31
|
+
input_tensors: Dict[str, NDArray],
|
|
32
|
+
*,
|
|
33
|
+
extra: Optional[Mapping[str, ValueTypes]] = None,
|
|
34
|
+
timeout: Optional[float] = None,
|
|
35
|
+
) -> Dict[str, NDArray]:
|
|
36
|
+
"""Take an already ordered input tensor as an array, make an inference on the model, and return an output tensor map.
|
|
37
|
+
|
|
38
|
+
::
|
|
39
|
+
|
|
40
|
+
import numpy as np
|
|
41
|
+
|
|
42
|
+
my_mlmodel = MLModelClient.from_robot(robot=machine, name="my_mlmodel_service")
|
|
43
|
+
|
|
44
|
+
image_data = np.zeros((1, 384, 384, 3), dtype=np.uint8)
|
|
45
|
+
|
|
46
|
+
# Create the input tensors dictionary
|
|
47
|
+
input_tensors = {
|
|
48
|
+
"image": image_data
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
output_tensors = await my_mlmodel.infer(input_tensors)
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
input_tensors (Dict[str, NDArray]): A dictionary of input flat tensors as specified in the metadata
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Dict[str, NDArray]: A dictionary of output flat tensors as specified in the metadata
|
|
58
|
+
|
|
59
|
+
For more information, see `ML model service <https://docs.viam.com/dev/reference/apis/services/ml/#infer>`_.
|
|
60
|
+
"""
|
|
61
|
+
...
|
|
62
|
+
|
|
63
|
+
@abc.abstractmethod
|
|
64
|
+
async def metadata(self, *, extra: Optional[Mapping[str, ValueTypes]] = None, timeout: Optional[float] = None) -> Metadata:
|
|
65
|
+
"""Get the metadata (such as name, type, expected tensor/array shape, inputs, and outputs) associated with the ML model.
|
|
66
|
+
|
|
67
|
+
::
|
|
68
|
+
|
|
69
|
+
my_mlmodel = MLModelClient.from_robot(robot=machine, name="my_mlmodel_service")
|
|
70
|
+
|
|
71
|
+
metadata = await my_mlmodel.metadata()
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
Metadata: The metadata
|
|
75
|
+
|
|
76
|
+
For more information, see `ML model service <https://docs.viam.com/dev/reference/apis/services/ml/#metadata>`_.
|
|
77
|
+
"""
|
|
78
|
+
...
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from grpclib.server import Stream
|
|
2
|
+
|
|
3
|
+
from viam.proto.service.mlmodel import InferRequest, InferResponse, MetadataRequest, MetadataResponse, MLModelServiceBase
|
|
4
|
+
from viam.resource.rpc_service_base import ResourceRPCServiceBase
|
|
5
|
+
from viam.services.mlmodel.utils import flat_tensors_to_ndarrays, ndarrays_to_flat_tensors
|
|
6
|
+
from viam.utils import struct_to_dict
|
|
7
|
+
|
|
8
|
+
from .mlmodel import MLModel
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MLModelRPCService(MLModelServiceBase, ResourceRPCServiceBase):
|
|
12
|
+
"""
|
|
13
|
+
gRPC service for a ML Model service
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
RESOURCE_TYPE = MLModel
|
|
17
|
+
|
|
18
|
+
async def Infer(self, stream: Stream[InferRequest, InferResponse]) -> None:
|
|
19
|
+
request = await stream.recv_message()
|
|
20
|
+
assert request is not None
|
|
21
|
+
name = request.name
|
|
22
|
+
mlmodel = self.get_resource(name)
|
|
23
|
+
extra = struct_to_dict(request.extra)
|
|
24
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
25
|
+
output_tensors = await mlmodel.infer(input_tensors=flat_tensors_to_ndarrays(request.input_tensors), extra=extra, timeout=timeout)
|
|
26
|
+
response = InferResponse(output_tensors=ndarrays_to_flat_tensors(output_tensors))
|
|
27
|
+
await stream.send_message(response)
|
|
28
|
+
|
|
29
|
+
async def Metadata(self, stream: Stream[MetadataRequest, MetadataResponse]) -> None:
|
|
30
|
+
request = await stream.recv_message()
|
|
31
|
+
assert request is not None
|
|
32
|
+
name = request.name
|
|
33
|
+
mlmodel = self.get_resource(name)
|
|
34
|
+
extra = struct_to_dict(request.extra)
|
|
35
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
36
|
+
metadata = await mlmodel.metadata(extra=extra, timeout=timeout)
|
|
37
|
+
response = MetadataResponse(metadata=metadata)
|
|
38
|
+
await stream.send_message(response)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from typing import Dict
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from numpy.typing import NDArray
|
|
5
|
+
from packaging.version import Version
|
|
6
|
+
|
|
7
|
+
from viam.proto.service.mlmodel import (
|
|
8
|
+
FlatTensor,
|
|
9
|
+
FlatTensorDataDouble,
|
|
10
|
+
FlatTensorDataFloat,
|
|
11
|
+
FlatTensorDataInt8,
|
|
12
|
+
FlatTensorDataInt16,
|
|
13
|
+
FlatTensorDataInt32,
|
|
14
|
+
FlatTensorDataInt64,
|
|
15
|
+
FlatTensorDataUInt8,
|
|
16
|
+
FlatTensorDataUInt16,
|
|
17
|
+
FlatTensorDataUInt32,
|
|
18
|
+
FlatTensorDataUInt64,
|
|
19
|
+
FlatTensors,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def flat_tensors_to_ndarrays(flat_tensors: FlatTensors) -> Dict[str, NDArray]:
|
|
24
|
+
property_name_to_dtype = {
|
|
25
|
+
"float_tensor": np.float32,
|
|
26
|
+
"double_tensor": np.float64,
|
|
27
|
+
"int8_tensor": np.int8,
|
|
28
|
+
"int16_tensor": np.int16,
|
|
29
|
+
"int32_tensor": np.int32,
|
|
30
|
+
"int64_tensor": np.int64,
|
|
31
|
+
"uint8_tensor": np.uint8,
|
|
32
|
+
"uint16_tensor": np.uint16,
|
|
33
|
+
"uint32_tensor": np.uint32,
|
|
34
|
+
"uint64_tensor": np.uint64,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
def make_ndarray(flat_data, dtype, shape):
|
|
38
|
+
"""Takes flat data (protobuf RepeatedScalarFieldContainer | bytes) to output an ndarray
|
|
39
|
+
of appropriate dtype and shape"""
|
|
40
|
+
make_array = np.frombuffer if dtype == np.int8 or dtype == np.uint8 else np.array
|
|
41
|
+
# As per proto, int16 and uint16 are stored as uint32. As of numpy v2, this creates
|
|
42
|
+
# some strange interactions with negative values for int16. Specifically, we end up
|
|
43
|
+
# trying to create an np.Int16 value with an out of bounds int due to rollover.
|
|
44
|
+
# Creating our array as a uint32 array initially and then casting to int16 solves this.
|
|
45
|
+
if Version(np.__version__) >= Version("2") and dtype == np.int16:
|
|
46
|
+
arr = np.astype(make_array(flat_data, np.uint32), np.int16) # pyright: ignore [reportAttributeAccessIssue]
|
|
47
|
+
|
|
48
|
+
else:
|
|
49
|
+
arr = make_array(flat_data, dtype)
|
|
50
|
+
return arr.reshape(shape)
|
|
51
|
+
|
|
52
|
+
ndarrays: Dict[str, NDArray] = dict()
|
|
53
|
+
for name, flat_tensor in flat_tensors.tensors.items():
|
|
54
|
+
property_name = flat_tensor.WhichOneof("tensor") or flat_tensor.WhichOneof(b"tensor")
|
|
55
|
+
if property_name:
|
|
56
|
+
tensor_data = getattr(flat_tensor, property_name)
|
|
57
|
+
flat_data, dtype, shape = tensor_data.data, property_name_to_dtype[property_name], flat_tensor.shape
|
|
58
|
+
ndarrays[name] = make_ndarray(flat_data, dtype, shape)
|
|
59
|
+
return ndarrays
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def ndarrays_to_flat_tensors(ndarrays: Dict[str, NDArray]) -> FlatTensors:
|
|
63
|
+
dtype_name_to_tensor_data_class = {
|
|
64
|
+
"float32": FlatTensorDataFloat,
|
|
65
|
+
"float64": FlatTensorDataDouble,
|
|
66
|
+
"int8": FlatTensorDataInt8,
|
|
67
|
+
"int16": FlatTensorDataInt16,
|
|
68
|
+
"int32": FlatTensorDataInt32,
|
|
69
|
+
"int64": FlatTensorDataInt64,
|
|
70
|
+
"uint8": FlatTensorDataUInt8,
|
|
71
|
+
"uint16": FlatTensorDataUInt16,
|
|
72
|
+
"uint32": FlatTensorDataUInt32,
|
|
73
|
+
"uint64": FlatTensorDataUInt64,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
def get_tensor_data(ndarray: NDArray):
|
|
77
|
+
"""Takes an ndarray and returns the corresponding tensor data class instance
|
|
78
|
+
for example FlatTensorDataInt8, FlatTensorDataUInt8 etc."""
|
|
79
|
+
tensor_data_class = dtype_name_to_tensor_data_class[ndarray.dtype.name]
|
|
80
|
+
data = ndarray.flatten()
|
|
81
|
+
if tensor_data_class == FlatTensorDataInt8 or tensor_data_class == FlatTensorDataUInt8:
|
|
82
|
+
data = data.tobytes() # as per the proto, int8 and uint8 are stored as bytes
|
|
83
|
+
elif tensor_data_class == FlatTensorDataInt16 or tensor_data_class == FlatTensorDataUInt16:
|
|
84
|
+
data = data.astype(np.uint32) # as per the proto, int16 and uint16 are stored as uint32
|
|
85
|
+
tensor_data = tensor_data_class(data=data)
|
|
86
|
+
return tensor_data
|
|
87
|
+
|
|
88
|
+
def get_tensor_data_type(ndarray: NDArray):
|
|
89
|
+
"""Takes ndarray and returns a FlatTensor datatype property to be set
|
|
90
|
+
for example "float_tensor", "uint32_tensor" etc."""
|
|
91
|
+
if ndarray.dtype == np.float32:
|
|
92
|
+
return "float_tensor"
|
|
93
|
+
elif ndarray.dtype == np.float64:
|
|
94
|
+
return "double_tensor"
|
|
95
|
+
return f"{ndarray.dtype.name}_tensor"
|
|
96
|
+
|
|
97
|
+
tensors_mapping: Dict[str, FlatTensor] = dict()
|
|
98
|
+
for name, ndarray in ndarrays.items():
|
|
99
|
+
prop_name, prop_value = get_tensor_data_type(ndarray), get_tensor_data(ndarray)
|
|
100
|
+
tensors_mapping[name] = FlatTensor(shape=ndarray.shape, **{prop_name: prop_value})
|
|
101
|
+
return FlatTensors(tensors=tensors_mapping)
|