cyberwave 0.2.6__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.
Files changed (124) hide show
  1. cyberwave-0.2.6/LICENSE +21 -0
  2. cyberwave-0.2.6/PKG-INFO +270 -0
  3. cyberwave-0.2.6/README.md +244 -0
  4. cyberwave-0.2.6/cyberwave/__init__.py +116 -0
  5. cyberwave-0.2.6/cyberwave/camera.py +678 -0
  6. cyberwave-0.2.6/cyberwave/client.py +416 -0
  7. cyberwave-0.2.6/cyberwave/compact.py +145 -0
  8. cyberwave-0.2.6/cyberwave/config.py +103 -0
  9. cyberwave-0.2.6/cyberwave/controller.py +175 -0
  10. cyberwave-0.2.6/cyberwave/exceptions.py +304 -0
  11. cyberwave-0.2.6/cyberwave/mqtt/README.md +171 -0
  12. cyberwave-0.2.6/cyberwave/mqtt/__init__.py +607 -0
  13. cyberwave-0.2.6/cyberwave/mqtt_client.py +328 -0
  14. cyberwave-0.2.6/cyberwave/py.typed +0 -0
  15. cyberwave-0.2.6/cyberwave/resources.py +329 -0
  16. cyberwave-0.2.6/cyberwave/rest/README.md +267 -0
  17. cyberwave-0.2.6/cyberwave/rest/__init__.py +222 -0
  18. cyberwave-0.2.6/cyberwave/rest/api/__init__.py +5 -0
  19. cyberwave-0.2.6/cyberwave/rest/api/default_api.py +41259 -0
  20. cyberwave-0.2.6/cyberwave/rest/api_client.py +804 -0
  21. cyberwave-0.2.6/cyberwave/rest/api_response.py +21 -0
  22. cyberwave-0.2.6/cyberwave/rest/configuration.py +606 -0
  23. cyberwave-0.2.6/cyberwave/rest/exceptions.py +219 -0
  24. cyberwave-0.2.6/cyberwave/rest/models/__init__.py +103 -0
  25. cyberwave-0.2.6/cyberwave/rest/models/asset_create_schema.py +114 -0
  26. cyberwave-0.2.6/cyberwave/rest/models/asset_create_with_urdf_schema.py +105 -0
  27. cyberwave-0.2.6/cyberwave/rest/models/asset_glb_from_attachment_schema.py +87 -0
  28. cyberwave-0.2.6/cyberwave/rest/models/asset_list_schema.py +119 -0
  29. cyberwave-0.2.6/cyberwave/rest/models/asset_schema.py +161 -0
  30. cyberwave-0.2.6/cyberwave/rest/models/asset_update_schema.py +134 -0
  31. cyberwave-0.2.6/cyberwave/rest/models/attachment_create_schema.py +106 -0
  32. cyberwave-0.2.6/cyberwave/rest/models/attachment_schema.py +141 -0
  33. cyberwave-0.2.6/cyberwave/rest/models/bulk_joint_states_update_schema.py +87 -0
  34. cyberwave-0.2.6/cyberwave/rest/models/combined_dataset_generation_request_schema.py +98 -0
  35. cyberwave-0.2.6/cyberwave/rest/models/combined_recording_generation_request_schema.py +98 -0
  36. cyberwave-0.2.6/cyberwave/rest/models/complete_large_upload_schema.py +94 -0
  37. cyberwave-0.2.6/cyberwave/rest/models/contact_form_schema.py +95 -0
  38. cyberwave-0.2.6/cyberwave/rest/models/controller_policy_create_schema.py +100 -0
  39. cyberwave-0.2.6/cyberwave/rest/models/controller_policy_schema.py +109 -0
  40. cyberwave-0.2.6/cyberwave/rest/models/controller_policy_update_schema.py +120 -0
  41. cyberwave-0.2.6/cyberwave/rest/models/dataset_create_schema.py +108 -0
  42. cyberwave-0.2.6/cyberwave/rest/models/dataset_generation_request_schema.py +91 -0
  43. cyberwave-0.2.6/cyberwave/rest/models/dataset_generation_request_schema_by_date.py +93 -0
  44. cyberwave-0.2.6/cyberwave/rest/models/dataset_generation_response_schema.py +91 -0
  45. cyberwave-0.2.6/cyberwave/rest/models/dataset_schema.py +110 -0
  46. cyberwave-0.2.6/cyberwave/rest/models/dataset_update_schema.py +113 -0
  47. cyberwave-0.2.6/cyberwave/rest/models/edge_command_schema.py +87 -0
  48. cyberwave-0.2.6/cyberwave/rest/models/edge_create_schema.py +101 -0
  49. cyberwave-0.2.6/cyberwave/rest/models/edge_schema.py +103 -0
  50. cyberwave-0.2.6/cyberwave/rest/models/environment_create_schema.py +103 -0
  51. cyberwave-0.2.6/cyberwave/rest/models/environment_schema.py +110 -0
  52. cyberwave-0.2.6/cyberwave/rest/models/episode_create_schema.py +112 -0
  53. cyberwave-0.2.6/cyberwave/rest/models/episode_schema.py +114 -0
  54. cyberwave-0.2.6/cyberwave/rest/models/episode_update_schema.py +127 -0
  55. cyberwave-0.2.6/cyberwave/rest/models/initiate_large_upload_response.py +101 -0
  56. cyberwave-0.2.6/cyberwave/rest/models/initiate_large_upload_schema.py +101 -0
  57. cyberwave-0.2.6/cyberwave/rest/models/joint_schema.py +114 -0
  58. cyberwave-0.2.6/cyberwave/rest/models/joint_state_schema.py +93 -0
  59. cyberwave-0.2.6/cyberwave/rest/models/joint_state_update_schema.py +106 -0
  60. cyberwave-0.2.6/cyberwave/rest/models/joint_states_schema.py +95 -0
  61. cyberwave-0.2.6/cyberwave/rest/models/link_share_create_schema.py +94 -0
  62. cyberwave-0.2.6/cyberwave/rest/models/link_share_revoke_schema.py +87 -0
  63. cyberwave-0.2.6/cyberwave/rest/models/link_share_schema.py +108 -0
  64. cyberwave-0.2.6/cyberwave/rest/models/llm_generation_schema.py +87 -0
  65. cyberwave-0.2.6/cyberwave/rest/models/llm_response_schema.py +87 -0
  66. cyberwave-0.2.6/cyberwave/rest/models/ml_model_create_schema.py +124 -0
  67. cyberwave-0.2.6/cyberwave/rest/models/ml_model_schema.py +120 -0
  68. cyberwave-0.2.6/cyberwave/rest/models/ml_model_update_schema.py +162 -0
  69. cyberwave-0.2.6/cyberwave/rest/models/organization_schema.py +91 -0
  70. cyberwave-0.2.6/cyberwave/rest/models/organization_update_schema.py +94 -0
  71. cyberwave-0.2.6/cyberwave/rest/models/payload.py +134 -0
  72. cyberwave-0.2.6/cyberwave/rest/models/permissions_schema.py +100 -0
  73. cyberwave-0.2.6/cyberwave/rest/models/plan_schema.py +91 -0
  74. cyberwave-0.2.6/cyberwave/rest/models/popular_tag_schema.py +89 -0
  75. cyberwave-0.2.6/cyberwave/rest/models/popular_tags_response_schema.py +95 -0
  76. cyberwave-0.2.6/cyberwave/rest/models/project_create_schema.py +98 -0
  77. cyberwave-0.2.6/cyberwave/rest/models/project_schema.py +104 -0
  78. cyberwave-0.2.6/cyberwave/rest/models/project_share_response_schema.py +89 -0
  79. cyberwave-0.2.6/cyberwave/rest/models/public_user_schema.py +98 -0
  80. cyberwave-0.2.6/cyberwave/rest/models/recording_generation_request_schema.py +91 -0
  81. cyberwave-0.2.6/cyberwave/rest/models/recording_generation_request_schema_by_date.py +93 -0
  82. cyberwave-0.2.6/cyberwave/rest/models/recording_generation_response_schema.py +91 -0
  83. cyberwave-0.2.6/cyberwave/rest/models/robot_description_schema.py +99 -0
  84. cyberwave-0.2.6/cyberwave/rest/models/share_schema.py +108 -0
  85. cyberwave-0.2.6/cyberwave/rest/models/shares_response_schema.py +115 -0
  86. cyberwave-0.2.6/cyberwave/rest/models/simulation_start_schema.py +116 -0
  87. cyberwave-0.2.6/cyberwave/rest/models/team_member_response.py +93 -0
  88. cyberwave-0.2.6/cyberwave/rest/models/team_share_schema.py +101 -0
  89. cyberwave-0.2.6/cyberwave/rest/models/twin_command_schema.py +87 -0
  90. cyberwave-0.2.6/cyberwave/rest/models/twin_create_schema.py +147 -0
  91. cyberwave-0.2.6/cyberwave/rest/models/twin_relationship_schema.py +97 -0
  92. cyberwave-0.2.6/cyberwave/rest/models/twin_schema.py +157 -0
  93. cyberwave-0.2.6/cyberwave/rest/models/twin_state_update_schema.py +134 -0
  94. cyberwave-0.2.6/cyberwave/rest/models/twin_telemetry_metadata_schema.py +93 -0
  95. cyberwave-0.2.6/cyberwave/rest/models/twin_telemetry_schema.py +95 -0
  96. cyberwave-0.2.6/cyberwave/rest/models/update_dataset_metadata_schema.py +87 -0
  97. cyberwave-0.2.6/cyberwave/rest/models/update_recording_metadata_schema.py +87 -0
  98. cyberwave-0.2.6/cyberwave/rest/models/urdf_project_create_schema.py +94 -0
  99. cyberwave-0.2.6/cyberwave/rest/models/urdf_project_schema.py +107 -0
  100. cyberwave-0.2.6/cyberwave/rest/models/user_schema.py +117 -0
  101. cyberwave-0.2.6/cyberwave/rest/models/user_share_schema.py +103 -0
  102. cyberwave-0.2.6/cyberwave/rest/models/vendor_description_schema.py +98 -0
  103. cyberwave-0.2.6/cyberwave/rest/models/vlm_generation_schema.py +89 -0
  104. cyberwave-0.2.6/cyberwave/rest/models/vlm_response_schema.py +87 -0
  105. cyberwave-0.2.6/cyberwave/rest/models/workflow_connection_create_schema.py +100 -0
  106. cyberwave-0.2.6/cyberwave/rest/models/workflow_connection_schema.py +102 -0
  107. cyberwave-0.2.6/cyberwave/rest/models/workflow_create_schema.py +107 -0
  108. cyberwave-0.2.6/cyberwave/rest/models/workflow_execute_schema.py +92 -0
  109. cyberwave-0.2.6/cyberwave/rest/models/workflow_execution_schema.py +129 -0
  110. cyberwave-0.2.6/cyberwave/rest/models/workflow_node_create_schema.py +120 -0
  111. cyberwave-0.2.6/cyberwave/rest/models/workflow_node_execution_schema.py +123 -0
  112. cyberwave-0.2.6/cyberwave/rest/models/workflow_node_schema.py +119 -0
  113. cyberwave-0.2.6/cyberwave/rest/models/workflow_node_update_schema.py +155 -0
  114. cyberwave-0.2.6/cyberwave/rest/models/workflow_schema.py +138 -0
  115. cyberwave-0.2.6/cyberwave/rest/models/workflow_update_schema.py +120 -0
  116. cyberwave-0.2.6/cyberwave/rest/models/workspace_response_schema.py +109 -0
  117. cyberwave-0.2.6/cyberwave/rest/models/workspace_schema.py +125 -0
  118. cyberwave-0.2.6/cyberwave/rest/models/workspace_update_schema.py +101 -0
  119. cyberwave-0.2.6/cyberwave/rest/models/workspace_user_schema.py +93 -0
  120. cyberwave-0.2.6/cyberwave/rest/py.typed +0 -0
  121. cyberwave-0.2.6/cyberwave/rest/rest.py +258 -0
  122. cyberwave-0.2.6/cyberwave/twin.py +406 -0
  123. cyberwave-0.2.6/cyberwave/utils.py +31 -0
  124. cyberwave-0.2.6/pyproject.toml +36 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 CyberWave Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,270 @@
