standardbots 2.0.0.dev1737492400__tar.gz → 2.0.0.dev1740502639__tar.gz

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 standardbots might be problematic. Click here for more details.

Files changed (18) hide show
  1. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/PKG-INFO +1 -1
  2. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/README.md +16 -4
  3. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/setup.py +1 -1
  4. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/standardbots/auto_generated/apis.py +185 -14
  5. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/standardbots/auto_generated/models.py +393 -45
  6. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/standardbots.egg-info/PKG-INFO +1 -1
  7. standardbots-2.0.0.dev1740502639/tests/test_apis.py +2994 -0
  8. standardbots-2.0.0.dev1737492400/tests/test_apis.py +0 -1294
  9. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/setup.cfg +0 -0
  10. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/standardbots/__init__.py +0 -0
  11. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/standardbots/auto_generated/__init__.py +0 -0
  12. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/standardbots.egg-info/SOURCES.txt +0 -0
  13. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/standardbots.egg-info/dependency_links.txt +0 -0
  14. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/standardbots.egg-info/requires.txt +0 -0
  15. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/standardbots.egg-info/top_level.txt +0 -0
  16. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/tests/fixtures/__init__.py +0 -0
  17. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/tests/fixtures/client_fixt.py +0 -0
  18. {standardbots-2.0.0.dev1737492400 → standardbots-2.0.0.dev1740502639}/tests/fixtures/routines_fixt.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: standardbots
3
- Version: 2.0.0.dev1737492400
3
+ Version: 2.0.0.dev1740502639
4
4
  Summary: Standard Bots RO1 Robotics API
5
5
  Home-page:
6
6
  Author: Standard Bots Support
@@ -26,9 +26,14 @@ To set up tests:
26
26
 
27
27
  ```bash
28
28
  cd sdks/python
29
+ ```
30
+
31
+ Note: Make sure to select proper python interpreter.
32
+ Sometimes there is an error related to missing "dotenv" module, to solve this install it separately
29
33
 
30
- pip install -r requirements.txt
31
- pip install -r requirements-dev.txt
34
+ ```
35
+ python3 -m pip install python-dotenv
36
+ python3 -m pip install -r requirements-dev.txt
32
37
  ```
33
38
 
34
39
  ### Create sample data
@@ -71,7 +76,7 @@ python3 -m pytest ./tests --cov=standardbots
71
76
 
72
77
  ### Robot state and testing (Markers)
73
78
 
74
- We need the bot to be in a certain state to run certain tests. For example, we need a routine to be running in order to stop the routine.
79
+ We need the bot to be in a certain state to run certain tests. For example, we need a routine to be running in order to stop the routine. Camera should be connected by default.
75
80
 
76
81
  At start of testing, robot should:
77
82
 
@@ -82,7 +87,14 @@ The basic idea here is:
82
87
 
83
88
  - These special tests will not be run by default.
84
89
  - You may pass a flag (e.g. `--routine-running`) when the bot is in the correct state to run the tests.
85
- - When the flag is passed:
90
+ - Markers usage:
91
+ - When `--routine-running` flag is passed:
92
+ 1. Tests with the flag are run.
93
+ 2. Tests without the flag are not run.
94
+ - When `--gripper=<type>` flag is passed(`type` is value from `GripperKindEnum` enum):
95
+ 1. Tests expect that this specific gripper is connected
96
+ 2. Tests without the flag are not run.
97
+ - When `--camera-disconnected` flag is passed:
86
98
  1. Tests with the flag are run.
87
99
  2. Tests without the flag are not run.
88
100
 
@@ -13,7 +13,7 @@
13
13
  from setuptools import setup, find_packages # noqa: H301
14
14
 
15
15
  NAME = "standardbots"
16
- VERSION = "2.0.0-dev1737492400"
16
+ VERSION = "2.0.0-dev1740502639"
17
17
  # To install the library, run the following
18
18
  #
19
19
  # python setup.py install
@@ -76,6 +76,95 @@ class RequestManager:
76
76
 
77
77
  class Default:
78
78
  _request_manager: RequestManager
