Spaces:
Sleeping
Sleeping
Update
Browse files- client/js/src/video/types.ts +0 -1
- client/python/examples/basic_consumer.py +2 -2
- client/python/examples/basic_producer.py +4 -4
- client/python/examples/consumer_first_recorder.py +10 -16
- client/python/examples/context_manager_example.py +10 -10
- client/python/examples/producer_consumer_demo.py +5 -5
- client/python/examples/room_management.py +3 -3
- client/python/examples/video_consumer_example.py +2 -2
- client/python/examples/video_producer_example.py +4 -4
- client/python/src/transport_server_client/__pycache__/client.cpython-312.pyc +0 -0
- client/python/src/transport_server_client/client.py +2 -2
- client/python/src/transport_server_client/video/__pycache__/core.cpython-312.pyc +0 -0
- client/python/src/transport_server_client/video/core.py +2 -2
- client/python/tests/test_rest_api.py +4 -4
client/js/src/video/types.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
| 1 |
/**
|
| 2 |
* Type definitions for RobotHub TransportServer Video Client
|
| 3 |
-
* β
Fully synchronized with server-side models.py
|
| 4 |
*/
|
| 5 |
|
| 6 |
// ============= CORE TYPES =============
|
|
|
|
| 1 |
/**
|
| 2 |
* Type definitions for RobotHub TransportServer Video Client
|
|
|
|
| 3 |
*/
|
| 4 |
|
| 5 |
// ============= CORE TYPES =============
|
client/python/examples/basic_consumer.py
CHANGED
|
@@ -86,8 +86,8 @@ async def main():
|
|
| 86 |
logger.info(f"Received {len(received_updates)} joint updates")
|
| 87 |
logger.info(f"Received {len(received_states)} state syncs")
|
| 88 |
|
| 89 |
-
except Exception
|
| 90 |
-
logger.exception(
|
| 91 |
finally:
|
| 92 |
# Always disconnect
|
| 93 |
if consumer.is_connected():
|
|
|
|
| 86 |
logger.info(f"Received {len(received_updates)} joint updates")
|
| 87 |
logger.info(f"Received {len(received_states)} state syncs")
|
| 88 |
|
| 89 |
+
except Exception:
|
| 90 |
+
logger.exception("Exception: ")
|
| 91 |
finally:
|
| 92 |
# Always disconnect
|
| 93 |
if consumer.is_connected():
|
client/python/examples/basic_producer.py
CHANGED
|
@@ -76,8 +76,8 @@ async def main():
|
|
| 76 |
|
| 77 |
logger.info("Example completed successfully!")
|
| 78 |
|
| 79 |
-
except Exception
|
| 80 |
-
logger.exception(
|
| 81 |
finally:
|
| 82 |
# Always disconnect and cleanup
|
| 83 |
if producer.is_connected():
|
|
@@ -89,8 +89,8 @@ async def main():
|
|
| 89 |
try:
|
| 90 |
await producer.delete_room(workspace_id, room_id)
|
| 91 |
logger.info("Room cleaned up")
|
| 92 |
-
except Exception
|
| 93 |
-
logger.
|
| 94 |
|
| 95 |
|
| 96 |
if __name__ == "__main__":
|
|
|
|
| 76 |
|
| 77 |
logger.info("Example completed successfully!")
|
| 78 |
|
| 79 |
+
except Exception:
|
| 80 |
+
logger.exception("Error")
|
| 81 |
finally:
|
| 82 |
# Always disconnect and cleanup
|
| 83 |
if producer.is_connected():
|
|
|
|
| 89 |
try:
|
| 90 |
await producer.delete_room(workspace_id, room_id)
|
| 91 |
logger.info("Room cleaned up")
|
| 92 |
+
except Exception:
|
| 93 |
+
logger.exception("Failed to clean up room")
|
| 94 |
|
| 95 |
|
| 96 |
if __name__ == "__main__":
|
client/python/examples/consumer_first_recorder.py
CHANGED
|
@@ -122,8 +122,8 @@ class VideoRecorder:
|
|
| 122 |
f"π¬ Recording: {elapsed:.1f}s / {self.duration_seconds}s ({remaining:.1f}s remaining)"
|
| 123 |
)
|
| 124 |
|
| 125 |
-
except Exception
|
| 126 |
-
logger.exception(
|
| 127 |
|
| 128 |
return False
|
| 129 |
|
|
@@ -291,11 +291,8 @@ async def main():
|
|
| 291 |
else:
|
| 292 |
logger.warning("β οΈ No recording was made - producer may not have joined")
|
| 293 |
|
| 294 |
-
except Exception
|
| 295 |
-
logger.exception(
|
| 296 |
-
import traceback
|
| 297 |
-
|
| 298 |
-
traceback.print_exc()
|
| 299 |
|
| 300 |
finally:
|
| 301 |
# Cleanup
|
|
@@ -309,12 +306,12 @@ async def main():
|
|
| 309 |
try:
|
| 310 |
await consumer.delete_room(workspace_id, room_id)
|
| 311 |
logger.info("ποΈ Room cleaned up")
|
| 312 |
-
except Exception
|
| 313 |
-
logger.
|
| 314 |
|
| 315 |
logger.info("π Consumer disconnected successfully")
|
| 316 |
-
except Exception
|
| 317 |
-
logger.exception(
|
| 318 |
|
| 319 |
|
| 320 |
if __name__ == "__main__":
|
|
@@ -323,8 +320,5 @@ if __name__ == "__main__":
|
|
| 323 |
except KeyboardInterrupt:
|
| 324 |
logger.info("π Stopped by user")
|
| 325 |
logger.info("π Goodbye!")
|
| 326 |
-
except Exception
|
| 327 |
-
logger.exception(
|
| 328 |
-
import traceback
|
| 329 |
-
|
| 330 |
-
traceback.print_exc()
|
|
|
|
| 122 |
f"π¬ Recording: {elapsed:.1f}s / {self.duration_seconds}s ({remaining:.1f}s remaining)"
|
| 123 |
)
|
| 124 |
|
| 125 |
+
except Exception:
|
| 126 |
+
logger.exception("β Error adding frame to recording")
|
| 127 |
|
| 128 |
return False
|
| 129 |
|
|
|
|
| 291 |
else:
|
| 292 |
logger.warning("β οΈ No recording was made - producer may not have joined")
|
| 293 |
|
| 294 |
+
except Exception:
|
| 295 |
+
logger.exception("β Consumer-first recorder failed")
|
|
|
|
|
|
|
|
|
|
| 296 |
|
| 297 |
finally:
|
| 298 |
# Cleanup
|
|
|
|
| 306 |
try:
|
| 307 |
await consumer.delete_room(workspace_id, room_id)
|
| 308 |
logger.info("ποΈ Room cleaned up")
|
| 309 |
+
except Exception:
|
| 310 |
+
logger.exception("Failed to clean up room")
|
| 311 |
|
| 312 |
logger.info("π Consumer disconnected successfully")
|
| 313 |
+
except Exception:
|
| 314 |
+
logger.exception("Error during cleanup")
|
| 315 |
|
| 316 |
|
| 317 |
if __name__ == "__main__":
|
|
|
|
| 320 |
except KeyboardInterrupt:
|
| 321 |
logger.info("π Stopped by user")
|
| 322 |
logger.info("π Goodbye!")
|
| 323 |
+
except Exception:
|
| 324 |
+
logger.exception("π₯ Fatal error")
|
|
|
|
|
|
|
|
|
client/python/examples/context_manager_example.py
CHANGED
|
@@ -45,8 +45,8 @@ async def basic_context_manager_example():
|
|
| 45 |
try:
|
| 46 |
# This might fail if room doesn't exist
|
| 47 |
await producer.send_joint_update([{"name": "invalid", "value": 999.0}])
|
| 48 |
-
except Exception
|
| 49 |
-
logger.
|
| 50 |
|
| 51 |
# Clean up room before context exit
|
| 52 |
await producer.delete_room(workspace_id, room_id)
|
|
@@ -118,8 +118,8 @@ async def exception_handling_example():
|
|
| 118 |
logger.info(f"Sent update {i}")
|
| 119 |
await asyncio.sleep(0.1)
|
| 120 |
|
| 121 |
-
except ValueError
|
| 122 |
-
logger.exception(
|
| 123 |
logger.info("Context manager still ensures cleanup")
|
| 124 |
|
| 125 |
# Clean up room after exception
|
|
@@ -128,8 +128,8 @@ async def exception_handling_example():
|
|
| 128 |
temp_producer = RoboticsProducer("http://localhost:8000")
|
| 129 |
await temp_producer.delete_room(workspace_id, room_id)
|
| 130 |
logger.info("Room cleaned up after exception")
|
| 131 |
-
except Exception
|
| 132 |
-
logger.
|
| 133 |
|
| 134 |
logger.info("Exception handling example completed")
|
| 135 |
|
|
@@ -185,8 +185,8 @@ async def multiple_clients_example():
|
|
| 185 |
temp_producer = RoboticsProducer("http://localhost:8000")
|
| 186 |
await temp_producer.delete_room(workspace_id, room_id)
|
| 187 |
logger.info("Room cleaned up")
|
| 188 |
-
except Exception
|
| 189 |
-
logger.
|
| 190 |
|
| 191 |
logger.info("Multiple clients example completed")
|
| 192 |
|
|
@@ -203,8 +203,8 @@ async def main():
|
|
| 203 |
|
| 204 |
logger.info("\nβ
All context manager examples completed successfully!")
|
| 205 |
|
| 206 |
-
except Exception
|
| 207 |
-
logger.exception(
|
| 208 |
|
| 209 |
|
| 210 |
if __name__ == "__main__":
|
|
|
|
| 45 |
try:
|
| 46 |
# This might fail if room doesn't exist
|
| 47 |
await producer.send_joint_update([{"name": "invalid", "value": 999.0}])
|
| 48 |
+
except Exception:
|
| 49 |
+
logger.exception("Handled exception")
|
| 50 |
|
| 51 |
# Clean up room before context exit
|
| 52 |
await producer.delete_room(workspace_id, room_id)
|
|
|
|
| 118 |
logger.info(f"Sent update {i}")
|
| 119 |
await asyncio.sleep(0.1)
|
| 120 |
|
| 121 |
+
except ValueError:
|
| 122 |
+
logger.exception("Caught expected error")
|
| 123 |
logger.info("Context manager still ensures cleanup")
|
| 124 |
|
| 125 |
# Clean up room after exception
|
|
|
|
| 128 |
temp_producer = RoboticsProducer("http://localhost:8000")
|
| 129 |
await temp_producer.delete_room(workspace_id, room_id)
|
| 130 |
logger.info("Room cleaned up after exception")
|
| 131 |
+
except Exception:
|
| 132 |
+
logger.exception("Failed to clean up room")
|
| 133 |
|
| 134 |
logger.info("Exception handling example completed")
|
| 135 |
|
|
|
|
| 185 |
temp_producer = RoboticsProducer("http://localhost:8000")
|
| 186 |
await temp_producer.delete_room(workspace_id, room_id)
|
| 187 |
logger.info("Room cleaned up")
|
| 188 |
+
except Exception:
|
| 189 |
+
logger.exception("Failed to clean up room")
|
| 190 |
|
| 191 |
logger.info("Multiple clients example completed")
|
| 192 |
|
|
|
|
| 203 |
|
| 204 |
logger.info("\nβ
All context manager examples completed successfully!")
|
| 205 |
|
| 206 |
+
except Exception:
|
| 207 |
+
logger.exception("β Example failed")
|
| 208 |
|
| 209 |
|
| 210 |
if __name__ == "__main__":
|
client/python/examples/producer_consumer_demo.py
CHANGED
|
@@ -97,7 +97,7 @@ async def simulate_robot_movement(producer: RoboticsProducer):
|
|
| 97 |
for step in range(20): # 20 movement steps
|
| 98 |
# Occasionally set new random targets
|
| 99 |
if step % 5 == 0:
|
| 100 |
-
for
|
| 101 |
joint_data["target"] = random.uniform(
|
| 102 |
joint_data["min"], joint_data["max"]
|
| 103 |
)
|
|
@@ -203,8 +203,8 @@ async def main():
|
|
| 203 |
|
| 204 |
logger.info("Demo completed successfully!")
|
| 205 |
|
| 206 |
-
except Exception
|
| 207 |
-
logger.exception(
|
| 208 |
finally:
|
| 209 |
# Cleanup
|
| 210 |
logger.info("Cleaning up...")
|
|
@@ -222,8 +222,8 @@ async def main():
|
|
| 222 |
try:
|
| 223 |
await producer.delete_room(workspace_id, room_id)
|
| 224 |
logger.info("Room cleaned up")
|
| 225 |
-
except Exception
|
| 226 |
-
logger.
|
| 227 |
|
| 228 |
logger.info("Demo cleanup completed")
|
| 229 |
|
|
|
|
| 97 |
for step in range(20): # 20 movement steps
|
| 98 |
# Occasionally set new random targets
|
| 99 |
if step % 5 == 0:
|
| 100 |
+
for joint_data in joints.values():
|
| 101 |
joint_data["target"] = random.uniform(
|
| 102 |
joint_data["min"], joint_data["max"]
|
| 103 |
)
|
|
|
|
| 203 |
|
| 204 |
logger.info("Demo completed successfully!")
|
| 205 |
|
| 206 |
+
except Exception:
|
| 207 |
+
logger.exception("Demo error")
|
| 208 |
finally:
|
| 209 |
# Cleanup
|
| 210 |
logger.info("Cleaning up...")
|
|
|
|
| 222 |
try:
|
| 223 |
await producer.delete_room(workspace_id, room_id)
|
| 224 |
logger.info("Room cleaned up")
|
| 225 |
+
except Exception:
|
| 226 |
+
logger.exception("Failed to clean up room")
|
| 227 |
|
| 228 |
logger.info("Demo cleanup completed")
|
| 229 |
|
client/python/examples/room_management.py
CHANGED
|
@@ -27,7 +27,7 @@ async def main():
|
|
| 27 |
|
| 28 |
try:
|
| 29 |
# Generate a workspace ID for this demo
|
| 30 |
-
workspace_id = client.
|
| 31 |
logger.info(f"Using workspace: {workspace_id}")
|
| 32 |
|
| 33 |
# List existing rooms in this workspace
|
|
@@ -93,8 +93,8 @@ async def main():
|
|
| 93 |
|
| 94 |
logger.info("\nRoom management example completed!")
|
| 95 |
|
| 96 |
-
except Exception
|
| 97 |
-
logger.exception(
|
| 98 |
|
| 99 |
|
| 100 |
if __name__ == "__main__":
|
|
|
|
| 27 |
|
| 28 |
try:
|
| 29 |
# Generate a workspace ID for this demo
|
| 30 |
+
workspace_id = client.generate_workspace_id()
|
| 31 |
logger.info(f"Using workspace: {workspace_id}")
|
| 32 |
|
| 33 |
# List existing rooms in this workspace
|
|
|
|
| 93 |
|
| 94 |
logger.info("\nRoom management example completed!")
|
| 95 |
|
| 96 |
+
except Exception:
|
| 97 |
+
logger.exception("Error")
|
| 98 |
|
| 99 |
|
| 100 |
if __name__ == "__main__":
|
client/python/examples/video_consumer_example.py
CHANGED
|
@@ -80,8 +80,8 @@ class VideoFrameHandler:
|
|
| 80 |
|
| 81 |
self.last_log_time = current_time
|
| 82 |
|
| 83 |
-
except Exception
|
| 84 |
-
logger.exception(f"β Error handling frame {self.frame_count}
|
| 85 |
|
| 86 |
|
| 87 |
async def main():
|
|
|
|
| 80 |
|
| 81 |
self.last_log_time = current_time
|
| 82 |
|
| 83 |
+
except Exception:
|
| 84 |
+
logger.exception(f"β Error handling frame {self.frame_count}")
|
| 85 |
|
| 86 |
|
| 87 |
async def main():
|
client/python/examples/video_producer_example.py
CHANGED
|
@@ -242,8 +242,8 @@ async def screen_share_example():
|
|
| 242 |
# Share for demo duration
|
| 243 |
await asyncio.sleep(20)
|
| 244 |
|
| 245 |
-
except Exception
|
| 246 |
-
logger.exception(
|
| 247 |
finally:
|
| 248 |
if "producer" in locals():
|
| 249 |
await producer.disconnect()
|
|
@@ -251,8 +251,8 @@ async def screen_share_example():
|
|
| 251 |
try:
|
| 252 |
await producer.delete_room(workspace_id, room_id)
|
| 253 |
logger.info("ποΈ Room cleaned up")
|
| 254 |
-
except Exception
|
| 255 |
-
logger.
|
| 256 |
|
| 257 |
|
| 258 |
if __name__ == "__main__":
|
|
|
|
| 242 |
# Share for demo duration
|
| 243 |
await asyncio.sleep(20)
|
| 244 |
|
| 245 |
+
except Exception:
|
| 246 |
+
logger.exception("β Screen share error")
|
| 247 |
finally:
|
| 248 |
if "producer" in locals():
|
| 249 |
await producer.disconnect()
|
|
|
|
| 251 |
try:
|
| 252 |
await producer.delete_room(workspace_id, room_id)
|
| 253 |
logger.info("ποΈ Room cleaned up")
|
| 254 |
+
except Exception:
|
| 255 |
+
logger.exception("Failed to clean up room")
|
| 256 |
|
| 257 |
|
| 258 |
if __name__ == "__main__":
|
client/python/src/transport_server_client/__pycache__/client.cpython-312.pyc
CHANGED
|
Binary files a/client/python/src/transport_server_client/__pycache__/client.cpython-312.pyc and b/client/python/src/transport_server_client/__pycache__/client.cpython-312.pyc differ
|
|
|
client/python/src/transport_server_client/client.py
CHANGED
|
@@ -47,7 +47,7 @@ class RoboticsClientCore:
|
|
| 47 |
) -> tuple[str, str]:
|
| 48 |
"""Create a new room and return (workspace_id, room_id)"""
|
| 49 |
# Generate workspace ID if not provided
|
| 50 |
-
final_workspace_id = workspace_id or self.
|
| 51 |
|
| 52 |
payload = {}
|
| 53 |
if room_id:
|
|
@@ -304,7 +304,7 @@ class RoboticsClientCore:
|
|
| 304 |
|
| 305 |
# ============= WORKSPACE HELPERS =============
|
| 306 |
|
| 307 |
-
def
|
| 308 |
"""Generate a UUID-like workspace ID"""
|
| 309 |
import uuid
|
| 310 |
|
|
|
|
| 47 |
) -> tuple[str, str]:
|
| 48 |
"""Create a new room and return (workspace_id, room_id)"""
|
| 49 |
# Generate workspace ID if not provided
|
| 50 |
+
final_workspace_id = workspace_id or self.generate_workspace_id()
|
| 51 |
|
| 52 |
payload = {}
|
| 53 |
if room_id:
|
|
|
|
| 304 |
|
| 305 |
# ============= WORKSPACE HELPERS =============
|
| 306 |
|
| 307 |
+
def generate_workspace_id(self) -> str:
|
| 308 |
"""Generate a UUID-like workspace ID"""
|
| 309 |
import uuid
|
| 310 |
|
client/python/src/transport_server_client/video/__pycache__/core.cpython-312.pyc
CHANGED
|
Binary files a/client/python/src/transport_server_client/video/__pycache__/core.cpython-312.pyc and b/client/python/src/transport_server_client/video/__pycache__/core.cpython-312.pyc differ
|
|
|
client/python/src/transport_server_client/video/core.py
CHANGED
|
@@ -122,7 +122,7 @@ class VideoClientCore:
|
|
| 122 |
) -> tuple[str, str]:
|
| 123 |
"""Create a new room and return (workspace_id, room_id)"""
|
| 124 |
# Generate workspace ID if not provided
|
| 125 |
-
final_workspace_id = workspace_id or self.
|
| 126 |
|
| 127 |
payload = {}
|
| 128 |
if room_id:
|
|
@@ -726,7 +726,7 @@ class VideoClientCore:
|
|
| 726 |
|
| 727 |
# ============= WORKSPACE HELPERS =============
|
| 728 |
|
| 729 |
-
def
|
| 730 |
"""Generate a UUID-like workspace ID"""
|
| 731 |
import uuid
|
| 732 |
|
|
|
|
| 122 |
) -> tuple[str, str]:
|
| 123 |
"""Create a new room and return (workspace_id, room_id)"""
|
| 124 |
# Generate workspace ID if not provided
|
| 125 |
+
final_workspace_id = workspace_id or self.generate_workspace_id()
|
| 126 |
|
| 127 |
payload = {}
|
| 128 |
if room_id:
|
|
|
|
| 726 |
|
| 727 |
# ============= WORKSPACE HELPERS =============
|
| 728 |
|
| 729 |
+
def generate_workspace_id(self) -> str:
|
| 730 |
"""Generate a UUID-like workspace ID"""
|
| 731 |
import uuid
|
| 732 |
|
client/python/tests/test_rest_api.py
CHANGED
|
@@ -17,7 +17,7 @@ class TestRestAPI:
|
|
| 17 |
async def test_list_rooms_empty(self, producer):
|
| 18 |
"""Test listing rooms when no rooms exist."""
|
| 19 |
# Use a temporary workspace ID
|
| 20 |
-
workspace_id = producer.
|
| 21 |
rooms = await producer.list_rooms(workspace_id)
|
| 22 |
assert isinstance(rooms, list)
|
| 23 |
|
|
@@ -129,7 +129,7 @@ class TestRestAPI:
|
|
| 129 |
@pytest.mark.asyncio
|
| 130 |
async def test_delete_nonexistent_room(self, producer):
|
| 131 |
"""Test deleting a room that doesn't exist."""
|
| 132 |
-
workspace_id = producer.
|
| 133 |
fake_room_id = "nonexistent-room-id"
|
| 134 |
success = await producer.delete_room(workspace_id, fake_room_id)
|
| 135 |
assert success is False
|
|
@@ -137,7 +137,7 @@ class TestRestAPI:
|
|
| 137 |
@pytest.mark.asyncio
|
| 138 |
async def test_get_room_info_nonexistent(self, producer):
|
| 139 |
"""Test getting info for a room that doesn't exist."""
|
| 140 |
-
workspace_id = producer.
|
| 141 |
fake_room_id = "nonexistent-room-id"
|
| 142 |
|
| 143 |
# This should raise an exception or return error info
|
|
@@ -151,7 +151,7 @@ class TestRestAPI:
|
|
| 151 |
@pytest.mark.asyncio
|
| 152 |
async def test_get_room_state_nonexistent(self, producer):
|
| 153 |
"""Test getting state for a room that doesn't exist."""
|
| 154 |
-
workspace_id = producer.
|
| 155 |
fake_room_id = "nonexistent-room-id"
|
| 156 |
|
| 157 |
# This should raise an exception or return error info
|
|
|
|
| 17 |
async def test_list_rooms_empty(self, producer):
|
| 18 |
"""Test listing rooms when no rooms exist."""
|
| 19 |
# Use a temporary workspace ID
|
| 20 |
+
workspace_id = producer.generate_workspace_id()
|
| 21 |
rooms = await producer.list_rooms(workspace_id)
|
| 22 |
assert isinstance(rooms, list)
|
| 23 |
|
|
|
|
| 129 |
@pytest.mark.asyncio
|
| 130 |
async def test_delete_nonexistent_room(self, producer):
|
| 131 |
"""Test deleting a room that doesn't exist."""
|
| 132 |
+
workspace_id = producer.generate_workspace_id()
|
| 133 |
fake_room_id = "nonexistent-room-id"
|
| 134 |
success = await producer.delete_room(workspace_id, fake_room_id)
|
| 135 |
assert success is False
|
|
|
|
| 137 |
@pytest.mark.asyncio
|
| 138 |
async def test_get_room_info_nonexistent(self, producer):
|
| 139 |
"""Test getting info for a room that doesn't exist."""
|
| 140 |
+
workspace_id = producer.generate_workspace_id()
|
| 141 |
fake_room_id = "nonexistent-room-id"
|
| 142 |
|
| 143 |
# This should raise an exception or return error info
|
|
|
|
| 151 |
@pytest.mark.asyncio
|
| 152 |
async def test_get_room_state_nonexistent(self, producer):
|
| 153 |
"""Test getting state for a room that doesn't exist."""
|
| 154 |
+
workspace_id = producer.generate_workspace_id()
|
| 155 |
fake_room_id = "nonexistent-room-id"
|
| 156 |
|
| 157 |
# This should raise an exception or return error info
|