bosdyn-client 4.1.1__py3-none-any.whl → 5.0.1__py3-none-any.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.
Files changed (33) hide show
  1. bosdyn/client/__init__.py +1 -0
  2. bosdyn/client/audio_visual.py +339 -0
  3. bosdyn/client/audio_visual_helpers.py +112 -0
  4. bosdyn/client/command_line.py +15 -7
  5. bosdyn/client/data_acquisition_helpers.py +1 -1
  6. bosdyn/client/data_acquisition_store.py +2 -2
  7. bosdyn/client/directory_registration.py +34 -5
  8. bosdyn/client/error_callback_result.py +29 -0
  9. bosdyn/client/gps/NMEAParser.py +16 -6
  10. bosdyn/client/gps/gps_listener.py +31 -1
  11. bosdyn/client/gps/ntrip_client.py +240 -0
  12. bosdyn/client/graph_nav.py +16 -1
  13. bosdyn/client/gripper_camera_param.py +40 -0
  14. bosdyn/client/image.py +16 -0
  15. bosdyn/client/image_service_helpers.py +88 -68
  16. bosdyn/client/keepalive.py +37 -8
  17. bosdyn/client/log_status.py +6 -0
  18. bosdyn/client/math_helpers.py +18 -0
  19. bosdyn/client/payload_registration.py +40 -6
  20. bosdyn/client/payload_software_update.py +185 -0
  21. bosdyn/client/payload_software_update_initiation.py +79 -0
  22. bosdyn/client/point_cloud.py +9 -0
  23. bosdyn/client/robot.py +9 -4
  24. bosdyn/client/sdk.py +4 -2
  25. bosdyn/client/service_customization_helpers.py +19 -6
  26. bosdyn/client/spot_cam/__init__.py +2 -0
  27. bosdyn/client/spot_cam/ptz.py +20 -24
  28. bosdyn/client/token_manager.py +56 -27
  29. bosdyn/client/util.py +1 -1
  30. {bosdyn_client-4.1.1.dist-info → bosdyn_client-5.0.1.dist-info}/METADATA +4 -4
  31. {bosdyn_client-4.1.1.dist-info → bosdyn_client-5.0.1.dist-info}/RECORD +33 -27
  32. {bosdyn_client-4.1.1.dist-info → bosdyn_client-5.0.1.dist-info}/WHEEL +0 -0
  33. {bosdyn_client-4.1.1.dist-info → bosdyn_client-5.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,79 @@
1
+ # Copyright (c) 2023 Boston Dynamics, Inc. All rights reserved.
2
+ #
3
+ # Downloading, reproducing, distributing or otherwise using the SDK Software
4
+ # is subject to the terms and conditions of the Boston Dynamics Software
5
+ # Development Kit License (20191101-BDSDK-SL).
6
+
7
+ """Payload software update initiation gRPC client.
8
+
9
+ This client uses an insecure channel for signaling to a payload that it should
10
+ send its version information or initiate a software update.
11
+ """
12
+
13
+ from bosdyn.api.payload_software_update_initiation_pb2 import (
14
+ TriggerInitiateUpdateRequest, TriggerSendPayloadSoftwareInfoRequest)
15
+ from bosdyn.api.payload_software_update_initiation_service_pb2_grpc import \
16
+ PayloadSoftwareUpdateInitiationServiceStub
17
+ from bosdyn.client.common import BaseClient
18
+
19
+
20
+ class PayloadSoftwareUpdateInitiationClient(BaseClient):
21
+ """A client used to direct a payload to send its version information or start an update."""
22
+
23
+ def __init__(self):
24
+ super(PayloadSoftwareUpdateInitiationClient,
25
+ self).__init__(PayloadSoftwareUpdateInitiationServiceStub)
26
+
27
+ default_service_name = 'payload-software-update-initiation'
28
+ service_type = 'bosdyn.api.PayloadSoftwareUpdateInitiationService'
29
+
30
+ def trigger_send_payload_software_info(self, **kwargs):
31
+ """Tell a payload to send its current version information to Spot.
32
+
33
+ Returns:
34
+ TriggerSendPayloadSoftwareInfoResponse: The response object from the payload. Currently
35
+ this message is empty.
36
+
37
+ Raises:
38
+ RpcError: Problem communicating with the payload.
39
+ """
40
+ return self.call(self._stub.TriggerSendPayloadSoftwareInfo,
41
+ TriggerSendPayloadSoftwareInfoRequest(), **kwargs)
42
+
43
+ def trigger_send_payload_software_info_async(self, **kwargs):
44
+ """Async version of trigger_send_payload_software_info().
45
+
46
+ Returns:
47
+ TriggerSendPayloadSoftwareInfoResponse: The response object from the payload. Currently
48
+ this message is empty.
49
+
50
+ Raises:
51
+ RpcError: Problem communicating with the payload.
52
+ """
53
+ return self.call_async(self._stub.TriggerSendPayloadSoftwareInfo,
54
+ TriggerSendPayloadSoftwareInfoRequest(), **kwargs)
55
+
56
+ def trigger_initiate_update(self, **kwargs):
57
+ """Tell a payload to initiate its software update logic.
58
+
59
+ Returns:
60
+ TriggerInitiateUpdateResponse: The response object from the payload. Currently this
61
+ message is empty.
62
+
63
+ Raises:
64
+ RpcError: Problem communicating with the payload.
65
+ """
66
+ return self.call(self._stub.TriggerInitiateUpdate, TriggerInitiateUpdateRequest(), **kwargs)
67
+
68
+ def trigger_initiate_update_async(self, **kwargs):
69
+ """Async version of trigger_initiate_update().
70
+
71
+ Returns:
72
+ TriggerInitiateUpdateResponse: The response object from the payload. Currently this
73
+ message is empty.
74
+
75
+ Raises:
76
+ RpcError: Problem communicating with the payload.
77
+ """
78
+ return self.call_async(self._stub.TriggerInitiateUpdate, TriggerInitiateUpdateRequest(),
79
+ **kwargs)
@@ -39,6 +39,10 @@ class PointCloudDataError(PointCloudResponseError):
39
39
  """System cannot generate point cloud data at this time."""
40
40
 
41
41
 
42
+ class PointCloudTypeError(PointCloudResponseError):
43
+ """System cannot generate point cloud with the request cloud_type."""
44
+
45
+
42
46
  _STATUS_TO_ERROR = collections.defaultdict(lambda: (PointCloudResponseError, None))
43
47
  _STATUS_TO_ERROR.update({
44
48
  point_cloud_protos.PointCloudResponse.STATUS_OK: (None, None),
@@ -50,6 +54,8 @@ _STATUS_TO_ERROR.update({
50
54
  error_pair(UnsetStatusError),
51
55
  point_cloud_protos.PointCloudResponse.STATUS_POINT_CLOUD_DATA_ERROR:
52
56
  error_pair(PointCloudDataError),
57
+ point_cloud_protos.PointCloudResponse.STATUS_UNSUPPORTED_CLOUD_TYPE:
58
+ error_pair(PointCloudTypeError),
53
59
  })
54
60
 
55
61
 
@@ -66,6 +72,8 @@ def _error_from_response(response):
66
72
  return None
67
73
 
68
74
 
75
+
76
+
69
77
  class PointCloudClient(BaseClient):
70
78
  """A client handling point clouds."""
71
79
 
@@ -177,6 +185,7 @@ class PointCloudClient(BaseClient):
177
185
  return point_cloud_protos.ListPointCloudSourcesRequest()
178
186
 
179
187
 
188
+
180
189
  def build_pc_request(point_cloud_source_name):
181
190
  """Helper function which builds an PointCloudRequest from a point cloud source name.
182
191
 
bosdyn/client/robot.py CHANGED
@@ -131,6 +131,10 @@ class Robot(object):
131
131
  self._time_sync_thread = None
132
132
  self.executor = None
133
133
 
134
+ #: Callable[[Exception], ErrorCallbackResult] | None: Optional callback to be invoked when
135
+ #: an error occurs in the token refresh thread.
136
+ self.token_refresh_error_callback = None
137
+
134
138
  # Set default max message length for sending and receiving. These values are used when
135
139
  # creating channels.
136
140
  self.max_send_message_length = DEFAULT_MAX_MESSAGE_LENGTH
@@ -385,7 +389,7 @@ class Robot(object):
385
389
  self.update_user_token(user_token, username)
386
390
 
387
391
  def authenticate_from_payload_credentials(self, guid, secret, payload_registration_client=None,
388
- timeout=None):
392
+ timeout=None, retry_interval=1.0):
389
393
  """Authenticate to this Robot with the guid/secret of the hosting payload.
390
394
 
391
395
  This call is used to authenticate to a robot using payload credentials. If a payload is
@@ -413,7 +417,7 @@ class Robot(object):
413
417
  self.logger.warning(
414
418
  'Payload is not authorized. Authentication will block until an'
415
419
  ' operator authorizes the payload in the Admin Console.')
416
- time.sleep(0.1)
420
+ time.sleep(retry_interval)
417
421
  self.update_user_token(user_token)
418
422
 
419
423
  def update_user_token(self, user_token, username=None):
@@ -467,7 +471,8 @@ class Robot(object):
467
471
  return self.service_type_by_name
468
472
 
469
473
 
470
- def register_payload_and_authenticate(self, payload, secret, timeout=None):
474
+ def register_payload_and_authenticate(self, payload, secret, timeout=None,
475
+ auth_retry_interval=1.0):
471
476
  """Register a payload with the robot and request a user_token.
472
477
 
473
478
  This method will block until the payload is authorized by an operator in the robot webpage.
@@ -486,7 +491,7 @@ class Robot(object):
486
491
  pass
487
492
  self.authenticate_from_payload_credentials(
488
493
  payload.GUID, secret, payload_registration_client=payload_registration_client,
489
- timeout=timeout)
494
+ timeout=timeout, retry_interval=auth_retry_interval)
490
495
 
491
496
  def start_time_sync(self, time_sync_interval_sec=None):
492
497
  """Start time sync thread if needed.
bosdyn/client/sdk.py CHANGED
@@ -8,13 +8,13 @@
8
8
 
9
9
  import datetime
10
10
  import glob
11
+ import importlib.resources
11
12
  import logging
12
13
  import os
13
14
  import platform
14
15
  from enum import Enum
15
16
 
16
17
  import jwt
17
- import pkg_resources
18
18
  from deprecated.sphinx import deprecated
19
19
 
20
20
  from .arm_surface_contact import ArmSurfaceContactClient
@@ -178,6 +178,8 @@ def create_standard_sdk(client_name_prefix, service_clients=None, cert_resource_
178
178
 
179
179
 
180
180
 
181
+
182
+
181
183
  class Sdk(object):
182
184
  """Repository for settings typically common to a single developer and/or robot fleet.
183
185
  See also Robot for robot-specific settings.
@@ -281,7 +283,7 @@ class Sdk(object):
281
283
  """
282
284
  self.cert = None
283
285
  if resource_path_glob is None:
284
- self.cert = pkg_resources.resource_stream('bosdyn.client.resources', 'robot.pem').read()
286
+ self.cert = importlib.resources.read_binary('bosdyn.client.resources', 'robot.pem')
285
287
  else:
286
288
  cert_paths = [c for c in glob.glob(resource_path_glob) if os.path.isfile(c)]
287
289
  if not cert_paths:
@@ -356,7 +356,7 @@ class _StringParamValidator(_ParamValidatorInterface):
356
356
  if err:
357
357
  return err
358
358
 
359
- if len(self.param_spec.options) > 0:
359
+ if not self.param_spec.editable and len(self.param_spec.options) > 0:
360
360
  if param_value.value not in self.param_spec.options:
361
361
  return CustomParamError(
362
362
  status=CustomParamError.STATUS_INVALID_VALUE, error_messages=[
@@ -404,6 +404,10 @@ class _RegionOfInterestParamValidator(_ParamValidatorInterface):
404
404
  if self.param_spec.default_area.rectangle:
405
405
  raise InvalidCustomParamSpecError(
406
406
  ["Default area is a rectangle despite not being allowed"])
407
+ if not self.param_spec.allows_polygon:
408
+ if len(self.param_spec.default_area.polygon.vertices) > 0:
409
+ raise InvalidCustomParamSpecError(
410
+ ["Default area is a polygon despite not being allowed"])
407
411
 
408
412
  def validate_value(self, param_value):
409
413
  err = check_types_match(param_value, self.proto_type)
@@ -415,6 +419,13 @@ class _RegionOfInterestParamValidator(_ParamValidatorInterface):
415
419
  return CustomParamError(
416
420
  status=CustomParamError.STATUS_INVALID_VALUE,
417
421
  error_messages=["Chosen area is a rectangle despite not being allowed"])
422
+
423
+ if not self.param_spec.allows_polygon:
424
+ if len(param_value.area.polygon.vertices) > 0:
425
+ return CustomParamError(
426
+ status=CustomParamError.STATUS_INVALID_VALUE,
427
+ error_messages=["Chosen area is a polygon despite not being allowed"])
428
+
418
429
  if param_value.image_cols < 0:
419
430
  return CustomParamError(status=CustomParamError.STATUS_INVALID_VALUE,
420
431
  error_messages=["Number of columns in image must be positive"])
@@ -1165,10 +1176,10 @@ def make_bool_param_spec(default_value: Optional[bool] = None) -> BoolParam.Spec
1165
1176
  return spec
1166
1177
 
1167
1178
 
1168
- def make_region_of_interest_param_spec(
1169
- service_and_source: Optional[RegionOfInterestParam.ServiceAndSource] = None,
1170
- default_area: Optional[AreaI] = None,
1171
- allows_rectangle: bool = False) -> RegionOfInterestParam.Spec:
1179
+ def make_region_of_interest_param_spec(service_and_source: Optional[
1180
+ RegionOfInterestParam.ServiceAndSource] = None, default_area: Optional[AreaI] = None,
1181
+ allows_rectangle: bool = False,
1182
+ allows_polygon: bool = False) -> RegionOfInterestParam.Spec:
1172
1183
  """
1173
1184
  Helper function to create a RegionOfInterestParam.Spec
1174
1185
 
@@ -1176,10 +1187,12 @@ def make_region_of_interest_param_spec(
1176
1187
  service_and_source: service and source to which the RegionOfInterestParam should adhere
1177
1188
  default_area: starting area for the RegionOfInterestParam
1178
1189
  allows_rectangle: whether a rectangle may be drawn for the selected area
1190
+ allows_polygon: whether a polygon may be drawn for the selected area
1179
1191
  """
1180
1192
  return RegionOfInterestParam.Spec(default_area=default_area,
1181
1193
  service_and_source=service_and_source,
1182
- allows_rectangle=allows_rectangle)
1194
+ allows_rectangle=allows_rectangle,
1195
+ allows_polygon=allows_polygon)
1183
1196
 
1184
1197
 
1185
1198
 
@@ -8,6 +8,8 @@ from . import (audio, compositor, health, lighting, media_log, network, power, p
8
8
  version)
9
9
 
10
10
 
11
+ IMAGE_SERVICE_NAME = 'spot-cam-image'
12
+
11
13
  CLIENTS = [
12
14
  audio.AudioClient,
13
15
  compositor.CompositorClient,
@@ -159,18 +159,7 @@ class PtzClient(BaseClient):
159
159
  Returns:
160
160
  SetPtzFocusStateResponse indicating whether the call was successful
161
161
  """
162
-
163
- if focus_position is not None:
164
- focus_position_val = Int32Value(value=focus_position)
165
- approx_distance = None
166
- elif distance is not None:
167
- approx_distance = FloatValue(value=distance)
168
- focus_position_val = None
169
- else:
170
- raise ValueError("One of distance or focus_position must be specified.")
171
-
172
- ptz_focus_state = ptz_pb2.PtzFocusState(mode=focus_mode, approx_distance=approx_distance,
173
- focus_position=focus_position_val)
162
+ ptz_focus_state = create_focus_state(focus_mode, distance, focus_position)
174
163
  request = ptz_pb2.SetPtzFocusStateRequest(focus_state=ptz_focus_state)
175
164
  return self.call(self._stub.SetPtzFocusState, request,
176
165
  self._set_ptz_focus_state_from_response, common_header_errors,
@@ -178,18 +167,7 @@ class PtzClient(BaseClient):
178
167
 
179
168
  def set_ptz_focus_state_async(self, focus_mode, distance=None, focus_position=None, **kwargs):
180
169
  """Async version of set_ptz_focus_state()"""
181
-
182
- if focus_position is not None:
183
- focus_position_val = Int32Value(value=focus_position)
184
- approx_distance = None
185
- elif distance is not None:
186
- approx_distance = FloatValue(value=distance)
187
- focus_position_val = None
188
- else:
189
- raise ValueError("One of distance or focus_position must be specified.")
190
-
191
- ptz_focus_state = ptz_pb2.PtzFocusState(mode=focus_mode, approx_distance=approx_distance,
192
- focus_position=focus_position_val)
170
+ ptz_focus_state = create_focus_state(focus_mode, distance, focus_position)
193
171
  request = ptz_pb2.SetPtzFocusStateRequest(focus_state=ptz_focus_state)
194
172
  return self.call_async(self._stub.SetPtzFocusState, request,
195
173
  self._set_ptz_focus_state_from_response, common_header_errors,
@@ -232,3 +210,21 @@ class PtzClient(BaseClient):
232
210
  def shift_pan_angle(pan):
233
211
  """Shift the pan angle (degrees) so that it is in the [0,360] range."""
234
212
  return recenter_value_mod(pan, 180, 360)
213
+
214
+
215
+ def create_focus_state(focus_mode, distance=None, focus_position=None):
216
+ """Generate a focus state proto."""
217
+ approx_distance = None
218
+ focus_position_val = None
219
+ if focus_mode == ptz_pb2.PtzFocusState.PTZ_FOCUS_MANUAL:
220
+ if focus_position is not None:
221
+ focus_position_val = Int32Value(value=focus_position)
222
+ approx_distance = None
223
+ elif distance is not None:
224
+ approx_distance = FloatValue(value=distance)
225
+ focus_position_val = None
226
+ else:
227
+ raise ValueError("One of distance or focus_position must be specified.")
228
+
229
+ return ptz_pb2.PtzFocusState(mode=focus_mode, approx_distance=approx_distance,
230
+ focus_position=focus_position_val)
@@ -14,11 +14,15 @@ import logging
14
14
  import threading
15
15
 
16
16
  from .auth import InvalidTokenError
17
- from .exceptions import ResponseError, RpcError
17
+ from .error_callback_result import ErrorCallbackResult
18
+ from .exceptions import ResponseError, RpcError, TimedOutError
18
19
  from .token_cache import WriteFailedError
19
20
 
20
21
  _LOGGER = logging.getLogger(__name__)
21
22
 
23
+ USER_TOKEN_REFRESH_TIME_DELTA = datetime.timedelta(hours=1)
24
+ USER_TOKEN_RETRY_INTERVAL_START = datetime.timedelta(seconds=1)
25
+
22
26
 
23
27
  class TokenManager:
24
28
  """Refreshes the user token in the robot object.
@@ -26,10 +30,13 @@ class TokenManager:
26
30
  The refresh policy assumes the token is minted and then the manager is
27
31
  launched."""
28
32
 
29
- def __init__(self, robot, timestamp=None):
33
+ def __init__(self, robot, timestamp=None, refresh_interval=USER_TOKEN_REFRESH_TIME_DELTA,
34
+ initial_retry_interval=USER_TOKEN_RETRY_INTERVAL_START):
30
35
  self.robot = robot
31
36
 
32
37
  self._last_timestamp = timestamp or datetime.datetime.now()
38
+ self._refresh_interval = refresh_interval
39
+ self._initial_retry_seconds = initial_retry_interval
33
40
 
34
41
  # Daemon threads can still run during shutdown after python has
35
42
  # started to clear out things in globals().
@@ -51,33 +58,55 @@ class TokenManager:
51
58
 
52
59
  def update(self):
53
60
  """Refresh the user token as needed."""
54
- USER_TOKEN_REFRESH_TIME_DELTA = datetime.timedelta(hours=1)
55
- USER_TOKEN_RETRY_INTERVAL_START = datetime.timedelta(seconds=1)
56
-
57
- retry_interval = USER_TOKEN_RETRY_INTERVAL_START
58
- while not self._exit_thread.is_set():
59
- elapsed_time = datetime.datetime.now() - self._last_timestamp
60
- if elapsed_time >= USER_TOKEN_REFRESH_TIME_DELTA:
61
- try:
62
- self.robot.authenticate_with_token(self.robot.user_token)
63
- except WriteFailedError:
64
- _LOGGER.exception(
65
- "Failed to save the token to the cache. Continuing without caching.")
66
- except (InvalidTokenError, ResponseError, RpcError):
67
- _LOGGER.exception("Error refreshing the token. Retry in %s", retry_interval)
68
-
69
- # Exponential back-off on retrying
70
- self._exit_thread.wait(retry_interval.seconds)
71
- retry_interval = min(2 * retry_interval, USER_TOKEN_REFRESH_TIME_DELTA)
72
- continue
73
-
74
- retry_interval = USER_TOKEN_RETRY_INTERVAL_START
75
-
76
- # Wait until the specified time or get interrupted by user.
61
+ retry_interval = self._initial_retry_seconds
62
+ wait_time = min(self._refresh_interval - (datetime.datetime.now() - self._last_timestamp),
63
+ self._refresh_interval)
64
+
65
+ while not self._exit_thread.wait(wait_time.total_seconds()):
66
+ start_time = datetime.datetime.now()
67
+ action = ErrorCallbackResult.RESUME_NORMAL_OPERATION
68
+ try:
69
+ self.robot.authenticate_with_token(self.robot.user_token)
77
70
  self._last_timestamp = datetime.datetime.now()
78
- elapsed_time = USER_TOKEN_REFRESH_TIME_DELTA
71
+ except WriteFailedError:
72
+ _LOGGER.exception(
73
+ "Failed to save the token to the cache. Continuing without caching.")
74
+ except (InvalidTokenError, ResponseError, RpcError) as exc:
75
+ _LOGGER.exception("Error refreshing the token.")
76
+ # Default course of action is to retry with a back-off, unless the application
77
+ # supplied callback directs us to do otherwise.
78
+ action = ErrorCallbackResult.RETRY_WITH_EXPONENTIAL_BACK_OFF
79
+ # If the application provided a callback and the error was encountered while
80
+ # refreshing the token, invoke the callback so that the application can take
81
+ # appropriate action.
82
+ if self.robot.token_refresh_error_callback is not None and not isinstance(
83
+ exc, TimedOutError):
84
+ try:
85
+ action = self.robot.token_refresh_error_callback(exc)
86
+ except Exception: #pylint: disable=broad-except
87
+ _LOGGER.exception(
88
+ "Exception thrown in the provided token refresh error callback")
89
+ if action == ErrorCallbackResult.RESUME_NORMAL_OPERATION:
90
+ _LOGGER.warning("Refreshing token in %s", self._refresh_interval)
91
+
92
+ elapsed = datetime.datetime.now() - start_time
93
+ if action == ErrorCallbackResult.ABORT:
94
+ _LOGGER.warning(
95
+ "Application-supplied callback directed the token refresh loop to exit.")
96
+ break
97
+ elif action == ErrorCallbackResult.RETRY_IMMEDIATELY:
98
+ _LOGGER.warning("Retrying to refresh token immediately.")
99
+ wait_time = datetime.timedelta(seconds=0)
100
+ elif action == ErrorCallbackResult.RESUME_NORMAL_OPERATION:
101
+ wait_time = self._refresh_interval - elapsed
102
+ retry_interval = self._initial_retry_seconds
103
+ else:
104
+ # action doesn't match one of the enum values or is one of
105
+ # RETRY_WITH_EXPONENTIAL_BACK_OFF or DEFAULT_ACTION
106
+ _LOGGER.warning("Retrying token refresh in %s", retry_interval)
107
+ wait_time = retry_interval - elapsed
108
+ retry_interval = min(2 * retry_interval, self._refresh_interval)
79
109
 
80
- self._exit_thread.wait(elapsed_time.seconds)
81
110
  message = 'Shutting down monitoring of token belonging to robot {}'.format(
82
111
  self.robot.address)
83
112
  _LOGGER.debug(message)
bosdyn/client/util.py CHANGED
@@ -389,7 +389,7 @@ def add_service_endpoint_arguments(parser):
389
389
 
390
390
  def safe_pb_enum_to_string(value, pb_enum_obj):
391
391
  """Safe wrapper to convert a protobuf enum object to its string representation.
392
- Avoids throughing an exception if the status is unknown by the enum object.
392
+ Avoids throwing an exception if the status is unknown by the enum object.
393
393
 
394
394
  Args:
395
395
  value: The enum value to convert
@@ -1,22 +1,22 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bosdyn-client
3
- Version: 4.1.1
3
+ Version: 5.0.1
4
4
  Summary: Boston Dynamics API client code and interfaces
5
5
  Home-page: https://dev.bostondynamics.com/
6
6
  Author: Boston Dynamics
7
7
  Author-email: support@bostondynamics.com
8
8
  Project-URL: Documentation, https://dev.bostondynamics.com/
9
9
  Project-URL: Source, https://github.com/boston-dynamics/spot-sdk/
10
- Classifier: Programming Language :: Python :: 3.6
11
10
  Classifier: Programming Language :: Python :: 3.7
12
11
  Classifier: Programming Language :: Python :: 3.8
13
12
  Classifier: Programming Language :: Python :: 3.9
14
13
  Classifier: Programming Language :: Python :: 3.10
15
14
  Classifier: License :: Other/Proprietary License
16
15
  Classifier: Operating System :: OS Independent
16
+ Requires-Python: >=3.7
17
17
  Description-Content-Type: text/markdown
18
- Requires-Dist: bosdyn-api (==4.1.1)
19
- Requires-Dist: bosdyn-core (==4.1.1)
18
+ Requires-Dist: bosdyn-api (==5.0.1)
19
+ Requires-Dist: bosdyn-core (==5.0.1)
20
20
  Requires-Dist: grpcio
21
21
  Requires-Dist: pyjwt
22
22
  Requires-Dist: numpy
@@ -1,5 +1,5 @@
1
1
  bosdyn/__init__.py,sha256=CMQioQKK1NlMk3kZuY49b_Aw-JyvDeOtuqOCAul1I0s,330
2
- bosdyn/client/__init__.py,sha256=EtinCbRF6c1BFlxRGFKGtcSSzYQQpBjnHTHOXBXxNLM,1312
2
+ bosdyn/client/__init__.py,sha256=PsouppDAVJC_29ETHUpDsGg6LWI6QDYIcQdFZGncWq4,1313
3
3
  bosdyn/client/__main__.py,sha256=g__h-0z_Q6yzuiXdHQQTh9AI3C2cSc3PocpvbLVwa3E,466
4
4
  bosdyn/client/area_callback.py,sha256=nQnhJR8-f0PMq9uILpKhYitVuIZHl6VViUDndN2K4u8,6270
5
5
  bosdyn/client/area_callback_region_handler_base.py,sha256=cr5SwGogXmuMbAbbMeHvQZQBflYyFTOCj7wrUOgsUHQ,16467
@@ -8,78 +8,84 @@ bosdyn/client/area_callback_service_servicer.py,sha256=o1kYKV83Q-ud-_rmT17XTSqBd
8
8
  bosdyn/client/area_callback_service_utils.py,sha256=R8ljJe8fPszMI6RyuGRyv_QGu63kw1yZAveZydlpERI,5858
9
9
  bosdyn/client/arm_surface_contact.py,sha256=DRfPfsFEzfk6ufe080ViqasUefl2ZUtcvcNENgcf55k,3710
10
10
  bosdyn/client/async_tasks.py,sha256=gEPev6_jaUCe-G5PqktMiMGb7ohDy0daunxzQD5jafg,5594
11
+ bosdyn/client/audio_visual.py,sha256=yfGy7qL6WRvYPE_gAzBJLzQ8Aucc_u5Hkb_L8fJ-Jyc,14230
12
+ bosdyn/client/audio_visual_helpers.py,sha256=9qksn7epH5jBdbwa6VVMcm2mn8HCVtJuSW1C847Jo6w,4499
11
13
  bosdyn/client/auth.py,sha256=YLo6jP0Ssl_Z6rHtTiPiKUNIweDRYub9w3iHdUe6n40,5302
12
14
  bosdyn/client/auto_return.py,sha256=kqT1gaaneLYIPFVAFzpvTHRwa8NYYQ2OBf7wViBQudE,5598
13
15
  bosdyn/client/autowalk.py,sha256=e57FcAC4fu2BPD57Yy4j1F8DPIPPic0Qt1E0UM-oZWo,5734
14
16
  bosdyn/client/bddf.py,sha256=ok_2JcflSCQfcM25lpEgzKnkEJl0FDcJ16Bgo9Rjyzc,1763
15
17
  bosdyn/client/bddf_download.py,sha256=oDztm-aS5J_ABLb-cxomNtwNPrdlnFp8hEuOMVxVRH4,7586
16
18
  bosdyn/client/channel.py,sha256=voNa-3S6LXsTlsXPXPLEoqNxYl2Xx5CNP7w9EELEtdY,8840
17
- bosdyn/client/command_line.py,sha256=0f5ALKTQB1dR7xegHQk0GLTExwkrFCeiTZJkIpEAetA,98595
19
+ bosdyn/client/command_line.py,sha256=lg5lhCAOP4Zgt6At8wis21_O2NB_SbGLL6MR22eIHL4,98748
18
20
  bosdyn/client/common.py,sha256=n4iTcdLCWTS9k0iH8_qrQAOhryqWjSfoEIgiBynjhOY,24997
19
21
  bosdyn/client/data_acquisition.py,sha256=jd3XvrktXsGUh3mlL4zMzs6zSvynayVE2_GodnYgFH4,15226
20
- bosdyn/client/data_acquisition_helpers.py,sha256=4eB0N2IEwhBm3LVp5d_ni2CkpYu3wTtkVS0k7qhYm2M,14805
22
+ bosdyn/client/data_acquisition_helpers.py,sha256=j6nTxk9QP4AsiYX9LPf0g2qDmBf-NU61kC2zZpbEBdA,14805
21
23
  bosdyn/client/data_acquisition_plugin.py,sha256=5IG2IYkL5FDPZhPRB8caoBjx34f63Eem5u5oZTHBaxo,6690
22
24
  bosdyn/client/data_acquisition_plugin_service.py,sha256=tzUBUg9LVPKvDpgogTqEzkhVdlxvHds2HdxRdNDfIJQ,28217
23
- bosdyn/client/data_acquisition_store.py,sha256=AeBUbgvybUCT7ROOwhvanN-fTKu6fH3ifvaxIRqOQHk,19647
25
+ bosdyn/client/data_acquisition_store.py,sha256=n7MUM5LLSzRJ7zC13d4pXCN-gbkduMYkt7YXU2syc1s,19647
24
26
  bosdyn/client/data_buffer.py,sha256=Ta-7CCoy_-StzXDm8cLIjvOnMDgKEzKFc9mcDmVkubc,26661
25
27
  bosdyn/client/data_chunk.py,sha256=6xq9zqLD-JH72ZxzEQEKYqhXvb34TlcZoeqAYaXRxCw,1959
26
28
  bosdyn/client/data_service.py,sha256=aKfXJCciJ2M2WZRKfdWiLS2n-UEKWSRkOgcTnArbc5o,5201
27
29
  bosdyn/client/directory.py,sha256=jWBxnPzBJSrfr4fuLf2VuZGsxOo8Q5iX5tEw6Zx2VY0,4906
28
- bosdyn/client/directory_registration.py,sha256=tO-OMVYrFr1tU3oVifoFcbjW_EIXWo6bdsdvS_Gr7RA,19101
30
+ bosdyn/client/directory_registration.py,sha256=SV2xWly0Zu1XaWhyJ9eqXYeWSjFbwfyFmup_RjR3Cdw,20806
29
31
  bosdyn/client/docking.py,sha256=hYwZNIir3_pt-WvMFiXzMqDCwW8nA5H1BYOUD6_3-00,17596
30
32
  bosdyn/client/door.py,sha256=dbBuGcuoZL3gRhxTQoQHKDlnzcML8ELBtQxCQqomYpo,3110
33
+ bosdyn/client/error_callback_result.py,sha256=B3O9D8ceV1ZsS19UvguISlbvJSjtQ1aZfktVuekZXLU,1317
31
34
  bosdyn/client/estop.py,sha256=-dy3SP6lcOryyTB_VXe0C_cFk-qK1TNJdSm9DKSz-MM,32073
32
35
  bosdyn/client/exceptions.py,sha256=VQg5cSrzB9_pmFcUCbBaRF2QtBUKfdzpR94N3q2rNx0,5323
33
36
  bosdyn/client/fault.py,sha256=ymo4M1Vy-bUasD8uOm1pxE1HnjheCds6qA9hZiJbAzY,6050
34
37
  bosdyn/client/frame_helpers.py,sha256=Rrm0Zx10LoaVsJv-FPCX02LVQwNkyKVO28lZz7Bmlvg,12572
35
- bosdyn/client/graph_nav.py,sha256=E1Qpvhfx4hj-h-QnonmWxahwiSNAOxa54jBdOMQgsC4,69570
36
- bosdyn/client/gripper_camera_param.py,sha256=QKkHrA08c-BRhyLHrE4pDdh8AGUytoq6OABZpqsvVB0,2631
37
- bosdyn/client/image.py,sha256=UepSlmgZhHD-GJeYKclStkExHNZ6_n4gCzqQxB4nJTQ,21355
38
- bosdyn/client/image_service_helpers.py,sha256=u8sCev4slrz593m02RxPrMV9Kdns06xrspJkTIFHe9E,39374
38
+ bosdyn/client/graph_nav.py,sha256=8sULbBAFaFxJPF3ZdI_kqLYpzA0XbhGO-zECRyVH1J4,70681
39
+ bosdyn/client/gripper_camera_param.py,sha256=kxhBffjbq5R-t1OxWEAFguo_tKW5xGIuasdflSmfAwY,4683
40
+ bosdyn/client/image.py,sha256=fn41QOvaAOH7UT7m2ENXayI4fLXg5NQBZrmpLFZVBBE,21980
41
+ bosdyn/client/image_service_helpers.py,sha256=l2hZKqcG7PI05-_bhh8BLkpN4METmG53JCR0YF3q-8Y,40421
39
42
  bosdyn/client/inverse_kinematics.py,sha256=KBgvGdnt-JZJvDzbdJ72Kqw8RHoOsqKq_p9rQtvwuKo,1708
40
43
  bosdyn/client/ir_enable_disable.py,sha256=6c5MAuO1Fj0RlVcjkP1vhs-qTLiOpM3RnD8F7_ik1Gw,2153
41
- bosdyn/client/keepalive.py,sha256=C-Vf17-sSfAHq4cbuuVIh7JQM7NLzv2pRekjHJywfdU,13214
44
+ bosdyn/client/keepalive.py,sha256=Sz1sobzkyDfamKfaam7-dP3jIVlVOBs4l6JE5qqTjEA,14892
42
45
  bosdyn/client/lease.py,sha256=-B698QATgRuddH_pc5YN2LhMkZDacZP1kkf1MeYjqec,45412
43
46
  bosdyn/client/lease_resource_hierarchy.py,sha256=b_YpVCeiJwVQzAy1Xh5h-1HYjpbzZvmDZAcREGCOgBc,3070
44
47
  bosdyn/client/lease_validator.py,sha256=Vo5-2mtfCh50i7MDXLf4NlOBOgqd28ynPp2FF7NNGx0,14505
45
48
  bosdyn/client/license.py,sha256=mJRBtwo3UHUVXqAKq-3eBf35v9U_Za_P9lPRXF9q9Lk,1736
46
49
  bosdyn/client/local_grid.py,sha256=YszM_pTmeGuGIwExgRwB76PXJciO6rZqfaL2RHLxAf0,3475
47
- bosdyn/client/log_status.py,sha256=Om5S7RPS5y-lwCfumWPPocygpYmokT5J9A6ri44Q6co,12563
50
+ bosdyn/client/log_status.py,sha256=wcKZEFw8GHyWeYKysZ75i3PrLb1r2xVUEAyO3SDmxOI,12656
48
51
  bosdyn/client/manipulation_api_client.py,sha256=bdTTqZk73m7l9bty9CNC9Bs-hTTRFEA_wDweMb4mLu4,4204
49
52
  bosdyn/client/map_processing.py,sha256=xmwTkAfIIvRbaRnOCj-JTkrfS13n4z_DAqg-sc8hL2Y,10239
50
- bosdyn/client/math_helpers.py,sha256=yWGd4LW32KNXdaZ6TNIEWX-nriV72yBuawu37IjTtC4,47848
53
+ bosdyn/client/math_helpers.py,sha256=HLJ2pmul--Ualfa2cWHIgdNAZScK8MC6kjwqNKSCX44,48793
51
54
  bosdyn/client/metrics_logging.py,sha256=9gjVK5Xu4JpOqMg4_tKMHd-XHOh--xaiU_OP9zcGOMs,6646
52
55
  bosdyn/client/network_compute_bridge_client.py,sha256=L7RmgCRKiPBn3SVwIxCqP0hkEkhRhF5k5xz2BpC-Omk,7966
53
56
  bosdyn/client/payload.py,sha256=12vZirEI4-gu9KPHsDg6MH0QCmnxbolWR1j81lvgfVw,2271
54
- bosdyn/client/payload_registration.py,sha256=ilT-2W1iuCZImLeDlPLovPYg5HJCk7nLTHxod0Rn8nY,22316
55
- bosdyn/client/point_cloud.py,sha256=EZO67eqzTEX31RPHBvWXhu2GSSM82BfNNoWALFv21Xk,8382
57
+ bosdyn/client/payload_registration.py,sha256=rDGMK3ZtI6nmvCFsjm1MjueYglDNuHHu-7Q5V901VM8,24306
58
+ bosdyn/client/payload_software_update.py,sha256=nYrFOxuikVd-cChkx8aZ9gpVQSxjadgPcxyT6eklwT4,8716
59
+ bosdyn/client/payload_software_update_initiation.py,sha256=LDAe_gDUCLDKOC54MbhC-hsywqNMmT_dtnYjmMaef1g,3216
60
+ bosdyn/client/point_cloud.py,sha256=F_AJBYql8b6Ok_-IEmxpV4ajdXZ_GOahPe_QwWLf7xk,8627
56
61
  bosdyn/client/power.py,sha256=teVPBPcwsUHvn996upF06Y5MJsfQrE-93ezMXAAYSmA,26955
57
62
  bosdyn/client/processors.py,sha256=Z-Djf_I_lhfokB-f_L0PewAY8J95LThdWVju1zJ2BaE,1275
58
63
  bosdyn/client/ray_cast.py,sha256=Ca1yJo0aY6OmVAazb19fy44L-9LzcKVxr_fHt_EoQtg,4465
59
64
  bosdyn/client/recording.py,sha256=sQ34G_ckrE-M42ER2GUbYI7UibvdrjHycaia58IpJ2s,25913
60
- bosdyn/client/robot.py,sha256=HlwDPETYiQ0GT1ko4jVv-9Atbu7qAhfdgFfAkWXD1Sg,30775
65
+ bosdyn/client/robot.py,sha256=XQCp9NjcwS4Bhhohjup_AcLlYm67DV0tlPxuqZTwU1M,31114
61
66
  bosdyn/client/robot_command.py,sha256=LtoVKlJwwhTmADRMvJIWJ4B5rY_MpdhHnL72zKm1ECU,108248
62
67
  bosdyn/client/robot_id.py,sha256=0VZHG9hltwTLAm1_Bt26Xq1O6EROswqNwHvjY7kaplk,2482
63
68
  bosdyn/client/robot_state.py,sha256=h551ke5eHdAC7NgVuLphY8FZR899Ii8_lYwuoX1w1nk,7073
64
- bosdyn/client/sdk.py,sha256=uyawohyi8-BpLoCJe7cKICIzfEsVD-hN5GtgKFuKRak,12861
69
+ bosdyn/client/sdk.py,sha256=UFG5sRbnzEiB7hlUBIPm9KVceBrEOLGDuLQJtoIdyzM,12864
65
70
  bosdyn/client/server_util.py,sha256=uLT12vs5nAhdJ0ryaKuE82dxXnBOupebyDuzI8tbLRo,10560
66
- bosdyn/client/service_customization_helpers.py,sha256=7x5of7UioiEN_jYshynFCRw7rjB8JhocCN1gpeyexaY,48335
71
+ bosdyn/client/service_customization_helpers.py,sha256=GD23vhBfwCi1S4eBYIBoTbvHe9kwap1cbq0CHXlciGw,49155
67
72
  bosdyn/client/signals_helpers.py,sha256=Sp91IrMxVU-PeH6TK2njzFCKmFMyshRJqNa4DYRMqDU,3682
68
73
  bosdyn/client/spot_check.py,sha256=PKqN3kwL6oISkqwXEm_R4vz0uixIsfowWY9mC0mM8Cc,14619
69
74
  bosdyn/client/time_sync.py,sha256=mDkcR5RlAKfAOwEUoBjwxtJFDKuGFGmiDcrOeCO2P_g,23089
70
75
  bosdyn/client/token_cache.py,sha256=Vwf9YfsR7pTyu1fLRzXrvDo9hG5GBJcen8Azlo_5_iA,3507
71
- bosdyn/client/token_manager.py,sha256=FvDFCXKIiGXZNkagKZM41Ut8Q0ChlYHN3O61CzrqMF8,3144
76
+ bosdyn/client/token_manager.py,sha256=FkF2-xWXrKG1ttTH2omhjx7FtbIGnYkB1vAaKEhg3xM,5112
72
77
  bosdyn/client/units_helpers.py,sha256=5SAmL8vsnl06oGNjzb57fUkuUbGvtbeNdg4NgW0wYAY,1084
73
- bosdyn/client/util.py,sha256=itOXkbGRuwLpMN0nOFCeLo2mHd1rcZofjawPGTcIrw4,19970
78
+ bosdyn/client/util.py,sha256=Cr_IB1taOh6Hmu1EdTHa_NU08eXnTEG7kzGX_2xDfoE,19968
74
79
  bosdyn/client/world_object.py,sha256=CNfZJxwdTjd-Oh35liNdkZ27sAzdnBVFTkpVIICfRTo,17066
75
- bosdyn/client/gps/NMEAParser.py,sha256=XD-qCjZwm0IlZz7wb--riI-c_L2N-8rf4ZKrFATyC_g,8392
80
+ bosdyn/client/gps/NMEAParser.py,sha256=4ZZDt7NbQiDQpeu2Cs7OsgWErUgMk5XtSIWaoEuLfHE,8709
76
81
  bosdyn/client/gps/__init__.py,sha256=1qUAbnMKYlERYZvxtGz4ThjYef7Tx-ZBclLoVE_ecjU,265
77
82
  bosdyn/client/gps/aggregator_client.py,sha256=hMlmUcFope-QO51h0OAcDKWd_VUmkTkmeI6kLhj7OrU,2361
78
- bosdyn/client/gps/gps_listener.py,sha256=YJs_VLjXz7eQqjqqhndJWydRQzMdrTGMr05J5gaFSuw,6524
83
+ bosdyn/client/gps/gps_listener.py,sha256=Xx-H61o-uV4qO5XWOBnOJckYDi7c9azl9_EyWHjYJbU,7796
84
+ bosdyn/client/gps/ntrip_client.py,sha256=AvFThi3F3LyuES9vm_niHmktSLiGr_-gbIjg7pRku4Q,8311
79
85
  bosdyn/client/gps/registration_client.py,sha256=LqDLl_Ezv3HNUr9R1B4n2hcMArmGwLgg1asCkGhe2WA,1901
80
86
  bosdyn/client/resources/__init__.py,sha256=1qUAbnMKYlERYZvxtGz4ThjYef7Tx-ZBclLoVE_ecjU,265
81
87
  bosdyn/client/resources/robot.pem,sha256=kWAr4xK29RtTVC_EhbwW2_NblIuecYqVudR2YIdTh84,1874
82
- bosdyn/client/spot_cam/__init__.py,sha256=EZAvjRSla78A2iAENu-VJLbmwamNenTZPwQspQ5iyx8,790
88
+ bosdyn/client/spot_cam/__init__.py,sha256=N0FRE-glagSWkK9HQZuGyHvRGCfDzxUyVoPFu0mkrPU,829
83
89
  bosdyn/client/spot_cam/audio.py,sha256=8DvUOhfHVYTOXqlQEny5qUjHvvDsijvJ_njqyNJWUrs,9845
84
90
  bosdyn/client/spot_cam/compositor.py,sha256=pU3OcyrSX8RukXgTygOC-Eub-slBCxm05u97-b3oKaw,10570
85
91
  bosdyn/client/spot_cam/health.py,sha256=HsmLOKVb7iM6bfbZye0UapPezL2naWo4yl_7HQDNGA4,4707
@@ -88,10 +94,10 @@ bosdyn/client/spot_cam/lights_helper.py,sha256=VWhXwcZ1a5X6OQ6Fd1CzGGPdW4BNQ5j63
88
94
  bosdyn/client/spot_cam/media_log.py,sha256=CJJepePouHr1QoXuev8oJSMhA-JUYpcm6IBUq4k-Bl4,10379
89
95
  bosdyn/client/spot_cam/network.py,sha256=W7z91ERPzba3BCK23jio8byDjVr6kYnucQ9zKg9BqUA,3023
90
96
  bosdyn/client/spot_cam/power.py,sha256=HS3nJF8hXq9m1JziOIwLHGLtlNMyLgewWBgs-mRZmTM,5181
91
- bosdyn/client/spot_cam/ptz.py,sha256=8e6fA07aGnymSXV2MB_QBx0Pv4PSAMOihxq1jyoinDU,10815
97
+ bosdyn/client/spot_cam/ptz.py,sha256=O1m7zDZ92zRmvy9qhjojiphMQwAweTO0HVizQFdWFFE,10630
92
98
  bosdyn/client/spot_cam/streamquality.py,sha256=e-RjizZPwZSOS4Jlqb5Ds-mC6uKam252dpEHkb58Oc8,6364
93
99
  bosdyn/client/spot_cam/version.py,sha256=R82eyCAY9PfZqbN8D6hNzSeZatpgpsFr995dRt1Mbe0,2856
94
- bosdyn_client-4.1.1.dist-info/METADATA,sha256=vKclAm8QFBonyUFvrL0waidEGkUw5YOZBTXZ9De1pKU,4014
95
- bosdyn_client-4.1.1.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92
96
- bosdyn_client-4.1.1.dist-info/top_level.txt,sha256=an2OWgx1ej2jFjmBjPWNQ68ZglvUfKhmXWW-WhTtDmA,7
97
- bosdyn_client-4.1.1.dist-info/RECORD,,
100
+ bosdyn_client-5.0.1.dist-info/METADATA,sha256=RYhDRNp8XDqkZmc5omW_vvTfEGEEpRYEAy3o961WbZg,3987
101
+ bosdyn_client-5.0.1.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92
102
+ bosdyn_client-5.0.1.dist-info/top_level.txt,sha256=an2OWgx1ej2jFjmBjPWNQ68ZglvUfKhmXWW-WhTtDmA,7
103
+ bosdyn_client-5.0.1.dist-info/RECORD,,