roboto.domain.topics.topic
Module Contents
Topic
Represents a topic within the Roboto platform.
A topic is a sequence of structured time-series data linked to a source file, typically containing sensor readings, robot state information, or other timestamped data streams. Topics are fundamental building blocks for data analysis in robotics, providing organized access to time-synchronized data from various sources like ROS bags, MCAP files, or other structured data formats.
Each topic follows a defined schema where message paths represent the individual fields or signals within that schema. Topics enable efficient querying, filtering, and analysis of time-series data, supporting operations like temporal slicing, field selection, and data export to various formats including pandas DataFrames.
Topics are associated with files and inherit access permissions from their parent dataset. They provide the primary interface for accessing ingested robotics data in the Roboto platform, supporting both programmatic access through the SDK and visualization in the web interface.
The Topic class serves as the main interface for topic operations in the Roboto SDK, providing methods for data retrieval, message path management, metadata operations, and schema management.
Parameters
roboto_client Optional[roboto.topic_data_service Optional[roboto.Topic.add_message_path()
Add a new message path to this topic.
Creates a new message path within this topic, defining a specific field or signal that can be extracted from the topic’s data. Message paths use dot notation to specify nested attributes within the topic’s schema.
Parameters
message_path strDot-delimited path to the attribute (e.g., “pose.position.x”).
data_type strNative data type of the attribute as it appears in the original data source (e.g., “float32”, “uint8[]”, “geometry_msgs/Pose”). Used primarily for display purposes and should match the robot’s runtime language or schema definitions.
canonical_data_type roboto.Normalized Roboto data type that enables specialized platform features for maps, images, timestamps, and other data with special interpretations.
path_in_schema Optional[list[str]]List of path components representing the field’s location in the source data schema. Unlike message_path, which assumes dots separate path parts implying nested data, this preserves the exact path from the source data for accurate attribute access.
metadata Optional[dict[str, Any]]Additional metadata to associate with the message path.
Returns
MessagePathRecord representing the newly created message path.
Raises
Message path already exists for this topic.
Caller lacks permission to modify the topic.
Usage
from roboto.domain.topics import CanonicalDataType
topic = Topic.from_id("topic_xyz789")
message_path = topic.add_message_path(
message_path="pose.position.x",
data_type="float64",
canonical_data_type=CanonicalDataType.Number,
metadata={"unit": "meters"},
)
print(message_path.message_path)
# pose.position.xTopic.add_message_path_representation()
Add a representation for a specific message path.
Associates a message path with a data representation, enabling efficient access to specific fields within the topic data. Representations can be in different storage formats like MCAP or Parquet.
Parameters
message_path_id strUnique identifier of the message path.
association roboto.Association pointing to the representation data.
storage_format roboto.Format of the representation data.
version intVersion number of the representation.
format Optional[str]Content format descriptor (e.g. “jpeg”, “sensor_msgs/Image”).
transformations Optional[list[str]]Transformation descriptors applied (e.g. [“downsample:0.5”]).
Returns
RepresentationRecord representing the newly created representation.
Raises
Message path with the given ID does not exist.
Caller lacks permission to modify the topic.
Usage
from roboto.association import Association
from roboto.domain.topics import RepresentationStorageFormat
topic = Topic.from_id("topic_xyz789")
representation = topic.add_message_path_representation(
message_path_id="mp_123",
association=Association.file("file_repr_456"),
storage_format=RepresentationStorageFormat.MCAP,
version=1,
)
print(representation.representation_id)
# repr_789Properties
Topic.association
Association linking this topic to its source entity (typically a file).
Topic.create()
Create a new topic associated with a file.
Creates a new topic record in the Roboto platform, associating it with the specified file and defining its schema and temporal boundaries. This method is typically used during data ingestion to register topics found in robotics data files.
Parameters
file_id strUnique identifier of the file this topic is associated with.
topic_name strName of the topic (e.g., “/camera/image”, “/imu/data”).
end_time Optional[int]End time of the topic data in nanoseconds since UNIX epoch.
message_count Optional[int]Total number of messages in this topic.
metadata Optional[collections.Additional metadata to associate with the topic.
schema_checksum Optional[str]Checksum of the topic’s message schema for validation.
schema_name Optional[str]Name of the message schema (e.g., “sensor_msgs/Image”).
start_time Optional[int]Start time of the topic data in nanoseconds since UNIX epoch.
message_paths Optional[collections.Message paths to create along with the topic.
caller_org_id Optional[str]Organization ID to create the topic in. Required for multi-org users.
roboto_client Optional[roboto.HTTP client for API communication. If None, uses the default client.
Returns
Topic instance representing the newly created topic.
Raises
Invalid topic parameters.
Caller lacks permission to create topics.
Usage
Create a basic topic for camera data:
topic = Topic.create(
file_id="file_abc123",
topic_name="/camera/image",
schema_name="sensor_msgs/Image",
start_time=1722870127699468923,
end_time=1722870127799468923,
message_count=100,
)
print(topic.topic_id)
# topic_xyz789Create a topic with metadata and message paths:
from roboto.domain.topics import AddMessagePathRequest, CanonicalDataType
message_paths = [
AddMessagePathRequest(
message_path="header.stamp.sec",
data_type="uint32",
canonical_data_type=CanonicalDataType.Timestamp,
)
]
topic = Topic.create(
file_id="file_abc123",
topic_name="/imu/data",
schema_name="sensor_msgs/Imu",
metadata={"sensor_type": "IMU", "frequency": 100},
message_paths=message_paths,
)Topic.create_from_df()
Create a Topic from a pandas DataFrame and associate it with a file.
If a topic with the same name already exists for the specified file, it will be updated with the new data and schema.
Parameters
file_id strID of the file to associate this topic with.
dataset_id strID of the dataset containing the file.
topic_name strName for the topic. Must be unique within the file.
df pandas.pandas DataFrame containing the data to ingest. Must include a timestamp column (either explicitly specified or automatically detectable).
timestamp_column Optional[str]Name of the column to use as the timestamp. If not provided, the method will attempt to automatically detect a timestamp column by looking for the first column that is a timezone-aware timestamp type.
timestamp_unit Optional[Union[str, roboto.Unit of the timestamp column values. Required when timestamp_column contains numeric values (int, float, decimal). Valid values include “s”, “ms”, “us”, “ns”. Not needed for datetime columns or when timestamp_column is not specified.
caller_org_id Optional[str]Organization ID of the caller. If not provided, uses the default from the client context.
roboto_client Optional[roboto.Roboto client instance. If not provided, uses the default client.
Returns
The created or updated Topic instance.
Raises
If the timestamp column cannot be determined, is not present in the DataFrame, has an invalid type, or if the timestamp unit is required but not provided.
ImportErrorIf pandas or pyarrow are not installed. Install with pip install roboto[ingestion] to use this feature.
If the caller lacks permission to create topics or upload files to the specified dataset.
Notes
- For most use cases, prefer
File.add_topic()instead
Usage
Create a topic when you have file and dataset IDs:
import pandas as pd
from roboto.domain.topics import Topic
df = pd.DataFrame(
{
"timestamp": [1763947309.4198897, 1763947316.7686195, 1763947335.0095527],
"temperature": [20.5, 21.0, 20.8],
"humidity": [45.2, 46.1, 45.8],
}
)
topic = Topic.create_from_df(
file_id="file_abc123",
dataset_id="ds_xyz789",
topic_name="sensor_data",
df=df,
timestamp_column="timestamp",
timestamp_unit="s",
)
print(f"Created topic: {topic.name}")
# Created topic: sensor_dataUsing File.add_topic() is typically more convenient:
from roboto import File
file = File.from_id("file_abc123")
topic = file.add_topic("sensor_data", df, timestamp_column="timestamp", timestamp_unit="s")Properties
Topic.created
Timestamp when this topic was created in the Roboto platform.
Topic.created_by
Identifier of the user or system that created this topic.
Topic.dataset_id
Unique identifier of the dataset containing this topic, if applicable.
Topic.default_representation
Default representation used for accessing this topic’s data.
Topic.delete()
Delete this topic from the Roboto platform.
Permanently removes this topic and all its associated message paths and representations from the platform. This operation cannot be undone.
Raises
Topic does not exist or has already been deleted.
Caller lacks permission to delete the topic.
Return type
Usage
topic = Topic.from_id("topic_xyz789")
topic.delete()
# # Topic and all its data are now permanently deletedTopic.from_id()
Retrieve a topic by its unique identifier.
Fetches a topic record from the Roboto platform using its unique topic ID. This is the most direct way to access a specific topic when you know its identifier.
Parameters
topic_id strUnique identifier for the topic.
roboto_client Optional[roboto.HTTP client for API communication. If None, uses the default client.
Returns
Topic instance representing the requested topic.
Raises
Topic with the given ID does not exist.
Caller lacks permission to access the topic.
Usage
topic = Topic.from_id("topic_xyz789")
print(topic.name)
# '/camera/image'
print(topic.message_count)
# 100Topic.from_name_and_file()
Retrieve a topic by its name and associated file.
Fetches a topic record using its name and the file it’s associated with. This is useful when you know the topic name (e.g., “/camera/image”) and the file containing the topic data.
Parameters
topic_name strName of the topic to retrieve.
file_id strUnique identifier of the file containing the topic.
owner_org_id Optional[str]Organization ID to scope the search. If None, uses caller’s org.
roboto_client Optional[roboto.HTTP client for API communication. If None, uses the default client.
Returns
Topic instance representing the requested topic.
Raises
Topic with the given name does not exist in the specified file.
Caller lacks permission to access the topic.
Usage
topic = Topic.from_name_and_file(topic_name="/camera/image", file_id="file_abc123")
print(topic.topic_id)
# topic_xyz789
print(len(topic.message_paths))
# 5Topic.get_by_dataset()
List all topics associated with files in a dataset.
Retrieves all topics from files within the specified dataset. If multiple files contain topics with the same name (e.g., chunked files with the same schema), they are returned as separate topic objects.
Parameters
dataset_id strUnique identifier of the dataset to search.
roboto_client Optional[roboto.HTTP client for API communication. If None, uses the default client.
Yields
Topic instances associated with files in the dataset.
Raises
Dataset with the given ID does not exist.
Caller lacks permission to access the dataset.
Return type
Usage
for topic in Topic.get_by_dataset("ds_abc123"):
print(f"Topic: {topic.name} (File: {topic.file_id})")
# Topic: /camera/image (File: file_001)
# Topic: /imu/data (File: file_001)
# Topic: /camera/image (File: file_002)
# Topic: /imu/data (File: file_002)# Count topics by name
from collections import Counter
topic_names = [topic.name for topic in Topic.get_by_dataset("ds_abc123")]
print(Counter(topic_names))
# Counter({'/camera/image': 2, '/imu/data': 2})Topic.get_by_file()
List all topics associated with a specific file.
Retrieves all topics contained within the specified file. This is useful for exploring the structure of robotics data files and understanding what data streams are available.
Parameters
file_id strUnique identifier of the file to search.
owner_org_id Optional[str]Organization ID to scope the search. If None, uses caller’s org.
roboto_client Optional[roboto.HTTP client for API communication. If None, uses the default client.
Yields
Topic instances associated with the specified file.
Raises
File with the given ID does not exist.
Caller lacks permission to access the file.
Return type
Usage
for topic in Topic.get_by_file("file_abc123"):
print(f"Topic: {topic.name} ({topic.message_count} messages)")
# Topic: /camera/image (150 messages)
# Topic: /imu/data (1500 messages)
# Topic: /gps/fix (50 messages)# Get topics with specific schema
camera_topics = [topic for topic in Topic.get_by_file("file_abc123") if "camera" in topic.name]Topic.get_data()
Return this topic’s underlying data.
Retrieves and yields data records from this topic, with optional filtering by message paths and time range. Each yielded datum is a dictionary that matches this topic’s schema.
Parameters
message_paths_include Optional[collections.Dot notation paths that match attributes of individual data records to include. If None, all paths are included.
message_paths_exclude Optional[collections.Dot notation paths that match attributes of individual data records to exclude. If None, no paths are excluded.
start_time Optional[roboto.Start time (inclusive) as nanoseconds since UNIX epoch or convertible to such by to_epoch_nanoseconds().
end_time Optional[roboto.End time (exclusive) as nanoseconds since UNIX epoch or convertible to such by to_epoch_nanoseconds().
cache_dir Union[str, pathlib.Directory where topic data will be downloaded if necessary. Defaults to DEFAULT_CACHE_DIR.
representation_selector roboto.Criteria for selecting among multiple representations. Defaults to RepresentationSelector.raw() — original, untransformed data. Pass a RepresentationSelector to request a specific content format or transformation pipeline.
Yields
Timestamp and dictionary records that match this topic’s schema, filtered according to the parameters.
Return type
Notes
For each example below, assume the following is a sample datum record that can be found in this topic:
{“angular_velocity”: {
“x”: <uint32>, “y”: <uint32>, “z”: <uint32>
}, “orientation”: { “x”: <uint32>, “y”: <uint32>, “z”: <uint32>, “w”: <uint32> }
}
Usage
Print all data to stdout:
topic = Topic.from_name_and_file(...)
for timestamp, record in topic.get_data():
print(timestamp, record)Only include the “angular_velocity” sub-object, but filter out its “y” property:
topic = Topic.from_name_and_file(...)
for timestamp, record in topic.get_data(
message_paths_include=["angular_velocity"],
message_paths_exclude=["angular_velocity.y"],
):
...Only include data between two timestamps:
topic = Topic.from_name_and_file(...)
for timestamp, record in topic.get_data(
start_time=1722870127699468923,
end_time=1722870127699468924,
):
...Collect all topic data into a dataframe (requires installing the roboto[analytics] extra):
topic = Topic.from_name_and_file(...)
df = topic.get_data_as_df()Get the JPEG-encoded version of image data:
topic = Topic.from_name_and_file(...)
for timestamp, record in topic.get_data(
representation_selector=RepresentationSelector(content_format="jpeg"),
):
...Topic.get_data_as_df()
Return this topic’s underlying data as a pandas DataFrame.
Retrieves topic data and converts it to a pandas DataFrame for analysis and visualization. The DataFrame is indexed by log time and contains columns for each message path in the topic data.
Parameters
message_paths_include Optional[collections.Dot notation paths that match attributes of individual data records to include. If None, all paths are included.
message_paths_exclude Optional[collections.Dot notation paths that match attributes of individual data records to exclude. If None, no paths are excluded.
start_time Optional[roboto.Start time (inclusive) as nanoseconds since UNIX epoch or convertible to such by to_epoch_nanoseconds().
end_time Optional[roboto.End time (exclusive) as nanoseconds since UNIX epoch or convertible to such by to_epoch_nanoseconds().
cache_dir Union[str, pathlib.Directory where topic data will be downloaded if necessary. Defaults to DEFAULT_CACHE_DIR.
representation_selector roboto.Criteria for selecting among multiple representations. Defaults to RepresentationSelector.raw() — original, untransformed data. Pass a RepresentationSelector to request a specific content format or transformation pipeline.
Returns
pandas DataFrame containing the topic data, indexed by log time.
Raises
ImportErrorpandas is not installed. Install with roboto[analytics] extra.
Notes
Requires installing this package using the roboto[analytics] extra.
An array-typed message path (for example a float32[3] acceleration) becomes a single column whose values are lists. Individual array elements are not addressable on their own — neither as separate DataFrame columns nor as message paths in message_paths_include / message_paths_exclude. Filter by the array’s path and unpack the column with numpy, as in the example below. np.stack requires every row to have the same length; a variable-length array path (for example a point cloud) must instead be processed row-wise, e.g. with df[col].map(...).
Usage
topic = Topic.from_name_and_file("/imu/data", "file_abc123")
df = topic.get_data_as_df()
print(df.head())
# angular_velocity.x angular_velocity.y ...
# log_time
# 1722870127699468923 0.1 0.2 ...
# 1722870127699468924 0.15 0.25 ...# Filter specific message paths
df_filtered = topic.get_data_as_df(
message_paths_include=["angular_velocity"], message_paths_exclude=["angular_velocity.z"]
)
print(df_filtered.columns.tolist())
# ['angular_velocity.x', 'angular_velocity.y']# Unpack a fixed-length array-typed path (a list-valued column) into a numpy array
import numpy as np
df_accel = topic.get_data_as_df(message_paths_include=["acceleration"])
xyz = np.stack(df_accel["acceleration"].to_numpy()) # shape (N, 3)Topic.get_message_path()
Get a specific message path from this topic.
Retrieves a MessagePath object for the specified path, enabling access to individual fields or signals within the topic’s data schema.
Parameters
message_path strDot-delimited path to the desired attribute (e.g., “pose.position.x”).
Returns
MessagePath instance for the specified path.
Raises
ValueErrorNo message path with the given name exists in this topic.
Usage
topic = Topic.from_name_and_file("/imu/data", "file_abc123")
angular_vel_x = topic.get_message_path("angular_velocity.x")
print(angular_vel_x.canonical_data_type)
# CanonicalDataType.Number# Access message path statistics
print(angular_vel_x.mean)
# 0.125
print(angular_vel_x.std_dev)
# 0.05Topic.get_schema()
Retrieve the schema for this topic, if one exists.
Returns
A TopicSchema describing the message structure of this topic, or None if this topic has no schema.
Raises
schema_id references a schema that no longer exists.
Usage
topic = Topic.from_id("topic_xyz789")
schema = topic.get_schema()
if schema is not None:
for field in schema.fields:
print(field.name, field.data_type)Topic.get_time_bounds_by_association()
Get the earliest start and latest end across every topic of a file or dataset.
The same aggregate you would reach by folding start_time and end_time over the topics of that file or dataset, computed server-side in one request instead of one per page of topics.
Parameters
association roboto.The file or dataset whose topics are aggregated, e.g. Association.file("file_abc123").
owner_org_id Optional[str]Organization ID to scope the lookup. If None, uses caller’s org.
roboto_client Optional[roboto.HTTP client for API communication. If None, uses the default client.
Returns
Bounds in nanoseconds since the Unix epoch. Both fields are None when the association holds no topics, and either is None when no topic of the association carries that timestamp.
Raises
Caller lacks permission to access the file or dataset.
Usage
from roboto.association import Association
bounds = Topic.get_time_bounds_by_association(Association.file("file_abc123"))
print(bounds.start_time, bounds.end_time)
# 1722870127699468923 1722870187004821001Properties
Topic.message_count
Total number of messages in this topic.
Topic.message_paths
Sequence of message path records defining the topic’s schema.
Topic.metadata
Metadata dictionary associated with this topic.
Topic.modified
Timestamp when this topic was last modified.
Topic.modified_by
Identifier of the user or system that last modified this topic.
Topic.record
Topic representation in the Roboto database.
This property is on the path to deprecation. All TopicRecord attributes are accessible directly using a Topic instance.
Topic.refresh()
Refresh this topic instance with the latest data from the platform.
Fetches the current state of the topic from the Roboto platform and updates this instance’s data. Useful when the topic may have been modified by other processes or users.
Usage
topic = Topic.from_id("topic_xyz789")
# Topic may have been updated by another process
topic.refresh()
print(f"Current message count: {topic.message_count}")Return type
Properties
Topic.schema_checksum
Checksum of the topic’s message schema for validation.
Topic.schema_id
ID of the schema for this topic.
None if the topic has no schema, or if the schema has not yet been populated.
Topic.schema_name
Name of the message schema (e.g., ‘sensor_msgs/Image’).
Topic.set_default_representation()
Set the default representation for this topic.
Designates a specific representation as the default for this topic, which will be used when accessing topic data without specifying a particular representation.
Parameters
association roboto.Association pointing to the representation data.
storage_format roboto.Format of the representation data.
version intVersion number of the representation.
format Optional[str]Content format descriptor (e.g. “jpeg”, “sensor_msgs/Image”).
transformations Optional[list[str]]Transformation descriptors applied (e.g. [“downsample:0.5”]).
Returns
RepresentationRecord representing the newly set default representation.
Raises
Specified representation does not exist.
Caller lacks permission to modify the topic.
Usage
from roboto.association import Association
from roboto.domain.topics import RepresentationStorageFormat
topic = Topic.from_id("topic_xyz789")
default_repr = topic.set_default_representation(
association=Association.file("file_repr_456"),
storage_format=RepresentationStorageFormat.MCAP,
version=2,
)
print(topic.default_representation.representation_id)
# repr_789Properties
Topic.start_time
Start time of the topic data in nanoseconds since UNIX epoch.
Topic.to_association()
Convert this topic to an Association object.
Creates an Association object that can be used to reference this topic in other parts of the Roboto platform.
Returns
Association object representing this topic.
Usage
topic = Topic.from_id("topic_xyz789")
association = topic.to_association()
print(association.association_type)
# AssociationType.Topic
print(association.association_id)
# topic_xyz789Topic.update()
Updates a topic’s attributes and (optionally) its message paths.
Parameters
schema_name Union[Optional[str], roboto.topic schema name. Setting to None clears the attribute.
schema_checksum Union[Optional[str], roboto.topic schema checksum. Setting to None clears the attribute.
start_time Union[Optional[int], roboto.topic data start time, in epoch nanoseconds. Must be non-negative. Setting to None clears the attribute.
end_time Union[Optional[int], roboto.topic data end time, in epoch nanoseconds. Must be non-negative, and greater than start_time. Setting to None clears the attribute.
message_count Union[int, roboto.number of messages recorded for this topic. Must be non-negative.
metadata_changeset Union[roboto.a set of changes to apply to the topic’s metadata
message_path_changeset Union[roboto.a set of additions, deletions or updates to this topic’s message paths. Updating or deleting non-existent message paths has no effect. Attempting to (re-)add existing message paths raises RobotoConflictException, unless the changeset’s replace_all flag is set to True
Returns
this Topic object with any updates applied
Raises
if any method argument has an invalid value, e.g. a negative message_count
if, as part of the update, an attempt is made to add an already extant message path, and to this topic, and replace_all is not toggled on the message_path_changeset
Topic.update_message_path()
Update the metadata and attributes of a message path.
Modifies an existing message path within this topic, allowing updates to its metadata, data type, and canonical data type. This is useful for correcting or enhancing message path definitions after initial creation.
Parameters
message_path strName of the message path to update (e.g., “pose.position.x”).
metadata_changeset Union[roboto.Metadata changeset to apply to any existing metadata.
data_type Union[str, roboto.Native (application-specific) message path data type.
canonical_data_type Union[roboto.Canonical Roboto data type corresponding to the native data type.
path_in_schema Union[list[str], roboto.Returns
MessagePath instance representing the updated message path.
Raises
No message path with the given name exists for this topic.
Caller lacks permission to modify the topic.
Usage
from roboto.updates import TaglessMetadataChangeset
from roboto.domain.topics import CanonicalDataType
topic = Topic.from_id("topic_xyz789")
# Update metadata for a message path
changeset = TaglessMetadataChangeset(put_fields={"unit": "meters"})
updated_path = topic.update_message_path(message_path="pose.position.x", metadata_changeset=changeset)
print(updated_path.metadata["unit"])
# meters# Update data type and canonical type
updated_path = topic.update_message_path(
message_path="velocity", data_type="float64", canonical_data_type=CanonicalDataType.Number
)