79
+ class Calibration:
80
+ def __init__(self, request_manager: RequestManager):
81
+ self._request_manager = request_manager
82
+
83
+
84
+ def get_active_calibration(
85
+ self,
86
+ ) -> Response[
87
+ Union[
88
+ models.ActiveCalibrationContainer,
89
+ models.ErrorResponse,
90
+ None
91
+ ],
92
+ models.ActiveCalibrationContainer
93
+ ]:
94
+ """
95
+ Get the active calibration for the robot.
96
+
97
+ """
98
+ path = "/api/v1/calibration/active"
99
+ try:
100
+ response = self._request_manager.request(
101
+ "GET",
102
+ path,
103
+ headers=self._request_manager.json_headers(),
104
+ )
105
+ parsed = None
106
+ if response.status == 200:
107
+ parsed = models.parse_active_calibration_container(json.loads(response.data))
108
+
109
+ is_user_error = response.status >= 400 and response.status <= 500
110
+ is_unavailable = response.status == 503
111
+ if parsed is None and (is_user_error or is_unavailable):
112
+ parsed = models.parse_error_response(json.loads(response.data))
113
+
114
+ return Response(
115
+ parsed,
116
+ response.status,
117
+ response
118
+ )
119
+ except urllib3.exceptions.MaxRetryError:
120
+ return Response(
121
+ models.ErrorResponse(
122
+ error=models.ErrorEnum.InternalServerError,
123
+ message="Connection Refused"
124
+ ),
125
+ 503,
126
+ None
127
+ )
128
+ def set_active_calibration(
129
+ self,
130
+ body: models.ActiveCalibrationContainer,
131
+ ) -> Response[
132
+ None,
133
+ None
134
+ ]:
135
+ """
136
+ Set the active calibration for the robot.
137
+
138
+ """
139
+ path = "/api/v1/calibration/active"
140
+ try:
141
+ response = self._request_manager.request(
142
+ "POST",
143
+ path,
144
+ headers=self._request_manager.json_headers(),
145
+ body=json.dumps(models.serialize_active_calibration_container(body)),
146
+ )
147
+ parsed = None
148
+
149
+ is_user_error = response.status >= 400 and response.status <= 500
150
+ is_unavailable = response.status == 503
151
+ if parsed is None and (is_user_error or is_unavailable):
152
+ parsed = models.parse_error_response(json.loads(response.data))
153
+
154
+ return Response(
155
+ parsed,
156
+ response.status,
157
+ response
158
+ )
159
+ except urllib3.exceptions.MaxRetryError:
160
+ return Response(
161
+ models.ErrorResponse(
162
+ error=models.ErrorEnum.InternalServerError,
163
+ message="Connection Refused"
164
+ ),
165
+ 503,
166
+ None
167
+ )
79
168
  class Equipment:
80
169
  def __init__(self, request_manager: RequestManager):
81
170
  self._request_manager = request_manager
@@ -83,7 +172,7 @@ class Default:
83
172
  def onrobot_2fg7_move(
84
173
  self,
85
174
  value: Union[int, float],
86
- direction: Union[str, models.LinearGripDirectionEnum] = models.LinearGripDirectionEnum.Inward,
175
+ direction: Union[str, models.LinearGripDirectionEnum] = models.LinearGripDirectionEnum.Internal,
87
176
  unit_kind: Union[str, models.LinearUnitKind] = models.LinearUnitKind.Millimeters
88
177
  ):
89
178
  """Move the robot to the onrobot_2fg7 position.
@@ -105,7 +194,7 @@ class Default:
105
194
  def onrobot_2fg7_grip(
106
195
  self,
107
196
  value: Union[int, float],
108
- direction: Union[str, models.LinearGripDirectionEnum] = models.LinearGripDirectionEnum.Inward,
197
+ direction: Union[str, models.LinearGripDirectionEnum] = models.LinearGripDirectionEnum.Internal,
109
198
  unit_kind: Union[str, models.LinearUnitKind] = models.LinearUnitKind.Millimeters,
110
199
  force: Union[int, float] = 0.0,
111
200
  force_unit: Union[str, models.ForceUnitKind] = models.ForceUnitKind.Newtons
@@ -382,12 +471,14 @@ class Default:
382
471
  None
383
472
  )
384
473
 
474
+ calibration: Calibration
385
475
  equipment: Equipment
386
476
  sensors: Sensors
387
477
  space: Space
388
478
 
389
479
  def __init__(self, request_manager: RequestManager):
390
480
  self._request_manager = request_manager
481
+ self.calibration = Default.Calibration(request_manager)
391
482
  self.equipment = Default.Equipment(request_manager)
392
483
  self.sensors = Default.Sensors(request_manager)
393
484
  self.space = Default.Space(request_manager)
@@ -425,6 +516,7 @@ class Movement:
425
516
  Union[
426
517
  models.BrakesState,
427
518
  models.ErrorResponse,
519
+ models.ErrorResponse,
428
520
  None
429
521
  ],
430
522
  models.BrakesState
@@ -444,6 +536,8 @@ class Movement:
444
536
  parsed = None
445
537
  if response.status == 200:
446
538
  parsed = models.parse_brakes_state(json.loads(response.data))
539
+ if response.status == 500:
540
+ parsed = models.parse_error_response(json.loads(response.data))
447
541
 
448
542
  is_user_error = response.status >= 400 and response.status <= 500
449
543
  is_unavailable = response.status == 503
@@ -713,7 +807,7 @@ class Camera:
713
807
  None
714
808
  ]:
715
809
  """
