Skip to content

Commit

Permalink
End-to-end tagging: Python (#8298)
Browse files Browse the repository at this point in the history
This semantically mimics very closely the way things are done in Rust,
minus all technical differences due to the differences between both the
languages and the SDKs.
For that reason, everything stated in
#8304 (comment) basically
applies as-is.

Pretty happy about it, I must say.

* DNM: requires #8316 
* Part of #7948
  • Loading branch information
teh-cmc authored Dec 9, 2024
1 parent 962f3e0 commit a580884
Show file tree
Hide file tree
Showing 148 changed files with 647 additions and 242 deletions.
5 changes: 3 additions & 2 deletions crates/build/re_types_builder/src/codegen/python/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ impl PythonCodeGenerator {
Archetype,
BaseBatch,
ComponentBatchMixin,
ComponentDescriptor,
ComponentMixin,
)
from {rerun_path}_converters import (
Expand Down Expand Up @@ -1926,7 +1927,7 @@ fn quote_arrow_support_from_obj(
r#"
class {extension_batch}{batch_superclass_decl}:
_ARROW_DATATYPE = {datatype}
_COMPONENT_NAME: str = "{fqname}"
_COMPONENT_DESCRIPTOR: ComponentDescriptor = ComponentDescriptor("{fqname}")
@staticmethod
def _native_to_pa_array(data: {many_aliases}, data_type: pa.DataType) -> pa.Array:
Expand All @@ -1939,7 +1940,7 @@ fn quote_arrow_support_from_obj(
unindent(&format!(
r#"
class {extension_batch}{batch_superclass_decl}:
_COMPONENT_NAME: str = "{fqname}"
_COMPONENT_DESCRIPTOR: ComponentDescriptor = ComponentDescriptor("{fqname}")
"#
))
}
Expand Down
18 changes: 1 addition & 17 deletions crates/store/re_chunk/src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,23 +284,7 @@ impl Chunk {
.collect();
timelines == rhs_timelines
}
// TODO(cmc): we cannot compare tags yet, need to support Python & C++ first
// && *components == rhs.components
&& {
let lhs_components_no_tags: ChunkComponents = components
.clone()
.into_iter_flattened()
.map(|(descr, list_array)| (ComponentDescriptor::new(descr.component_name), list_array))
.collect();
let rhs_components_no_tags: ChunkComponents = rhs
.components
.clone()
.into_iter_flattened()
.map(|(descr, list_array)| (ComponentDescriptor::new(descr.component_name), list_array))
.collect();

lhs_components_no_tags == rhs_components_no_tags
}
&& *components == rhs.components
}

/// Check for equality while ignoring possible `Extension` type information
Expand Down
12 changes: 12 additions & 0 deletions docs/snippets/all/descriptors/descr_builtin_archetype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env python3

from __future__ import annotations

import rerun as rr # pip install rerun-sdk

rr.init("rerun_example_descriptors_builtin_archetype")
rr.spawn()

rr.log("data", rr.Points3D([[1, 2, 3]], radii=[0.3, 0.2, 0.1]), static=True)

# The tags are indirectly checked by the Rust version (have a look over there for more info).
12 changes: 12 additions & 0 deletions docs/snippets/all/descriptors/descr_builtin_component.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env python3

from __future__ import annotations

import rerun as rr # pip install rerun-sdk

rr.init("rerun_example_descriptors_builtin_component")
rr.spawn()

rr.log("data", [rr.components.Position3DBatch([1, 2, 3])], static=True)

# The tags are indirectly checked by the Rust version (have a look over there for more info).
59 changes: 59 additions & 0 deletions docs/snippets/all/descriptors/descr_custom_archetype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python3

from __future__ import annotations

from typing import Any, Iterable

import numpy.typing as npt
import pyarrow as pa
import rerun as rr # pip install rerun-sdk


class CustomPosition3DBatch(rr.ComponentBatchLike):
def __init__(self: Any, positions: npt.ArrayLike) -> None:
self.position = rr.components.Position3DBatch(positions)

def component_descriptor(self) -> rr.ComponentDescriptor:
return rr.ComponentDescriptor(
"user.CustomPosition3D",
archetype_name="user.CustomPoints3D",
archetype_field_name="custom_positions",
)

def as_arrow_array(self) -> pa.Array:
return self.position.as_arrow_array()


class CustomPoints3D(rr.AsComponents):
def __init__(self: Any, positions: npt.ArrayLike, colors: npt.ArrayLike) -> None:
self.positions = CustomPosition3DBatch(positions)
self.colors = rr.components.ColorBatch(colors)

def as_component_batches(self) -> Iterable[rr.ComponentBatchLike]:
return (
[rr.IndicatorComponentBatch("user.CustomPoints3D")]
+ [
rr.DescribedComponentBatch(
self.positions,
self.positions.component_descriptor().or_with_overrides(
archetype_name="user.CustomPoints3D", archetype_field_name="custom_positions"
),
)
]
+ [
rr.DescribedComponentBatch(
self.colors,
self.colors.component_descriptor().or_with_overrides(
archetype_name="user.CustomPoints3D", archetype_field_name="colors"
),
)
]
)


rr.init("rerun_example_descriptors_custom_archetype")
rr.spawn()

rr.log("data", CustomPoints3D([[1, 2, 3]], [0xFF00FFFF]), static=True)

# The tags are indirectly checked by the Rust version (have a look over there for more info).
32 changes: 32 additions & 0 deletions docs/snippets/all/descriptors/descr_custom_component.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env python3

from __future__ import annotations

from typing import Any

import numpy.typing as npt
import pyarrow as pa
import rerun as rr # pip install rerun-sdk


class CustomPosition3DBatch(rr.ComponentBatchLike):
def __init__(self: Any, positions: npt.ArrayLike) -> None:
self.position = rr.components.Position3DBatch(positions)

def component_descriptor(self) -> rr.ComponentDescriptor:
return rr.ComponentDescriptor(
"user.CustomPosition3D",
archetype_name="user.CustomArchetype",
archetype_field_name="custom_positions",
)

def as_arrow_array(self) -> pa.Array:
return self.position.as_arrow_array()


rr.init("rerun_example_descriptors_custom_component")
rr.spawn()

rr.log("data", [CustomPosition3DBatch([[1, 2, 3]])], static=True)

# The tags are indirectly checked by the Rust version (have a look over there for more info).
18 changes: 13 additions & 5 deletions docs/snippets/all/tutorials/custom_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import numpy as np
import numpy.typing as npt
import pyarrow as pa
import rerun as rr # pip install rerun-sdk
import rerun as rr


class ConfidenceBatch(rr.ComponentBatchLike):
Expand All @@ -18,9 +18,9 @@ class ConfidenceBatch(rr.ComponentBatchLike):
def __init__(self: Any, confidence: npt.ArrayLike) -> None:
self.confidence = confidence

def component_name(self) -> str:
"""The name of the custom component."""
return "user.Confidence"
def component_descriptor(self) -> rr.ComponentDescriptor:
"""The descriptor of the custom component."""
return rr.ComponentDescriptor("user.Confidence")

def as_arrow_array(self) -> pa.Array:
"""The arrow batch representing the custom component."""
Expand All @@ -36,10 +36,18 @@ def __init__(self: Any, points3d: npt.ArrayLike, confidences: npt.ArrayLike) ->

def as_component_batches(self) -> Iterable[rr.ComponentBatchLike]:
points3d = np.asarray(self.points3d)
confidences = ConfidenceBatch(self.confidences)
return (
list(rr.Points3D(points3d).as_component_batches()) # The components from Points3D
+ [rr.IndicatorComponentBatch("user.CustomPoints3D")] # Our custom indicator
+ [ConfidenceBatch(self.confidences)] # Custom confidence data
+ [
rr.DescribedComponentBatch(
confidences,
confidences.component_descriptor().or_with_overrides(
archetype_name="user.CustomPoints3D", archetype_field_name="confidences"
),
)
] # Custom confidence data
)


Expand Down
15 changes: 1 addition & 14 deletions docs/snippets/snippets.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,10 @@
"cpp",
"rust",
]
"descriptors/descr_builtin_archetype" = [ # Python and C++ not yet supported (next PRs)
"py",
]
"descriptors/descr_builtin_component" = [ # Python and C++ not yet supported (next PRs)
"py",
]
"descriptors/descr_custom_archetype" = [ # Python and C++ not yet supported (next PRs)
"py",
]
"descriptors/descr_custom_component" = [ # Python and C++ not yet supported (next PRs)
"py",
]
views = [
"views" = [
"cpp", # TODO(#5520): C++ views are not yet implemented
"rust", # TODO(#5521): Rust views are not yet implemented
]

"archetypes/image_advanced" = [
"cpp", # Missing examples
"rust", # Missing examples
Expand Down
2 changes: 2 additions & 0 deletions rerun_py/rerun_bindings/rerun_bindings.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,11 @@ class Schema:
def index_columns(self) -> list[IndexColumnDescriptor]:
"""Return a list of all the index columns in the schema."""
...

def component_columns(self) -> list[ComponentColumnDescriptor]:
"""Return a list of all the component columns in the schema."""
...

def column_for(self, entity_path: str, component: ComponentLike) -> Optional[ComponentColumnDescriptor]:
"""
Look up the column descriptor for a specific entity path and component.
Expand Down
2 changes: 2 additions & 0 deletions rerun_py/rerun_sdk/rerun/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
)
from ._baseclasses import (
ComponentColumn as ComponentColumn,
ComponentDescriptor as ComponentDescriptor,
DescribedComponentBatch as DescribedComponentBatch,
)
from ._image_encoded import (
ImageEncoded as ImageEncoded,
Expand Down
Loading

0 comments on commit a580884

Please sign in to comment.