antioch-py 2.0.6__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.

Potentially problematic release.


This version of antioch-py might be problematic. Click here for more details.

Files changed (99) hide show
  1. antioch/__init__.py +0 -0
  2. antioch/message.py +87 -0
  3. antioch/module/__init__.py +53 -0
  4. antioch/module/clock.py +62 -0
  5. antioch/module/execution.py +278 -0
  6. antioch/module/input.py +127 -0
  7. antioch/module/module.py +218 -0
  8. antioch/module/node.py +357 -0
  9. antioch/module/token.py +42 -0
  10. antioch/session/__init__.py +150 -0
  11. antioch/session/ark.py +504 -0
  12. antioch/session/asset.py +65 -0
  13. antioch/session/error.py +80 -0
  14. antioch/session/record.py +158 -0
  15. antioch/session/scene.py +1521 -0
  16. antioch/session/session.py +220 -0
  17. antioch/session/task.py +323 -0
  18. antioch/session/views/__init__.py +40 -0
  19. antioch/session/views/animation.py +189 -0
  20. antioch/session/views/articulation.py +245 -0
  21. antioch/session/views/basis_curve.py +186 -0
  22. antioch/session/views/camera.py +92 -0
  23. antioch/session/views/collision.py +75 -0
  24. antioch/session/views/geometry.py +74 -0
  25. antioch/session/views/ground_plane.py +63 -0
  26. antioch/session/views/imu.py +73 -0
  27. antioch/session/views/joint.py +64 -0
  28. antioch/session/views/light.py +175 -0
  29. antioch/session/views/pir_sensor.py +140 -0
  30. antioch/session/views/radar.py +73 -0
  31. antioch/session/views/rigid_body.py +282 -0
  32. antioch/session/views/xform.py +119 -0
  33. antioch_py-2.0.6.dist-info/METADATA +115 -0
  34. antioch_py-2.0.6.dist-info/RECORD +99 -0
  35. antioch_py-2.0.6.dist-info/WHEEL +5 -0
  36. antioch_py-2.0.6.dist-info/entry_points.txt +2 -0
  37. antioch_py-2.0.6.dist-info/top_level.txt +2 -0
  38. common/__init__.py +0 -0
  39. common/ark/__init__.py +60 -0
  40. common/ark/ark.py +128 -0
  41. common/ark/hardware.py +121 -0
  42. common/ark/kinematics.py +31 -0
  43. common/ark/module.py +85 -0
  44. common/ark/node.py +94 -0
  45. common/ark/scheduler.py +439 -0
  46. common/ark/sim.py +33 -0
  47. common/assets/__init__.py +3 -0
  48. common/constants.py +47 -0
  49. common/core/__init__.py +52 -0
  50. common/core/agent.py +296 -0
  51. common/core/auth.py +305 -0
  52. common/core/registry.py +331 -0
  53. common/core/task.py +36 -0
  54. common/message/__init__.py +59 -0
  55. common/message/annotation.py +89 -0
  56. common/message/array.py +500 -0
  57. common/message/base.py +517 -0
  58. common/message/camera.py +91 -0
  59. common/message/color.py +139 -0
  60. common/message/frame.py +50 -0
  61. common/message/image.py +171 -0
  62. common/message/imu.py +14 -0
  63. common/message/joint.py +47 -0
  64. common/message/log.py +31 -0
  65. common/message/pir.py +16 -0
  66. common/message/point.py +109 -0
  67. common/message/point_cloud.py +63 -0
  68. common/message/pose.py +148 -0
  69. common/message/quaternion.py +273 -0
  70. common/message/radar.py +58 -0
  71. common/message/types.py +37 -0
  72. common/message/vector.py +786 -0
  73. common/rome/__init__.py +9 -0
  74. common/rome/client.py +430 -0
  75. common/rome/error.py +16 -0
  76. common/session/__init__.py +54 -0
  77. common/session/environment.py +31 -0
  78. common/session/sim.py +240 -0
  79. common/session/views/__init__.py +263 -0
  80. common/session/views/animation.py +73 -0
  81. common/session/views/articulation.py +184 -0
  82. common/session/views/basis_curve.py +102 -0
  83. common/session/views/camera.py +147 -0
  84. common/session/views/collision.py +59 -0
  85. common/session/views/geometry.py +102 -0
  86. common/session/views/ground_plane.py +41 -0
  87. common/session/views/imu.py +66 -0
  88. common/session/views/joint.py +81 -0
  89. common/session/views/light.py +96 -0
  90. common/session/views/pir_sensor.py +115 -0
  91. common/session/views/radar.py +82 -0
  92. common/session/views/rigid_body.py +236 -0
  93. common/session/views/viewport.py +21 -0
  94. common/session/views/xform.py +39 -0
  95. common/utils/__init__.py +4 -0
  96. common/utils/comms.py +571 -0
  97. common/utils/logger.py +123 -0
  98. common/utils/time.py +42 -0
  99. common/utils/usd.py +12 -0