716
- Retrieve the latest RGB frame from the camera. In JPEG format.
810
+ Retrieve the latest RGB frame from the camera as base64 string. In JPEG format.
717
811
  """
718
812
  path = "/api/v1/camera/frame/rgb"
719
813
  try:
@@ -747,8 +841,12 @@ class Camera:
747
841
  def get_camera_intrinsics_color(
748
842
  self,
749
843
  ) -> Response[
750
- None,
751
- None
844
+ Union[
845
+ models.CameraIntrinsics,
846
+ models.ErrorResponse,
847
+ None
848
+ ],
849
+ models.CameraIntrinsics
752
850
  ]:
753
851
  """
754
852
  Retrieve the intrinsic parameters for the color camera.
@@ -761,6 +859,8 @@ class Camera:
761
859
  headers=self._request_manager.json_headers(),
762
860
  )
763
861
  parsed = None
862
+ if response.status == 200:
863
+ parsed = models.parse_camera_intrinsics(json.loads(response.data))
764
864
 
765
865
  is_user_error = response.status >= 400 and response.status <= 500
766
866
  is_unavailable = response.status == 503
@@ -788,7 +888,7 @@ class Camera:
788
888
  None
789
889
  ]:
790
890
  """
791
- Retrieve the latest RGB frame from the camera.
891
+ Retrieve the latest RGB frame from the camera as base64 string. In JPEG format.
792
892
  """
793
893
  path = "/api/v1/camera/stream/rgb"
794
894
  try:
@@ -863,14 +963,64 @@ class Camera:
863
963
  503,
864
964
  None
865
965
  )
966
+ class Status:
967
+ def __init__(self, request_manager: RequestManager):
968
+ self._request_manager = request_manager
969
+
970
+
971
+ def get_camera_status(
972
+ self,
973
+ ) -> Response[
974
+ Union[
975
+ models.CameraStatus,
976
+ models.ErrorResponse,
977
+ None
978
+ ],
979
+ models.CameraStatus
980
+ ]:
981
+ """
982
+ Retrieve the current status of the camera.
983
+ """
984
+ path = "/api/v1/camera/status"
985
+ try:
986
+ response = self._request_manager.request(
987
+ "GET",
988
+ path,
989
+ headers=self._request_manager.json_headers(),
990
+ )
991
+ parsed = None
992
+ if response.status == 200:
993
+ parsed = models.parse_camera_status(json.loads(response.data))
994
+
995
+ is_user_error = response.status >= 400 and response.status <= 500
996
+ is_unavailable = response.status == 503
997
+ if parsed is None and (is_user_error or is_unavailable):
998
+ parsed = models.parse_error_response(json.loads(response.data))
999
+
1000
+ return Response(
1001
+ parsed,
1002
+ response.status,
1003
+ response
1004
+ )
1005
+ except urllib3.exceptions.MaxRetryError:
1006
+ return Response(
1007
+ models.ErrorResponse(
1008
+ error=models.ErrorEnum.InternalServerError,
1009
+ message="Connection Refused"
1010
+ ),
1011
+ 503,
1012
+ None
1013
+ )
866
1014
 
867
1015
  data: Data
868
1016
  settings: Settings
1017
+ status: Status
869
1018
 
870
1019
  def __init__(self, request_manager: RequestManager):
871
1020
  self._request_manager = request_manager
872
1021
  self.data = Camera.Data(request_manager)
873
1022
  self.settings = Camera.Settings(request_manager)
