antioch-py 1.9.7__tar.gz → 2.0.2__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 antioch-py might be problematic. Click here for more details.
- antioch_py-2.0.2/PKG-INFO +249 -0
- antioch_py-2.0.2/antioch_py.egg-info/PKG-INFO +249 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/pyproject.toml +28 -3
- antioch_py-1.9.7/PKG-INFO +0 -24
- antioch_py-1.9.7/antioch_py.egg-info/PKG-INFO +0 -24
- {antioch_py-1.9.7 → antioch_py-2.0.2}/README.md +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/message.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/module/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/module/clock.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/module/execution.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/module/input.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/module/module.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/module/node.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/module/token.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/ark.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/asset.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/error.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/record.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/scene.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/session.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/task.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/animation.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/articulation.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/basis_curve.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/camera.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/collision.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/geometry.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/ground_plane.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/imu.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/joint.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/light.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/pir_sensor.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/radar.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/rigid_body.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch/session/views/xform.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch_py.egg-info/SOURCES.txt +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch_py.egg-info/dependency_links.txt +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch_py.egg-info/entry_points.txt +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch_py.egg-info/requires.txt +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/antioch_py.egg-info/top_level.txt +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/ark/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/ark/ark.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/ark/hardware.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/ark/kinematics.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/ark/module.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/ark/node.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/ark/scheduler.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/ark/sim.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/assets/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/constants.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/core/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/core/agent.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/core/auth.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/core/registry.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/core/task.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/annotation.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/array.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/base.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/camera.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/color.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/frame.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/image.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/imu.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/joint.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/log.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/pir.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/point.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/point_cloud.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/pose.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/quaternion.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/radar.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/types.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/message/vector.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/rome/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/rome/client.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/rome/error.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/environment.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/sim.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/animation.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/articulation.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/basis_curve.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/camera.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/collision.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/geometry.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/ground_plane.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/imu.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/joint.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/light.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/pir_sensor.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/radar.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/rigid_body.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/viewport.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/session/views/xform.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/utils/__init__.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/utils/comms.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/utils/logger.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/utils/time.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/common/utils/usd.py +0 -0
- {antioch_py-1.9.7 → antioch_py-2.0.2}/setup.cfg +0 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: antioch-py
|
|
3
|
+
Version: 2.0.2
|
|
4
|
+
Summary: The Antioch Python SDK
|
|
5
|
+
Author-email: Antioch Robotics <support@antioch.dev>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://antioch.com
|
|
8
|
+
Keywords: robotics,simulation,middleware,sdk
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Requires-Python: <3.13,>=3.12
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: click>=8.0.0
|
|
18
|
+
Requires-Dist: click>=8.3.0
|
|
19
|
+
Requires-Dist: eclipse-zenoh>=1.5.0
|
|
20
|
+
Requires-Dist: google-cloud-artifact-registry>=1.16.1
|
|
21
|
+
Requires-Dist: httpx>=0.27.0
|
|
22
|
+
Requires-Dist: loguru>=0.7.3
|
|
23
|
+
Requires-Dist: msgpack==1.1.1
|
|
24
|
+
Requires-Dist: msgpack>=1.1.1
|
|
25
|
+
Requires-Dist: numpy==1.26.0
|
|
26
|
+
Requires-Dist: ormsgpack>=1.6.0
|
|
27
|
+
Requires-Dist: pydantic>=2.11.6
|
|
28
|
+
Requires-Dist: pydantic>=2.11.7
|
|
29
|
+
Requires-Dist: python-on-whales>=0.78.0
|
|
30
|
+
Requires-Dist: pyyaml>=6.0.2
|
|
31
|
+
Requires-Dist: requests>=2.32.0
|
|
32
|
+
Requires-Dist: scipy==1.15.3
|
|
33
|
+
Requires-Dist: sortedcontainers-stubs>=2.4.3
|
|
34
|
+
Requires-Dist: sortedcontainers>=2.4.0
|
|
35
|
+
Requires-Dist: tqdm>=4.67.1
|
|
36
|
+
|
|
37
|
+
# Antioch Python
|
|
38
|
+
|
|
39
|
+
Python client library for the Antioch middleware platform.
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
Authenticate your local environment with GCP via the Google Cloud CLI:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
gcloud auth login # Login to Google Cloud
|
|
47
|
+
gcloud config set project proof-of-concept-staging-9072 # Set the correct project
|
|
48
|
+
gcloud auth application-default login # Create app credentials
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This project uses [uv](https://github.com/astral-sh/uv), a fast Python package and project manager. Install it and set up authentication:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Install uv
|
|
55
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
56
|
+
|
|
57
|
+
# Install keyring authentication globally for uv
|
|
58
|
+
uv tool install keyring --with keyrings.google-artifactregistry-auth
|
|
59
|
+
|
|
60
|
+
# Install all default groups in one step
|
|
61
|
+
uv sync
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Install the pre-commit hooks to auto-run `uv sync` and `ruff format` on Git commit:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
uv run pre-commit install
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Usage
|
|
71
|
+
|
|
72
|
+
The Antioch Python client builds both Docker images that can be used and a Python package.
|
|
73
|
+
|
|
74
|
+
## Docker Images
|
|
75
|
+
|
|
76
|
+
We have 2 Docker images currently
|
|
77
|
+
|
|
78
|
+
### Standard Image (`antioch-py:latest`)
|
|
79
|
+
|
|
80
|
+
- Base: `python:3.12-slim`
|
|
81
|
+
- Sidecar binary at `/usr/local/bin/sidecar`
|
|
82
|
+
- antioch-py package pre-installed
|
|
83
|
+
- Python 3.12 virtual environment with pip
|
|
84
|
+
- Runs as root for maximum compatibility
|
|
85
|
+
|
|
86
|
+
Build locally using
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
./build-image.sh
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### ROS Image (`antioch-py-ros:latest`)
|
|
93
|
+
|
|
94
|
+
- Base: `osrf/ros:jazzy-desktop`
|
|
95
|
+
- All features of the standard image
|
|
96
|
+
- Full ROS 2 Jazzy desktop environment
|
|
97
|
+
- ROS 2 Python packages and tools pre-installed
|
|
98
|
+
- Ideal for robotics applications requiring ROS integration
|
|
99
|
+
|
|
100
|
+
NOTE: not included in cloudbuild currently
|
|
101
|
+
|
|
102
|
+
Build locally using
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
./build-image.sh --variant ros-jazzy
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Usage
|
|
109
|
+
|
|
110
|
+
For standard Python modules:
|
|
111
|
+
|
|
112
|
+
```dockerfile
|
|
113
|
+
FROM antioch-py:latest
|
|
114
|
+
|
|
115
|
+
# Install any additional packages you need
|
|
116
|
+
RUN pip install opencv-python-headless numpy
|
|
117
|
+
|
|
118
|
+
# Copy your module entrypoint
|
|
119
|
+
# The sidecar will automatically run your module.py file
|
|
120
|
+
COPY module.py .
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
For ROS-enabled modules:
|
|
124
|
+
|
|
125
|
+
```dockerfile
|
|
126
|
+
FROM antioch-py-ros:latest
|
|
127
|
+
|
|
128
|
+
# Install ROS-specific packages if needed
|
|
129
|
+
RUN apt-get update && apt-get install -y ros-jazzy-cv-bridge
|
|
130
|
+
|
|
131
|
+
# You will probably need to source your ROS modules / install
|
|
132
|
+
# To ensure your ROS environment is available to your module, source the ROS setup script before running the sidecar.
|
|
133
|
+
# For example, you can add the following to your Dockerfile:
|
|
134
|
+
RUN echo "source /opt/ros/jazzy/setup.bash" >> /etc/profile.d/ros.sh
|
|
135
|
+
SHELL ["/bin/bash", "-c"]
|
|
136
|
+
|
|
137
|
+
# If you have a custom ROS workspace, source its setup script as well:
|
|
138
|
+
# RUN echo "source /workspace/install/setup.bash" >> /etc/profile.d/ros.sh
|
|
139
|
+
|
|
140
|
+
# The sidecar will automatically run your module.py file in the ROS environment.
|
|
141
|
+
COPY module.py .
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Testing Modules
|
|
145
|
+
|
|
146
|
+
Antioch provides a test framework for testing modules in isolation without requiring a full deployment. The `ModuleTestHarness` runs your module in a separate process and communicates with it using the standard Antioch protocol.
|
|
147
|
+
|
|
148
|
+
### Basic Example
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
from antioch.module import Module, NodeExecution
|
|
152
|
+
from antioch.module.test import ModuleTestHarness, TestNode, TestInput, TestOutput
|
|
153
|
+
from common.message import Message
|
|
154
|
+
|
|
155
|
+
# Define your message types
|
|
156
|
+
class InputData(Message):
|
|
157
|
+
_type = "input_data"
|
|
158
|
+
value: int
|
|
159
|
+
|
|
160
|
+
class OutputData(Message):
|
|
161
|
+
_type = "output_data"
|
|
162
|
+
result: int
|
|
163
|
+
|
|
164
|
+
# Create your module
|
|
165
|
+
class MyModule(Module):
|
|
166
|
+
def init(self):
|
|
167
|
+
self.add_node("process", self.process)
|
|
168
|
+
|
|
169
|
+
def process(self, exec: NodeExecution):
|
|
170
|
+
data = exec.input("data").data(InputData)
|
|
171
|
+
if data:
|
|
172
|
+
exec.output("result").set(OutputData(result=data.value * 2))
|
|
173
|
+
|
|
174
|
+
def cleanup(self):
|
|
175
|
+
pass
|
|
176
|
+
|
|
177
|
+
# Test your module
|
|
178
|
+
def test_my_module():
|
|
179
|
+
with ModuleTestHarness(MyModule) as harness:
|
|
180
|
+
# Configure the module
|
|
181
|
+
harness.configure(
|
|
182
|
+
module_name="my-module",
|
|
183
|
+
nodes=[
|
|
184
|
+
TestNode(
|
|
185
|
+
name="process",
|
|
186
|
+
budget=50, # 50ms time budget
|
|
187
|
+
inputs=[TestInput(name="data", message_type="input_data")],
|
|
188
|
+
outputs=[TestOutput(name="result", message_type="output_data")],
|
|
189
|
+
)
|
|
190
|
+
],
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
# Execute the node
|
|
194
|
+
result = harness.execute(
|
|
195
|
+
"process",
|
|
196
|
+
inputs={"data": InputData(value=21)},
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
# Check the output
|
|
200
|
+
output = result.output("result", OutputData)
|
|
201
|
+
assert output.result == 42
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The test framework handles module lifecycle, message serialization, and provides helpful error messages for common issues like budget overruns.
|
|
205
|
+
|
|
206
|
+
### Testing Modules with Hardware
|
|
207
|
+
|
|
208
|
+
For modules that use hardware (cameras, IMUs, actuator groups), provide mock hardware data:
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
from antioch.module import Module, NodeExecution
|
|
212
|
+
from antioch.module.test import ModuleTestHarness
|
|
213
|
+
from antioch.message import Image, ImageEncoding
|
|
214
|
+
|
|
215
|
+
class CameraModule(Module):
|
|
216
|
+
def init(self):
|
|
217
|
+
self.add_node("process_frame", self.process_frame)
|
|
218
|
+
self.camera = self.get_rgb_camera("my_camera")
|
|
219
|
+
|
|
220
|
+
def process_frame(self, exec: NodeExecution):
|
|
221
|
+
frame = self.camera.get_frame()
|
|
222
|
+
# Process frame...
|
|
223
|
+
exec.output("processed").set(...)
|
|
224
|
+
|
|
225
|
+
def test_camera_module():
|
|
226
|
+
with ModuleTestHarness(CameraModule, module_yaml_path="tests/camera.yaml") as harness:
|
|
227
|
+
# Execute node with mock camera data
|
|
228
|
+
result = harness.execute_node(
|
|
229
|
+
node_name="process_frame",
|
|
230
|
+
hardware_data={
|
|
231
|
+
"my_camera": Image(
|
|
232
|
+
width=640,
|
|
233
|
+
height=480,
|
|
234
|
+
encoding=ImageEncoding.RGB8,
|
|
235
|
+
data=b"mock_rgb_data",
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
# Verify outputs
|
|
241
|
+
processed = result.output("processed", ProcessedData)
|
|
242
|
+
assert processed is not None
|
|
243
|
+
|
|
244
|
+
# For actuator groups, you can also verify hardware writes
|
|
245
|
+
# write = result.get_hardware_write("my_actuator_group")
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The test harness automatically mocks the Sim RPC layer, so hardware reads and writes
|
|
249
|
+
work exactly as they would in production, but without requiring Isaac Sim to be running.
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: antioch-py
|
|
3
|
+
Version: 2.0.2
|
|
4
|
+
Summary: The Antioch Python SDK
|
|
5
|
+
Author-email: Antioch Robotics <support@antioch.dev>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://antioch.com
|
|
8
|
+
Keywords: robotics,simulation,middleware,sdk
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Requires-Python: <3.13,>=3.12
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: click>=8.0.0
|
|
18
|
+
Requires-Dist: click>=8.3.0
|
|
19
|
+
Requires-Dist: eclipse-zenoh>=1.5.0
|
|
20
|
+
Requires-Dist: google-cloud-artifact-registry>=1.16.1
|
|
21
|
+
Requires-Dist: httpx>=0.27.0
|
|
22
|
+
Requires-Dist: loguru>=0.7.3
|
|
23
|
+
Requires-Dist: msgpack==1.1.1
|
|
24
|
+
Requires-Dist: msgpack>=1.1.1
|
|
25
|
+
Requires-Dist: numpy==1.26.0
|
|
26
|
+
Requires-Dist: ormsgpack>=1.6.0
|
|
27
|
+
Requires-Dist: pydantic>=2.11.6
|
|
28
|
+
Requires-Dist: pydantic>=2.11.7
|
|
29
|
+
Requires-Dist: python-on-whales>=0.78.0
|
|
30
|
+
Requires-Dist: pyyaml>=6.0.2
|
|
31
|
+
Requires-Dist: requests>=2.32.0
|
|
32
|
+
Requires-Dist: scipy==1.15.3
|
|
33
|
+
Requires-Dist: sortedcontainers-stubs>=2.4.3
|
|
34
|
+
Requires-Dist: sortedcontainers>=2.4.0
|
|
35
|
+
Requires-Dist: tqdm>=4.67.1
|
|
36
|
+
|
|
37
|
+
# Antioch Python
|
|
38
|
+
|
|
39
|
+
Python client library for the Antioch middleware platform.
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
Authenticate your local environment with GCP via the Google Cloud CLI:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
gcloud auth login # Login to Google Cloud
|
|
47
|
+
gcloud config set project proof-of-concept-staging-9072 # Set the correct project
|
|
48
|
+
gcloud auth application-default login # Create app credentials
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This project uses [uv](https://github.com/astral-sh/uv), a fast Python package and project manager. Install it and set up authentication:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Install uv
|
|
55
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
56
|
+
|
|
57
|
+
# Install keyring authentication globally for uv
|
|
58
|
+
uv tool install keyring --with keyrings.google-artifactregistry-auth
|
|
59
|
+
|
|
60
|
+
# Install all default groups in one step
|
|
61
|
+
uv sync
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Install the pre-commit hooks to auto-run `uv sync` and `ruff format` on Git commit:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
uv run pre-commit install
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Usage
|
|
71
|
+
|
|
72
|
+
The Antioch Python client builds both Docker images that can be used and a Python package.
|
|
73
|
+
|
|
74
|
+
## Docker Images
|
|
75
|
+
|
|
76
|
+
We have 2 Docker images currently
|
|
77
|
+
|
|
78
|
+
### Standard Image (`antioch-py:latest`)
|
|
79
|
+
|
|
80
|
+
- Base: `python:3.12-slim`
|
|
81
|
+
- Sidecar binary at `/usr/local/bin/sidecar`
|
|
82
|
+
- antioch-py package pre-installed
|
|
83
|
+
- Python 3.12 virtual environment with pip
|
|
84
|
+
- Runs as root for maximum compatibility
|
|
85
|
+
|
|
86
|
+
Build locally using
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
./build-image.sh
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### ROS Image (`antioch-py-ros:latest`)
|
|
93
|
+
|
|
94
|
+
- Base: `osrf/ros:jazzy-desktop`
|
|
95
|
+
- All features of the standard image
|
|
96
|
+
- Full ROS 2 Jazzy desktop environment
|
|
97
|
+
- ROS 2 Python packages and tools pre-installed
|
|
98
|
+
- Ideal for robotics applications requiring ROS integration
|
|
99
|
+
|
|
100
|
+
NOTE: not included in cloudbuild currently
|
|
101
|
+
|
|
102
|
+
Build locally using
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
./build-image.sh --variant ros-jazzy
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Usage
|
|
109
|
+
|
|
110
|
+
For standard Python modules:
|
|
111
|
+
|
|
112
|
+
```dockerfile
|
|
113
|
+
FROM antioch-py:latest
|
|
114
|
+
|
|
115
|
+
# Install any additional packages you need
|
|
116
|
+
RUN pip install opencv-python-headless numpy
|
|
117
|
+
|
|
118
|
+
# Copy your module entrypoint
|
|
119
|
+
# The sidecar will automatically run your module.py file
|
|
120
|
+
COPY module.py .
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
For ROS-enabled modules:
|
|
124
|
+
|
|
125
|
+
```dockerfile
|
|
126
|
+
FROM antioch-py-ros:latest
|
|
127
|
+
|
|
128
|
+
# Install ROS-specific packages if needed
|
|
129
|
+
RUN apt-get update && apt-get install -y ros-jazzy-cv-bridge
|
|
130
|
+
|
|
131
|
+
# You will probably need to source your ROS modules / install
|
|
132
|
+
# To ensure your ROS environment is available to your module, source the ROS setup script before running the sidecar.
|
|
133
|
+
# For example, you can add the following to your Dockerfile:
|
|
134
|
+
RUN echo "source /opt/ros/jazzy/setup.bash" >> /etc/profile.d/ros.sh
|
|
135
|
+
SHELL ["/bin/bash", "-c"]
|
|
136
|
+
|
|
137
|
+
# If you have a custom ROS workspace, source its setup script as well:
|
|
138
|
+
# RUN echo "source /workspace/install/setup.bash" >> /etc/profile.d/ros.sh
|
|
139
|
+
|
|
140
|
+
# The sidecar will automatically run your module.py file in the ROS environment.
|
|
141
|
+
COPY module.py .
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Testing Modules
|
|
145
|
+
|
|
146
|
+
Antioch provides a test framework for testing modules in isolation without requiring a full deployment. The `ModuleTestHarness` runs your module in a separate process and communicates with it using the standard Antioch protocol.
|
|
147
|
+
|
|
148
|
+
### Basic Example
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
from antioch.module import Module, NodeExecution
|
|
152
|
+
from antioch.module.test import ModuleTestHarness, TestNode, TestInput, TestOutput
|
|
153
|
+
from common.message import Message
|
|
154
|
+
|
|
155
|
+
# Define your message types
|
|
156
|
+
class InputData(Message):
|
|
157
|
+
_type = "input_data"
|
|
158
|
+
value: int
|
|
159
|
+
|
|
160
|
+
class OutputData(Message):
|
|
161
|
+
_type = "output_data"
|
|
162
|
+
result: int
|
|
163
|
+
|
|
164
|
+
# Create your module
|
|
165
|
+
class MyModule(Module):
|
|
166
|
+
def init(self):
|
|
167
|
+
self.add_node("process", self.process)
|
|
168
|
+
|
|
169
|
+
def process(self, exec: NodeExecution):
|
|
170
|
+
data = exec.input("data").data(InputData)
|
|
171
|
+
if data:
|
|
172
|
+
exec.output("result").set(OutputData(result=data.value * 2))
|
|
173
|
+
|
|
174
|
+
def cleanup(self):
|
|
175
|
+
pass
|
|
176
|
+
|
|
177
|
+
# Test your module
|
|
178
|
+
def test_my_module():
|
|
179
|
+
with ModuleTestHarness(MyModule) as harness:
|
|
180
|
+
# Configure the module
|
|
181
|
+
harness.configure(
|
|
182
|
+
module_name="my-module",
|
|
183
|
+
nodes=[
|
|
184
|
+
TestNode(
|
|
185
|
+
name="process",
|
|
186
|
+
budget=50, # 50ms time budget
|
|
187
|
+
inputs=[TestInput(name="data", message_type="input_data")],
|
|
188
|
+
outputs=[TestOutput(name="result", message_type="output_data")],
|
|
189
|
+
)
|
|
190
|
+
],
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
# Execute the node
|
|
194
|
+
result = harness.execute(
|
|
195
|
+
"process",
|
|
196
|
+
inputs={"data": InputData(value=21)},
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
# Check the output
|
|
200
|
+
output = result.output("result", OutputData)
|
|
201
|
+
assert output.result == 42
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The test framework handles module lifecycle, message serialization, and provides helpful error messages for common issues like budget overruns.
|
|
205
|
+
|
|
206
|
+
### Testing Modules with Hardware
|
|
207
|
+
|
|
208
|
+
For modules that use hardware (cameras, IMUs, actuator groups), provide mock hardware data:
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
from antioch.module import Module, NodeExecution
|
|
212
|
+
from antioch.module.test import ModuleTestHarness
|
|
213
|
+
from antioch.message import Image, ImageEncoding
|
|
214
|
+
|
|
215
|
+
class CameraModule(Module):
|
|
216
|
+
def init(self):
|
|
217
|
+
self.add_node("process_frame", self.process_frame)
|
|
218
|
+
self.camera = self.get_rgb_camera("my_camera")
|
|
219
|
+
|
|
220
|
+
def process_frame(self, exec: NodeExecution):
|
|
221
|
+
frame = self.camera.get_frame()
|
|
222
|
+
# Process frame...
|
|
223
|
+
exec.output("processed").set(...)
|
|
224
|
+
|
|
225
|
+
def test_camera_module():
|
|
226
|
+
with ModuleTestHarness(CameraModule, module_yaml_path="tests/camera.yaml") as harness:
|
|
227
|
+
# Execute node with mock camera data
|
|
228
|
+
result = harness.execute_node(
|
|
229
|
+
node_name="process_frame",
|
|
230
|
+
hardware_data={
|
|
231
|
+
"my_camera": Image(
|
|
232
|
+
width=640,
|
|
233
|
+
height=480,
|
|
234
|
+
encoding=ImageEncoding.RGB8,
|
|
235
|
+
data=b"mock_rgb_data",
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
# Verify outputs
|
|
241
|
+
processed = result.output("processed", ProcessedData)
|
|
242
|
+
assert processed is not None
|
|
243
|
+
|
|
244
|
+
# For actuator groups, you can also verify hardware writes
|
|
245
|
+
# write = result.get_hardware_write("my_actuator_group")
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The test harness automatically mocks the Sim RPC layer, so hardware reads and writes
|
|
249
|
+
work exactly as they would in production, but without requiring Isaac Sim to be running.
|
|
@@ -1,8 +1,27 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "antioch-py"
|
|
3
|
-
version = "
|
|
4
|
-
description = "
|
|
5
|
-
|
|
3
|
+
version = "2.0.2"
|
|
4
|
+
description = "The Antioch Python SDK"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
requires-python = ">=3.12,<3.13"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Antioch Robotics", email = "support@antioch.dev" },
|
|
10
|
+
]
|
|
11
|
+
keywords = [
|
|
12
|
+
"robotics",
|
|
13
|
+
"simulation",
|
|
14
|
+
"middleware",
|
|
15
|
+
"sdk",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 4 - Beta",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
23
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
24
|
+
]
|
|
6
25
|
dependencies = [
|
|
7
26
|
"click>=8.0.0",
|
|
8
27
|
"click>=8.3.0",
|
|
@@ -25,6 +44,9 @@ dependencies = [
|
|
|
25
44
|
"tqdm>=4.67.1",
|
|
26
45
|
]
|
|
27
46
|
|
|
47
|
+
[project.urls]
|
|
48
|
+
Homepage = "https://antioch.com"
|
|
49
|
+
|
|
28
50
|
[project.scripts]
|
|
29
51
|
schedule_viz = "scripts.schedule_viz:main"
|
|
30
52
|
|
|
@@ -56,6 +78,9 @@ requires = [
|
|
|
56
78
|
]
|
|
57
79
|
build-backend = "setuptools.build_meta"
|
|
58
80
|
|
|
81
|
+
[tool.setuptools]
|
|
82
|
+
include-package-data = true
|
|
83
|
+
|
|
59
84
|
[tool.setuptools.packages.find]
|
|
60
85
|
where = [
|
|
61
86
|
".",
|
antioch_py-1.9.7/PKG-INFO
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: antioch-py
|
|
3
|
-
Version: 1.9.7
|
|
4
|
-
Summary: Python implementation of the Antioch middleware for distributed systems
|
|
5
|
-
Requires-Python: >=3.12
|
|
6
|
-
Requires-Dist: click>=8.0.0
|
|
7
|
-
Requires-Dist: click>=8.3.0
|
|
8
|
-
Requires-Dist: eclipse-zenoh>=1.5.0
|
|
9
|
-
Requires-Dist: google-cloud-artifact-registry>=1.16.1
|
|
10
|
-
Requires-Dist: httpx>=0.27.0
|
|
11
|
-
Requires-Dist: loguru>=0.7.3
|
|
12
|
-
Requires-Dist: msgpack==1.1.1
|
|
13
|
-
Requires-Dist: msgpack>=1.1.1
|
|
14
|
-
Requires-Dist: numpy==1.26.0
|
|
15
|
-
Requires-Dist: ormsgpack>=1.6.0
|
|
16
|
-
Requires-Dist: pydantic>=2.11.6
|
|
17
|
-
Requires-Dist: pydantic>=2.11.7
|
|
18
|
-
Requires-Dist: python-on-whales>=0.78.0
|
|
19
|
-
Requires-Dist: pyyaml>=6.0.2
|
|
20
|
-
Requires-Dist: requests>=2.32.0
|
|
21
|
-
Requires-Dist: scipy==1.15.3
|
|
22
|
-
Requires-Dist: sortedcontainers-stubs>=2.4.3
|
|
23
|
-
Requires-Dist: sortedcontainers>=2.4.0
|
|
24
|
-
Requires-Dist: tqdm>=4.67.1
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: antioch-py
|
|
3
|
-
Version: 1.9.7
|
|
4
|
-
Summary: Python implementation of the Antioch middleware for distributed systems
|
|
5
|
-
Requires-Python: >=3.12
|
|
6
|
-
Requires-Dist: click>=8.0.0
|
|
7
|
-
Requires-Dist: click>=8.3.0
|
|
8
|
-
Requires-Dist: eclipse-zenoh>=1.5.0
|
|
9
|
-
Requires-Dist: google-cloud-artifact-registry>=1.16.1
|
|
10
|
-
Requires-Dist: httpx>=0.27.0
|
|
11
|
-
Requires-Dist: loguru>=0.7.3
|
|
12
|
-
Requires-Dist: msgpack==1.1.1
|
|
13
|
-
Requires-Dist: msgpack>=1.1.1
|
|
14
|
-
Requires-Dist: numpy==1.26.0
|
|
15
|
-
Requires-Dist: ormsgpack>=1.6.0
|
|
16
|
-
Requires-Dist: pydantic>=2.11.6
|
|
17
|
-
Requires-Dist: pydantic>=2.11.7
|
|
18
|
-
Requires-Dist: python-on-whales>=0.78.0
|
|
19
|
-
Requires-Dist: pyyaml>=6.0.2
|
|
20
|
-
Requires-Dist: requests>=2.32.0
|
|
21
|
-
Requires-Dist: scipy==1.15.3
|
|
22
|
-
Requires-Dist: sortedcontainers-stubs>=2.4.3
|
|
23
|
-
Requires-Dist: sortedcontainers>=2.4.0
|
|
24
|
-
Requires-Dist: tqdm>=4.67.1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|