@@ -0,0 +1,65 @@
1
+ from pathlib import Path
2
+
3
+ from antioch.session.session import SessionContainer
4
+ from common.ark import AssetReference
5
+ from common.core import list_local_assets, list_remote_assets, pull_remote_asset
6
+
7
+
8
+ class Asset(SessionContainer):
9
+ """
10
+ Provides methods for interacting with the asset registry.
11
+
12
+ All methods handle authentication automatically using the current session's auth context.
13
+ This is a lightweight wrapper around registry functions that manages auth token complexity.
14
+
15
+ Example:
16
+ # List local assets
17
+ local_assets = Asset.list_local()
18
+
19
+ # List remote assets (requires auth)
20
+ remote_assets = Asset.list_remote()
21
+
22
+ # Pull an asset from remote registry
23
+ asset_path = Asset.pull(name="my_asset", version="1.0.0")
24
+ """
25
+
26
+ @staticmethod
27
+ def list_local() -> list[AssetReference]:
28
+ """
29
+ List all locally available assets.
30
+
31
+ :return: List of AssetReference objects from local storage.
32
+ """
33
+
34
+ return list_local_assets()
35
+
36
+ @staticmethod
37
+ def list_remote() -> list[AssetReference]:
38
+ """
39
+ List all assets from remote registry.
40
+
41
+ Requires authentication. Call session.login() first if not authenticated.
42
+
43
+ :return: List of AssetReference objects from remote registry.
44
+ :raises SessionAuthError: If not authenticated.
45
+ """
46
+
47
+ return list_remote_assets()
48
+
49
+ @staticmethod
50
+ def pull(name: str, version: str, overwrite: bool = False, show_progress: bool = True) -> Path:
51
+ """
52
+ Pull an asset from remote registry to local storage.
53
+
54
+ Requires authentication. Call session.login() first if not authenticated.
55
+ If the asset already exists locally, returns the existing path unless overwrite=True.
56
+
57
+ :param name: Name of the asset.
58
+ :param version: Version of the asset.
59
+ :param overwrite: Overwrite local asset if it already exists.
60
+ :param show_progress: Show download progress bar.
61
+ :return: Path to the downloaded asset file.
62
+ :raises SessionAuthError: If not authenticated.
63
+ """
64
+
65
+ return pull_remote_asset(name=name, version=version, overwrite=overwrite, show_progress=show_progress)
@@ -0,0 +1,80 @@
1
+ class SessionError(Exception):
2
+ """
3
+ Base exception for all session-related errors.
4
+ """
5
+
6
+
7
+ class SessionSimRpcNotConnectedError(SessionError):
8
+ """
9
+ Raised when the Sim RPC server is not reachable.
10
+ """
11
+
12
+
13
+ class SessionSimRpcInterruptedError(SessionError):
14
+ """
15
+ Raised when the Sim RPC is interrupted.
16
+ """
17
+
18
+
19
+ class SessionSimRpcClientError(SessionError):
20
+ """
21
+ Raised when the Sim RPC server returns a client error (user error).
22
+ """
23
+
24
+
25
+ class SessionSimRpcInternalError(SessionError):
26
+ """
27
+ Raised when the Sim RPC server returns an internal error with traceback.
28
+ """
29
+
30
+ def __init__(self, message: str, traceback: str | None = None):
31
+ super().__init__(message)
32
+ self.traceback = traceback
33
+
34
+
35
+ class SessionAuthError(SessionError):
36
+ """
37
+ Raised when authentication fails.
38
+ """
39
+
40
+
41
+ class SessionAgentError(SessionError):
42
+ """
43
+ Raised when an agent operation fails (start/stop ark, telemetry, etc).
44
+ """
45
+
46
+
47
+ class SessionTaskError(SessionError):
48
+ """
49
+ Raised when a task operation fails (invalid lifecycle, etc).
50
+ """
51
+
52
+
53
+ class SessionArkError(SessionError):
54
+ """
55
+ Raised when an Ark operation fails (loading, stepping, hardware access, etc).
56
+ """
57
+
58
+
59
+ class SessionHardwareError(SessionError):
60
+ """
61
+ Raised when a hardware operation fails.
62
+ """
63
+
64
+
65
+ class SessionAssetError(SessionError):
66
+ """
67
+ Raised when an asset operation fails.
68
+ """
69
+
70
+
71
+ class SessionRecordError(SessionError):
72
+ """
73
+ Raised when a recording operation fails (node output recording, etc).
74
+ """
75
+
76
+
77
+ class SessionValidationError(SessionError):
78
+ """
79
+ Raised when input validation fails (user error).
80
+ """
@@ -0,0 +1,158 @@
1
+ from collections import deque
2
+ from threading import Lock
3
+ from typing import TypeVar, overload
4
+
5
+ from antioch.module.node import TOKEN_OUTPUT_PATH
6
+ from antioch.module.token import Token, TokenType
7
+ from antioch.session.error import SessionRecordError
8
+ from common.ark.ark import Ark as ArkDefinition
9
+ from common.message import Message
10
+ from common.utils.comms import CommsSession
11
+
12
+ T = TypeVar("T", bound=Message)
13
+
14
+
15
+ class NodeOutputRecorder:
16
+ """
17
+ Records node outputs by subscribing to token stream with filtering and buffering.
18
+
19
+ Maintains a circular buffer of recent tokens using async callback for efficient updates.
20
+ Validates that module/node/output exists in the Ark definition.
21
+ """
22
+
23
+ def __init__(
24
+ self,
25
+ comms: CommsSession,
26
+ ark_def: ArkDefinition,
27
+ module_name: str,
28
+ node_name: str,
29
+ output_name: str,
30
+ token_type: TokenType | None = TokenType.DATA,
31
+ last_n: int = 10,
32
+ ):
33
+ """
34
+ Initialize node output recorder with validation and subscription.
35
+
36
+ :param comms: Communication session for subscribing to token stream.
37
+ :param ark_def: Ark definition used to validate module/node/output exists.
38
+ :param module_name: Name of module containing the node.
39
+ :param node_name: Name of node containing the output.
40
+ :param output_name: Name of output to record tokens from.
41
+ :param token_type: Token type to filter (None records all types).
42
+ :param last_n: Maximum number of recent tokens to buffer.
43
+ :raises SessionRecordError: If module, node, or output doesn't exist in Ark.
44
+ """
45
+
46
+ # Validate module exists
47
+ module = next((m for m in ark_def.modules if m.name == module_name), None)
48
+ if module is None:
49
+ raise SessionRecordError(f"Module '{module_name}' not found in Ark")
50
+
51
+ # Validate node exists
52
+ node = module.nodes.get(node_name)
53
+ if node is None:
54
+ raise SessionRecordError(f"Node '{node_name}' not found in module '{module_name}'")
55
+
56
+ # Validate output exists
57
+ output = node.outputs.get(output_name)
58
+ if output is None:
59
+ raise SessionRecordError(f"Output '{output_name}' not found in node '{module_name}/{node_name}'")
60
+
61
+ self._token_type = token_type
62
+ self._buffer: deque[Token] = deque(maxlen=last_n)
63
+ self._buffer_lock = Lock()
64
+ self._subscriber = comms.declare_callback_subscriber(TOKEN_OUTPUT_PATH.format(path=output.path), self._on_token)
65
+
66
+ @overload
67
+ def next(self, message_cls: type[T]) -> T | None: ...
68
+
69
+ @overload
70
+ def next(self, message_cls: None = None) -> dict | None: ...
71
+
72
+ def next(self, message_cls: type[T] | None = None) -> T | dict | None:
73
+ """
74
+ Return next deserialized payload in order and remove from buffer.
75
+
76
+ :param message_cls: Message class to deserialize payload (None for generic JSON dict).
77
+ :return: Deserialized payload, or None if buffer empty.
78
+ """
79
+
80
+ token = self.next_token()
81
+ if token is None:
82
+ return None
83
+ return self._deserialize_payload(token, message_cls)
84
+
85
+ @overload
86
+ def latest(self, message_cls: type[T]) -> T | None: ...
87
+
88
+ @overload
89
+ def latest(self, message_cls: None = None) -> dict | None: ...
90
+
91
+ def latest(self, message_cls: type[T] | None = None) -> T | dict | None:
92
+ """
93
+ Return latest deserialized payload and clear entire buffer.
94
+
95
+ :param message_cls: Message class to deserialize payload (None for generic JSON dict).
96
+ :return: Deserialized payload, or None if buffer empty.
97
+ """
98
+
99
+ token = self.latest_token()
100
+ if token is None:
101
+ return None
102
+ return self._deserialize_payload(token, message_cls)
103
+
104
+ def next_token(self) -> Token | None:
105
+ """
106
+ Return next token in order and remove from buffer.
107
+
108
+ :return: Token, or None if buffer empty.
109
+ """
110
+
111
+ with self._buffer_lock:
112
+ if not self._buffer:
113
+ return None
114
+ return self._buffer.popleft()
115
+
116
+ def latest_token(self) -> Token | None:
117
+ """
118
+ Return latest buffered token and clear entire buffer.
119
+
120
+ :return: Token, or None if buffer empty.
121
+ """
122
+
123
+ with self._buffer_lock:
124
+ if not self._buffer:
125
+ return None
126
+ token = self._buffer[-1]
127
+ self._buffer.clear()
128
+ return token
129
+
130
+ def _on_token(self, sample) -> None:
131
+ """
132
+ Callback invoked when token arrives, filters by type and adds to buffer.
133
+
134
+ :param sample: Zenoh sample containing token payload.
135
+ """
136
+
137
+ token = Token.unpack(sample.payload.to_bytes())
138
+ if self._token_type is not None and token.status != self._token_type:
139
+ return
140
+
141
+ with self._buffer_lock:
142
+ self._buffer.append(token)
143
+
144
+ def _deserialize_payload(self, token: Token, message_cls: type[T] | None) -> T | dict | None:
145
+ """
146
+ Deserialize token payload as specific message type or generic JSON dict.
147
+
148
+ :param token: Token containing payload to deserialize.
149
+ :param message_cls: Message class to deserialize as (None for generic JSON).
150
+ :return: Deserialized payload.
151
+ """
152
+
153
+ if token.payload is None:
154
+ return None
155
+ elif message_cls is None:
156
+ return Message.extract_data_as_json(token.payload)
157
+ else:
158
+ return message_cls.unpack(token.payload)