1023
+ self.status = Camera.Status(request_manager)
874
1024
 
875
1025
  class Faults:
876
1026
  _request_manager: RequestManager
@@ -1927,8 +2077,13 @@ class RoutineEditor:
1927
2077
  body: models.PlayRoutineRequest,
1928
2078
  routine_id: str,
1929
2079
  ) -> Response[
1930
- None,
1931
- None
2080
+ Union[
2081
+ models.PlayRoutineResponse,
2082
+ models.ErrorResponse,
2083
+ models.ErrorResponse,
2084
+ None
2085
+ ],
2086
+ models.PlayRoutineResponse
1932
2087
  ]:
1933
2088
  """
1934
2089
  Play a routine
@@ -1943,6 +2098,10 @@ class RoutineEditor:
1943
2098
  body=json.dumps(models.serialize_play_routine_request(body)),
1944
2099
  )
1945
2100
  parsed = None
2101
+ if response.status == 200:
2102
+ parsed = models.parse_play_routine_response(json.loads(response.data))
2103
+ if response.status == 400:
2104
+ parsed = models.parse_error_response(json.loads(response.data))
1946
2105
 
1947
2106
  is_user_error = response.status >= 400 and response.status <= 500
1948
2107
  is_unavailable = response.status == 503
@@ -1967,11 +2126,15 @@ class RoutineEditor:
1967
2126
  self,
1968
2127
  routine_id: str,
1969
2128
  ) -> Response[
1970
- None,
2129
+ Union[
2130
+ models.ErrorResponse,
2131
+ models.ErrorResponse,
2132
+ None
2133
+ ],
1971
2134
  None
1972
2135
  ]:
1973
2136
  """
1974
- Pause a routine
2137
+ Pause a routine. Routine must be running.
1975
2138
  """
1976
2139
  path = "/api/v1/routine-editor/routines/{routine_id}/pause"
1977
2140
  path = path.replace("{routine_id}", str(routine_id))
@@ -1982,6 +2145,8 @@ class RoutineEditor:
1982
2145
  headers=self._request_manager.json_headers(),
1983
2146
  )
1984
2147
  parsed = None
2148
+ if response.status == 400:
2149
+ parsed = models.parse_error_response(json.loads(response.data))
1985
2150
 
1986
2151
  is_user_error = response.status >= 400 and response.status <= 500
1987
2152
  is_unavailable = response.status == 503
@@ -2005,11 +2170,15 @@ class RoutineEditor:
2005
2170
  def stop(
2006
2171
  self,
2007
2172
  ) -> Response[
2008
- None,
2173
+ Union[
2174
+ models.ErrorResponse,
2175
+ models.ErrorResponse,
2176
+ None
2177
+ ],
2009
2178
  None
2010
2179
  ]:
2011
2180
  """
2012
- Stop running routine and all ongoing motions
2181
+ Stop running routine and all ongoing motions. Routine must be running.
2013
2182
  """
2014
2183
  path = "/api/v1/routine-editor/stop"
2015
2184
  try:
@@ -2019,6 +2188,8 @@ class RoutineEditor:
2019
2188
  headers=self._request_manager.json_headers(),
2020
2189
  )
2021
2190
  parsed = None
2191
+ if response.status == 400:
2192
+ parsed = models.parse_error_response(json.loads(response.data))
2022
2193
 
2023
2194
  is_user_error = response.status >= 400 and response.status <= 500
2024
2195
  is_unavailable = response.status == 503
@@ -2293,7 +2464,7 @@ class RoutineEditor:
2293
2464
  models.RuntimeVariable
2294
2465
  ]:
2295
2466
  """
2296
- Returns current state of a variable
2467
+ Returns current state of a variable. Routine must be running.
2297
2468
  """
2298
2469
  path = "/api/v1/routine-editor/variables/{variable_name}"
2299
2470
  path = path.replace("{variable_name}", str(variable_name))
@@ -2339,7 +2510,7 @@ class RoutineEditor:
2339
2510
  models.RuntimeVariable
2340
2511
  ]:
2341
2512
  """
2342
- Update the value of a variable
2513
+ Update the value of a variable. Routine must be running.
2343
2514
  """
2344
2515
  path = "/api/v1/routine-editor/variables/{variable_name}"
2345
2516
  path = path.replace("{variable_name}", str(variable_name))