|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
3 |
| -from typing import Iterable, Protocol, TypeVar |
| 3 | +from typing import Iterable, Protocol, TypeVar, Union |
4 | 4 |
|
5 | 5 | import pyarrow as pa
|
6 | 6 | import rerun_bindings as bindings
|
7 | 7 |
|
8 |
| -from ._baseclasses import Archetype, ComponentColumnLike |
| 8 | +from ._baseclasses import Archetype, ComponentBatchMixin, ComponentColumn |
9 | 9 | from ._log import IndicatorComponentBatch
|
10 | 10 | from .error_utils import catch_and_log_exceptions
|
11 | 11 | from .recording_stream import RecordingStream
|
@@ -84,7 +84,7 @@ def as_arrow_array(self) -> pa.Array:
|
84 | 84 | def send_columns(
|
85 | 85 | entity_path: str,
|
86 | 86 | times: Iterable[TimeColumnLike],
|
87 |
| - components: Iterable[ComponentColumnLike], |
| 87 | + components: Iterable[Union[ComponentBatchMixin, ComponentColumn]], |
88 | 88 | recording: RecordingStream | None = None,
|
89 | 89 | strict: bool | None = None,
|
90 | 90 | ) -> None:
|
@@ -148,7 +148,11 @@ def send_columns(
|
148 | 148 | of timestamps. Generally you should use one of the provided classes: [`TimeSequenceColumn`][],
|
149 | 149 | [`TimeSecondsColumn`][], or [`TimeNanosColumn`][].
|
150 | 150 | components:
|
151 |
| - The batches of components to log. Each `ComponentColumnLike` object represents a single column of data. |
| 151 | + The columns of components to log. Each object represents a single column of data. |
| 152 | +
|
| 153 | + If a batch of components is passed, it will be partitioned with one element per timepoint. |
| 154 | + In order to send multiple components per time value, explicitly create a [`ComponentColumn`][rerun.ComponentColumn] |
| 155 | + either by constructing it directly, or by calling the `.partition()` method on a `ComponentBatch` type. |
152 | 156 | recording:
|
153 | 157 | Specifies the [`rerun.RecordingStream`][] to use.
|
154 | 158 | If left unspecified, defaults to the current active data recording, if there is one.
|
@@ -182,15 +186,25 @@ def send_columns(
|
182 | 186 | indicators.append(c)
|
183 | 187 | continue
|
184 | 188 | component_name = c.component_name()
|
185 |
| - component_column = c.as_arrow_array() # type: ignore[union-attr] |
| 189 | + |
| 190 | + if isinstance(c, ComponentColumn): |
| 191 | + component_column = c |
| 192 | + elif isinstance(c, ComponentBatchMixin): |
| 193 | + component_column = c.partition([1] * len(c)) # type: ignore[arg-type] |
| 194 | + else: |
| 195 | + raise TypeError( |
| 196 | + f"Expected either a type that implements the `ComponentMixin` or a `ComponentColumn`, got: {type(c)}" |
| 197 | + ) |
| 198 | + arrow_list_array = component_column.as_arrow_array() |
| 199 | + |
186 | 200 | if expected_length is None:
|
187 |
| - expected_length = len(component_column) |
188 |
| - elif len(component_column) != expected_length: |
| 201 | + expected_length = len(arrow_list_array) |
| 202 | + elif len(arrow_list_array) != expected_length: |
189 | 203 | raise ValueError(
|
190 |
| - f"All times and components in a batch must have the same length. Expected length: {expected_length} but got: {len(component_column)} for component: {component_name}" |
| 204 | + f"All times and components in a batch must have the same length. Expected length: {expected_length} but got: {len(arrow_list_array)} for component: {component_name}" |
191 | 205 | )
|
192 | 206 |
|
193 |
| - components_args[component_name] = component_column |
| 207 | + components_args[component_name] = arrow_list_array |
194 | 208 |
|
195 | 209 | for i in indicators:
|
196 | 210 | if expected_length is None:
|
|
0 commit comments