1
+ Metadata-Version: 2.4
2
+ Name: cyberwave
3
+ Version: 0.2.6
4
+ Summary: Python SDK for Cyberwave
5
+ License-File: LICENSE
6
+ Author: Simone Di Somma
7
+ Author-email: sdisomma@cyberwave.com
8
+ Requires-Python: >=3.10,<4.0
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Provides-Extra: camera
16
+ Requires-Dist: aiortc (>=1.5.0,<2.0.0) ; extra == "camera"
17
+ Requires-Dist: av (>=16.0.1,<17.0.0) ; extra == "camera"
18
+ Requires-Dist: opencv-python (>=4.8.0,<5.0.0) ; extra == "camera"
19
+ Requires-Dist: paho-mqtt (>=2.1.0,<3.0.0)
20
+ Requires-Dist: pydantic (>=2,<3)
21
+ Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
22
+ Requires-Dist: typing-extensions (>=4.7.1,<5.0.0)
23
+ Requires-Dist: urllib3 (>=2.1.0,<3.0.0)
24
+ Description-Content-Type: text/markdown
25
+
26
+ # Cyberwave Python SDK
27
+
28
+ The official Python SDK for Cyberwave. Create, control, and simulate robotics with ease.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install cyberwave
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ### 1. Get Your Token
39
+
40
+ Get your API token from the Cyberwave platform:
41
+
42
+ - Log in to your Cyberwave instance
43
+ - Navigate to [Profile](https://cyberwave.com/profile) → API Tokens
44
+ - Create a token and copy it
45
+
46
+ ### 2. Create Your First Digital Twin
47
+
48
+ ```python
49
+ from cyberwave import Cyberwave
50
+
51
+ # Configure with your token
52
+ cw = Cyberwave(
53
+ token="your_token_here",
54
+ )
55
+
56
+ # Create a digital twin from an asset
57
+ robot = cw.twin("the-robot-studio/so101")
58
+
59
+ # Control position and rotation
60
+ robot.move(x=1.0, y=0.0, z=0.5)
61
+ robot.rotate(yaw=90) # degrees
62
+
63
+ # Move the robot arm to 30 degrees
64
+ robot.joints.set("1", 30)
65
+
66
+ # Get current joint positions
67
+ print(robot.joints.get_all())
68
+ ```
69
+
70
+ ## Core Features
71
+
72
+ ### Working with Workspaces and Projects
73
+
74
+ ```python
75
+ from cyberwave import Cyberwave
76
+
77
+ cw = Cyberwave(
78
+ token="your_token_here"
79
+ )
80
+
81
+ # You can also set your token as an environment variable: export CYBERWAVE_TOKEN=your_token_here
82
+ # in that case, you can simply do:
83
+ cw = Cyberwave()
84
+
85
+ # List workspaces
86
+ workspaces = cw.workspaces.list()
87
+ print(f"Found {len(workspaces)} workspaces")
88
+
89
+ # Create a project
90
+ project = cw.projects.create(
91
+ name="My Robotics Project",
92
+ workspace_id=workspaces[0].uuid
93
+ )
94
+
95
+ # Create an environment
96
+ environment = cw.environments.create(
97
+ name="Development",
98
+ project_id=project.uuid
99
+ )
100
+ ```
101
+
102
+ ### Managing Assets and Twins
103
+
104
+ ```python
105
+ # To instantiate a twin, you can query the available assets from the catalog.
106
+ # This query will return both the public assets availaable at cyberwave.com/catalog and the private assets available to your organization.
107
+ assets = cw.assets.search("so101")
108
+ robot = cw.twin(assets[0].registry_id) # the registry_id is the unique identifier for the asset in the catalog. in this case it's the-robot-studio/so101
109
+
110
+ # Move to a specific position
111
+ robot.move_to([1.0, 0.5, 0.0])
112
+
113
+ # Update scale
114
+ robot.scale(x=1.5, y=1.5, z=1.5)
115
+
116
+ # Move a joint to a specific position using radians
117
+ robot.joints.set("shoulder_joint", math.pi/4)
118
+
119
+ # You can also use degrees:
120
+ robot.joints.set("shoulder_joint", 45, degrees=True)
121
+
122
+ # You can also go a get_or_create for a specific twin an environment you created:
123
+ robot = cw.twin("the-robot-studio/so101", environment_id="YOUR_ENVIRONMENT_ID")
124
+ ```
125
+
126
+ ### Environment Variables
127
+
128
+ If you are always using the same environment, you can set it as a default with the CYBERWAVE_ENVIRONMENT_ID environment variable:
129
+
130
+ ```bash
131
+ export CYBERWAVE_ENVIRONMENT_ID="YOUR_ENVIRONMENT_ID"
132
+ export CYBERWAVE_TOKEN="YOUR_TOKEN"
133
+ python your_script.py
134
+ ```
135
+
136
+ And then you can simply do:
137
+
138
+ ```python
139
+ from cyberwave import Cyberwave
140
+
141
+ cw = Cyberwave()
142
+ robot = cw.twin("the-robot-studio/so101")
143
+ ```
144
+
145
+ This code will return you the first SO101 twin in your environment, or create it if it doesn't exist.
146
+
147
+ ### Video Streaming (WebRTC)
148
+
149
+ Stream camera feeds to your digital twins using WebRTC.
150
+
151
+ To stream you will need to install FFMPEG if you don't have it.
152
+
153
+ On Mac with brew:
154
+
155
+ ```bash
156
+ brew install ffmpeg pkg-config
157
+ ```
158
+
159
+ On Ubuntu:
160
+
161
+ ```bash
162
+ sudo apt-get install ffmpeg
163
+ ```
164
+
165
+ Then install the additional deps for camera streaming:
166
+
167
+ ```bash
168
+ # Install with camera support
169
+ pip install cyberwave[camera]
170
+ ```
171
+
172
+ ```python
173
+ import asyncio
174
+ from cyberwave import Cyberwave
175
+
176
+ # Initialize client
177
+ cw = Cyberwave()
178
+
179
+ # Create camera streamer - integrated into the Cyberwave client!
180
+ streamer = cw.video_stream(
181
+ twin_uuid="your_twin_uuid",
182
+ camera_id=0, # Default camera
183
+ fps=10 # Frames per second
184
+ )
185
+
186
+ # Start streaming
187
+ async def stream_camera():
188
+ await streamer.start()
189
+ # Stream runs until stopped
190
+ await asyncio.sleep(60) # Stream for 60 seconds
191
+ await streamer.stop()
192
+
193
+ # Run the async function
194
+ asyncio.run(stream_camera())
195
+ ```
196
+
197
+ The `video_stream()` method:
198
+
199
+ - Automatically uses the client's MQTT connection
200
+ - Pre-configures the streamer with the twin UUID
201
+ - Handles WebRTC peer connection setup
202
+ - Manages ICE candidate gathering with STUN/TURN servers
203
+ - Handles video encoding and streaming
204
+
205
+ ## Advanced Usage
206
+
207
+ ### Joint Control
208
+
209
+ You can change a specific joint actuation. You can use degrees or radiants:
210
+
211
+ ```python
212
+ robot = cw.twin("the-robot-studio/so101")
213
+
214
+ # Set individual joints (degrees by default)
215
+ robot.joints.set("shoulder_joint", 45, degrees=True)
216
+
217
+ # Or use radians
218
+ import math
219
+ robot.joints.set("elbow_joint", math.pi/4, degrees=False)
220
+
221
+ # Get current joint position
222
+ angle = robot.joints.get("shoulder_joint")
223
+
224
+ # List all joints
225
+ joint_names = robot.joints.list()
226
+
227
+ # Get all joint states at once
228
+ all_joints = robot.joints.get_all()
229
+ ```
230
+
231
+ ## API Reference
232
+
233
+ You can use the lower level API by using the `client` attribute:
234
+
235
+ ```python
236
+ from cyberwave import Cyberwave
237
+
238
+ cw = Cyberwave()
239
+ client = cw.client.rest # for the rest API
240
+ client = cw.client.mqtt # for the MQTT API
241
+ ```
242
+
243
+ To check out the available endpoints and their parameters, you can refer to the full API reference [here](https://docs.cyberwave.com/api-reference/overview).
244
+
245
+ ## Examples
246
+
247
+ Check the [examples](examples) directory for complete examples:
248
+
249
+ - Basic twin control
250
+ - Multi-robot coordination
251
+ - Real-time synchronization
252
+ - Joint manipulation for robot arms
253
+
254
+ ## Testing
255
+
256
+ ### Unit Tests
257
+
258
+ Run basic import tests:
259
+
260
+ ```bash
261
+ poetry install
262
+ poetry run python tests/test_imports.py
263
+ ```
264
+
265
+ ## Support
266
+
267
+ - **Documentation**: [docs.cyberwave.com](https://docs.cyberwave.com)
268
+ - **Issues**: [GitHub Issues](https://github.com/cyberwave/cyberwave-python/issues)
269
+ <!-- - **Community**: [Discord](https://discord.gg/cyberwave) -->
270
+
@@ -0,0 +1,244 @@
1
+ # Cyberwave Python SDK
2
+
3
+ The official Python SDK for Cyberwave. Create, control, and simulate robotics with ease.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install cyberwave
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### 1. Get Your Token
14
+
15
+ Get your API token from the Cyberwave platform:
16
+
17
+ - Log in to your Cyberwave instance
18
+ - Navigate to [Profile](https://cyberwave.com/profile) → API Tokens
19
+ - Create a token and copy it
20
+
21
+ ### 2. Create Your First Digital Twin
22
+
23
+ ```python
24
+ from cyberwave import Cyberwave
25
+
26
+ # Configure with your token
27
+ cw = Cyberwave(
28
+ token="your_token_here",
29
+ )
30
+
31
+ # Create a digital twin from an asset
32
+ robot = cw.twin("the-robot-studio/so101")
33
+
34
+ # Control position and rotation
35
+ robot.move(x=1.0, y=0.0, z=0.5)
36
+ robot.rotate(yaw=90) # degrees
37
+
38
+ # Move the robot arm to 30 degrees
39
+ robot.joints.set("1", 30)
40
+
41
+ # Get current joint positions
42
+ print(robot.joints.get_all())
43
+ ```
44
+
45
+ ## Core Features
46
+
47
+ ### Working with Workspaces and Projects
48
+
49
+ ```python
50
+ from cyberwave import Cyberwave
51
+
52
+ cw = Cyberwave(
53
+ token="your_token_here"
54
+ )
55
+
56
+ # You can also set your token as an environment variable: export CYBERWAVE_TOKEN=your_token_here
57
+ # in that case, you can simply do:
58
+ cw = Cyberwave()
59
+
60
+ # List workspaces
61
+ workspaces = cw.workspaces.list()
62
+ print(f"Found {len(workspaces)} workspaces")
63
+
64
+ # Create a project
65
+ project = cw.projects.create(
66
+ name="My Robotics Project",
67
+ workspace_id=workspaces[0].uuid
68
+ )
69
+
70
+ # Create an environment
71
+ environment = cw.environments.create(
72
+ name="Development",
73
+ project_id=project.uuid
74
+ )
75
+ ```
76
+
77
+ ### Managing Assets and Twins
78
+
79
+ ```python
80
+ # To instantiate a twin, you can query the available assets from the catalog.
81
+ # This query will return both the public assets availaable at cyberwave.com/catalog and the private assets available to your organization.
82
+ assets = cw.assets.search("so101")
83
+ robot = cw.twin(assets[0].registry_id) # the registry_id is the unique identifier for the asset in the catalog. in this case it's the-robot-studio/so101
84
+
85
+ # Move to a specific position
86
+ robot.move_to([1.0, 0.5, 0.0])
87
+
88
+ # Update scale
89
+ robot.scale(x=1.5, y=1.5, z=1.5)
90
+
91
+ # Move a joint to a specific position using radians
92
+ robot.joints.set("shoulder_joint", math.pi/4)
93
+
94
+ # You can also use degrees:
95
+ robot.joints.set("shoulder_joint", 45, degrees=True)
96
+
97
+ # You can also go a get_or_create for a specific twin an environment you created:
98
+ robot = cw.twin("the-robot-studio/so101", environment_id="YOUR_ENVIRONMENT_ID")
99
+ ```
100
+
101
+ ### Environment Variables
102
+
103
+ If you are always using the same environment, you can set it as a default with the CYBERWAVE_ENVIRONMENT_ID environment variable:
104
+
105
+ ```bash
106
+ export CYBERWAVE_ENVIRONMENT_ID="YOUR_ENVIRONMENT_ID"
107
+ export CYBERWAVE_TOKEN="YOUR_TOKEN"
108
+ python your_script.py
109
+ ```
110
+
111
+ And then you can simply do:
112
+
113
+ ```python
114
+ from cyberwave import Cyberwave
115
+
116
+ cw = Cyberwave()
117
+ robot = cw.twin("the-robot-studio/so101")
118
+ ```
119
+
120
+ This code will return you the first SO101 twin in your environment, or create it if it doesn't exist.
121
+
122
+ ### Video Streaming (WebRTC)
123
+
124
+ Stream camera feeds to your digital twins using WebRTC.
125
+
126
+ To stream you will need to install FFMPEG if you don't have it.
127
+
128
+ On Mac with brew:
129
+
130
+ ```bash
131
+ brew install ffmpeg pkg-config
132
+ ```
133
+
134
+ On Ubuntu:
135
+
136
+ ```bash
137
+ sudo apt-get install ffmpeg
138
+ ```
139
+
140
+ Then install the additional deps for camera streaming:
141
+
142
+ ```bash
143
+ # Install with camera support
144
+ pip install cyberwave[camera]
145
+ ```
146
+
147
+ ```python
148
+ import asyncio
149
+ from cyberwave import Cyberwave
150
+
151
+ # Initialize client
152
+ cw = Cyberwave()
153
+
154
+ # Create camera streamer - integrated into the Cyberwave client!
155
+ streamer = cw.video_stream(
156
+ twin_uuid="your_twin_uuid",
157
+ camera_id=0, # Default camera
158
+ fps=10 # Frames per second
159
+ )
160
+
161
+ # Start streaming
162
+ async def stream_camera():
163
+ await streamer.start()
164
+ # Stream runs until stopped
165
+ await asyncio.sleep(60) # Stream for 60 seconds
166
+ await streamer.stop()
167
+
168
+ # Run the async function
169
+ asyncio.run(stream_camera())
170
+ ```
171
+
172
+ The `video_stream()` method:
173
+
174
+ - Automatically uses the client's MQTT connection
175
+ - Pre-configures the streamer with the twin UUID
176
+ - Handles WebRTC peer connection setup
177
+ - Manages ICE candidate gathering with STUN/TURN servers
178
+ - Handles video encoding and streaming
179
+
180
+ ## Advanced Usage
181
+
182
+ ### Joint Control
183
+
184
+ You can change a specific joint actuation. You can use degrees or radiants:
185
+
186
+ ```python
187
+ robot = cw.twin("the-robot-studio/so101")
188
+
189
+ # Set individual joints (degrees by default)
190
+ robot.joints.set("shoulder_joint", 45, degrees=True)
191
+
192
+ # Or use radians
193
+ import math
194
+ robot.joints.set("elbow_joint", math.pi/4, degrees=False)
195
+
196
+ # Get current joint position
197
+ angle = robot.joints.get("shoulder_joint")
198
+
199
+ # List all joints
200
+ joint_names = robot.joints.list()
201
+
202
+ # Get all joint states at once
203
+ all_joints = robot.joints.get_all()
204
+ ```
205
+
206
+ ## API Reference
207
+
208
+ You can use the lower level API by using the `client` attribute:
209
+
210
+ ```python
211
+ from cyberwave import Cyberwave
212
+
213
+ cw = Cyberwave()
214
+ client = cw.client.rest # for the rest API
215
+ client = cw.client.mqtt # for the MQTT API
216
+ ```
217
+
218
+ To check out the available endpoints and their parameters, you can refer to the full API reference [here](https://docs.cyberwave.com/api-reference/overview).
219
+
220
+ ## Examples
221
+
222
+ Check the [examples](examples) directory for complete examples:
223
+
224
+ - Basic twin control
225
+ - Multi-robot coordination
226
+ - Real-time synchronization
227
+ - Joint manipulation for robot arms
228
+
229
+ ## Testing
230
+
231
+ ### Unit Tests
232
+
233
+ Run basic import tests:
234
+
235
+ ```bash
236
+ poetry install
237
+ poetry run python tests/test_imports.py
238
+ ```
239
+
240
+ ## Support
241
+
242
+ - **Documentation**: [docs.cyberwave.com](https://docs.cyberwave.com)
243
+ - **Issues**: [GitHub Issues](https://github.com/cyberwave/cyberwave-python/issues)
244
+ <!-- - **Community**: [Discord](https://discord.gg/cyberwave) -->
@@ -0,0 +1,116 @@
1
+ """
2
+ Cyberwave SDK - Python client for the Cyberwave Digital Twin Platform
3
+
4
+ This SDK provides a comprehensive interface for interacting with the Cyberwave platform,
5
+ including REST APIs, MQTT messaging, and high-level abstractions for digital twins.
6
+
7
+ Quick Start:
8
+ >>> from cyberwave import Cyberwave
9
+ >>> client = Cyberwave(base_url="http://localhost:8000", api_key="your_key")
10
+ >>> workspaces = client.workspaces.list()
11
+
12
+ Or use the compact API:
13
+ >>> import cyberwave as cw
14
+ >>> cw.configure(api_key="your_key", base_url="http://localhost:8000")
15
+ >>> robot = cw.twin("the-robot-studio/so101")
16
+ >>> robot.move(x=1, y=0, z=0.5)
17
+
18
+ Video Streaming (requires: pip install cyberwave[camera]):
19
+ >>> client = Cyberwave(token="your_token")
20
+ >>> streamer = client.video_stream(twin_uuid="your_twin_uuid")
21
+ >>> await streamer.start()
22
+ """
23
+
24
+ # Core client
25
+ from .client import Cyberwave
26
+
27
+ # Configuration
28
+ from .config import CyberwaveConfig, get_config, set_config
29
+
30
+ # High-level abstractions
31
+ from .twin import Twin, JointController
32
+
33
+ # Exceptions
34
+ from .exceptions import (
35
+ CyberwaveError,
36
+ CyberwaveAPIError,
37
+ CyberwaveConnectionError,
38
+ CyberwaveTimeoutError,
39
+ CyberwaveValidationError,
40
+ )
41
+
42
+ # Compact API - convenience functions
43
+ from .compact import (
44
+ configure,
45
+ twin,
46
+ get_client,
47
+ )
48
+
49
+ # Resource managers (optional, available through client instance)
50
+ from .resources import (
51
+ WorkspaceManager,
52
+ ProjectManager,
53
+ EnvironmentManager,
54
+ AssetManager,
55
+ TwinManager,
56
+ )
57
+
58
+ # MQTT client (optional, for direct MQTT access)
59
+ from .mqtt import CyberwaveMQTTClient
60
+
61
+ # Camera streaming (optional, requires additional dependencies)
62
+ try:
63
+ from .camera import CameraStreamer, CV2VideoStreamTrack
64
+
65
+ _has_camera = True
66
+ except ImportError:
67
+ _has_camera = False
68
+ CameraStreamer = None # type: ignore
69
+ CV2VideoStreamTrack = None # type: ignore
70
+
71
+ # Edge controller
72
+ from .controller import EdgeController
73
+
74
+ # Version information
75
+ __version__ = "0.2.4"
76
+
77
+ # Define public API
78
+ __all__ = [
79
+ # Core client
80
+ "Cyberwave",
81
+ # Configuration
82
+ "CyberwaveConfig",
83
+ "get_config",
84
+ "set_config",
85
+ # High-level abstractions
86
+ "Twin",
87
+ "JointController",
88
+ # Exceptions
89
+ "CyberwaveError",
90
+ "CyberwaveAPIError",
91
+ "CyberwaveConnectionError",
92
+ "CyberwaveTimeoutError",
93
+ "CyberwaveValidationError",
94
+ # Compact API
95
+ "configure",
96
+ "twin",
97
+ "simulation",
98
+ "get_client",
99
+ # Resource managers
100
+ "WorkspaceManager",
101
+ "ProjectManager",
102
+ "EnvironmentManager",
103
+ "AssetManager",
104
+ "TwinManager",
105
+ # MQTT client
106
+ "CyberwaveMQTTClient",
107
+ # Camera streaming (optional)
108
+ "CameraStreamer",
109
+ "CV2VideoStreamTrack",
110
+ # Edge controller
111
+ "EdgeController",
112
+ # Utils
113
+ "TimeReference",
114
+ # Version
115
+ "__version__",
116
+ ]