---
sidebar:
  hidden: true
title: roboto.domain.topics.record
---
## Module Contents

### CanonicalDataType

```python
class roboto.domain.topics.record.CanonicalDataType(*args, **kwds)
```

`from roboto import CanonicalDataType`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L225-L298)

Bases: `enum.Enum`

Normalized data types used across different robotics frameworks.

Well-known and simplified data types that provide a common vocabulary for describing message path data types across different frameworks and technologies. These canonical types are primarily used for UI rendering decisions and cross-platform compatibility.

The canonical types abstract away framework-specific details while preserving the essential characteristics needed for data processing and visualization.

**References**

- ROS 1 field types: [http://wiki.ros.org/msg](http://wiki.ros.org/msg)
- ROS 2 field types: [https://docs.ros.org/en/iron/Concepts/Basic/About-Interfaces.html#field-types](https://docs.ros.org/en/iron/Concepts/Basic/About-Interfaces.html#field-types)
- uORB: [https://docs.px4.io/main/en/middleware/uorb.html#adding-a-new-topic](https://docs.px4.io/main/en/middleware/uorb.html#adding-a-new-topic)

**Example mappings:**

- `float32` -> `CanonicalDataType.Number`
- `uint8[]` -> `CanonicalDataType.Array`
- `sensor_msgs/Image` -> `CanonicalDataType.Image`
- `geometry_msgs/Pose` -> `CanonicalDataType.Object`
- `std_msgs/Header` -> `CanonicalDataType.Object`
- `string` -> `CanonicalDataType.String`
- `char` -> `CanonicalDataType.String`
- `bool` -> `CanonicalDataType.Boolean`
- `byte` -> `CanonicalDataType.Byte`

**Attributes**

- **CanonicalDataType.Array** = `'array'`: A sequence of values.

- **CanonicalDataType.Boolean** = `'boolean'`

- **CanonicalDataType.Byte** = `'byte'`

- **CanonicalDataType.Categorical** = `'categorical'`: Data that can take a limited, fixed set of values. To be interpreted correctly by Roboto clients, a `MessagePathRecord` with this type must have a `"categories"` metadata key on the `MessagePathRecord`, which must be the ordered list of values that the Categorical can take.

  For example, a signal that is logged as either "off" or "on" could be represented as a Categorical with the metadata `"categories"=["off", "on"]`. This allows Roboto to map the value "off" to 0 and "on" to 1 --each corresponding to their index position in the metadata array-- and therefore visualize these state transitions as a plot.

  The default visual representation of `Categorical` data will be the same as `String` data, but the Roboto visualizer will be capable of rendering Categorical data in a plot.

- **CanonicalDataType.Image** = `'image'`: Special purpose type for data that can be rendered as an image.

- **CanonicalDataType.LatDegFloat** = `'latdegfloat'`: Geographic point in degrees. E.g. 47.6749387 (used in ULog ver_data_format >= 2)

- **CanonicalDataType.LatDegInt** = `'latdegint'`: Geographic point in degrees, expressed as an integer. E.g. 317534036 (used in ULog ver_data_format \< 2)

- **CanonicalDataType.LonDegFloat** = `'londegfloat'`: Geographic point in degrees. E.g. 9.1445274 (used in ULog ver_data_format >= 2)

- **CanonicalDataType.LonDegInt** = `'londegint'`: Geographic point in degrees, expressed as an integer. E.g. 1199146398 (used in ULog ver_data_format \< 2)

- **CanonicalDataType.Number** = `'number'`

- **CanonicalDataType.NumberArray** = `'number_array'`

- **CanonicalDataType.Object** = `'object'`: A struct with attributes.

- **CanonicalDataType.String** = `'string'`

- **CanonicalDataType.Timestamp** = `'timestamp'`: Time elapsed since the Unix epoch, identifying a single instant on the time-line. Roboto clients will look for a `"unit"` metadata key on the `MessagePath` record, and will assume "ns" if none is found. If the timestamp is in a different unit, add the following metadata to the MessagePath record: `{ "unit": "s"|"ms"|"us"|"ns" }` The unit must be a known value from [`TimeUnit`](/reference/python-sdk/roboto/time#roboto.time.TimeUnit).

- **CanonicalDataType.Unknown** = `'unknown'`: This is a fallback and should be used sparingly.

### DataRange

```python
roboto.domain.topics.record.DataRange
```

`from roboto.domain.topics.record import DataRange`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L616-L616)

A slice of one file's contents, as `(start, end)` with `start` included and `end` excluded.

A position is expressed in whatever the file's format uses to address its contents: stored-row positions counted from 0, or nanoseconds of media time for video. The pair alone does not say which of the two applies, so a reader takes that from the file's format. The half-open form matches LeRobot's `dataset_from_index` and `dataset_to_index`, so row ranges read from LeRobot episode metadata carry over unchanged.

### FieldPath

```python
roboto.domain.topics.record.FieldPath
```

`from roboto.domain.topics.record import FieldPath`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L571-L571)

A schema field's path components, in order from the schema root to the leaf.

### MessagePathMetadataWellKnown

```python
class roboto.domain.topics.record.MessagePathMetadataWellKnown
```

`from roboto import MessagePathMetadataWellKnown`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L324-L359)

Bases: `roboto.compat.StrEnum`

Well-known metadata key names (with well-known semantics) that may be set in [`metadata`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.MessagePathRecord.metadata).

These are most often set by Roboto's first-party ingestion actions and used by Roboto clients.

**Attributes**

- **MessagePathMetadataWellKnown.Categories** = `'categories'`: An ordered list of values that a [`Categorical`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.CanonicalDataType.Categorical) can take.

  **Usage**

  - `"categories"=["off", "on"]`
  - `"categories"=["left", "up", "right", "down"]`

- **MessagePathMetadataWellKnown.ColumnName** = `'column_name'`: The original name or path to this field in the source data schema. May differ from [`message_path`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.MessagePathRecord.message_path) if character substitutions were applied to conform to naming requirements.

  **Notes**

  - Use of this metadata field is soft-deprecated as of SDK v0.24.0.
  - Prefer use of [`source_path`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.MessagePathRecord.source_path) and [`path_in_schema`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.MessagePathRecord.path_in_schema) instead. Those attributes are now first-class fields on [`MessagePathRecord`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.MessagePathRecord) and can be specified via [`AddMessagePathRequest`](/reference/python-sdk/roboto/domain/topics/operations#roboto.domain.topics.operations.AddMessagePathRequest).

- **MessagePathMetadataWellKnown.Unit** = `'unit'`: Unit of a field. E.g., 'ns' for a timestamp. If provided, must match a known, supported unit from [`TimeUnit`](/reference/python-sdk/roboto/time#roboto.time.TimeUnit).

### MessagePathRecord

```python
class roboto.domain.topics.record.MessagePathRecord(/, **data: Any)
```

`from roboto import MessagePathRecord`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L362-L452)

Bases: `pydantic.BaseModel`

Record representing a message path within a topic.

Defines a specific field or signal within a topic's data schema, including its data type, metadata, and statistical information. Message paths use dot notation to specify nested attributes within complex message structures.

Message paths are the fundamental units for accessing individual data elements within time-series robotics data, enabling fine-grained analysis and visualization of specific signals or measurements.

**Parameters**

- **data** (`Any`)

**Attributes**

- **MessagePathRecord.canonical_data_type** (`CanonicalDataType`): Normalized data type, used primarily internally by the Roboto Platform.

- **MessagePathRecord.created** (`datetime.datetime`)

- **MessagePathRecord.created_by** (`str`)

- **MessagePathRecord.data_type** (`str`): 'Native'/framework-specific data type of the attribute at this path. E.g. "float32", "uint8[]", "geometry_msgs/Pose", "string".

- **MessagePathRecord.message_path** (`str`): Dot-delimited path to the attribute within the datum record.

- **MessagePathRecord.message_path_id** (`str`)

- **MessagePathRecord.metadata** (`collections.abc.Mapping[str, Any]`) = `None`: Key-value pairs to associate with this metadata for discovery and search, e.g. { 'min': '0.71', 'max': '1.77 }

- **MessagePathRecord.modified** (`datetime.datetime`)

- **MessagePathRecord.modified_by** (`str`)

- **MessagePathRecord.org_id** (`str`): This message path's organization ID, which is the organization ID of the containing topic.

- **MessagePathRecord.path_in_schema** (`list[str]`): List of path components representing the field's location in the original data schema. Unlike [`message_path`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.MessagePathRecord.message_path), which must conform to Roboto-specific naming requirements and assumes dots separated path parts imply nested data, this preserves the exact path from the source data for accurate attribute access. This is expected to be the split representation of [`source_path`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.MessagePathRecord.source_path).

- **MessagePathRecord.representations** (`collections.abc.MutableSequence[RepresentationRecord]`) = `None`: Zero to many Representations of this MessagePath.

- **MessagePathRecord.source_path** (`str`): The original name of this field in the source data schema. May differ from [`message_path`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.MessagePathRecord.message_path) if character substitutions were applied to conform to naming requirements.

  This is the preferred field to use when specifying `message_path_include` or `message_path_exclude` to the `get_data` or `get_data_as_df` methods of [`Topic`](/reference/python-sdk/roboto/domain/topics/topic#roboto.domain.topics.topic.Topic) and [`Event`](/reference/python-sdk/roboto/domain/events/event#roboto.domain.events.event.Event).

- **MessagePathRecord.topic_id** (`str`)

#### MessagePathRecord.parents()

```python
def parents(delimiter: str = '.') -> list[str]
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L435-L448)

Logical message path ancestors of this path.

**Usage**

Given a deeply nested field `root.sub_obj_1.sub_obj_2.leaf_field`:

```python
field = "root.sub_obj_1.sub_obj_2.leaf_field"
record = MessagePathRecord(message_path=field)  # other fields omitted for brevity
print(record.parents())
# ['root.sub_obj_1.sub_obj_2', 'root.sub_obj_1', 'root']
```

**Parameters**

- **delimiter** (`str`)

**Returns**

- `list[str]`

#### MessagePathRecord.to_field_selection()

```python
def to_field_selection() -> roboto.formats.FieldSelection
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L450-L452)

Translate this record into the [`FieldSelection`](/reference/python-sdk/roboto/formats/fields#roboto.formats.fields.FieldSelection) the format decoders accept.

**Returns**

- `roboto.formats.FieldSelection`

### MessagePathRepresentationMapping

```python
class roboto.domain.topics.record.MessagePathRepresentationMapping(/, **data: Any)
```

`from roboto.domain.topics import MessagePathRepresentationMapping`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L455-L464)

Bases: `pydantic.BaseModel`

Mapping between message paths and their data representation.

Associates a set of message paths with a specific representation that contains their data. This mapping is used to efficiently locate and access data for specific message paths within topic representations.

**Parameters**

- **data** (`Any`)

**Attributes**

- **MessagePathRepresentationMapping.message_paths** (`collections.abc.MutableSequence[MessagePathRecord]`)
- **MessagePathRepresentationMapping.representation** (`RepresentationRecord`)

### MessagePathStatistic

```python
class roboto.domain.topics.record.MessagePathStatistic(*args, **kwds)
```

`from roboto import MessagePathStatistic`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L301-L321)

Bases: `enum.Enum`

Statistics computed by Roboto in our standard ingestion actions.

Which of these a given message path actually carries depends on the ingestion path that produced it, so treat every one as optional: read them with `metadata.get(...)` or through the corresponding [`MessagePath`](/reference/python-sdk/roboto/domain/topics/message_path#roboto.domain.topics.message_path.MessagePath) property, both of which yield `None` when the statistic was never written, and never assume a missing value means zero. Indexing [`metadata`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.MessagePathRecord.metadata) directly raises `KeyError` for a statistic that was never written.

**Attributes**

- **MessagePathStatistic.Count** = `'count'`
- **MessagePathStatistic.Max** = `'max'`
- **MessagePathStatistic.Mean** = `'mean'`
- **MessagePathStatistic.Median** = `'median'`
- **MessagePathStatistic.Min** = `'min'`
- **MessagePathStatistic.P25** = `'p25'`
- **MessagePathStatistic.P75** = `'p75'`
- **MessagePathStatistic.P95** = `'p95'`
- **MessagePathStatistic.P99** = `'p99'`
- **MessagePathStatistic.Stddev** = `'stddev'`

### RepresentationRecord

```python
class roboto.domain.topics.record.RepresentationRecord(/, **data: Any)
```

`from roboto import RepresentationRecord`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L174-L222)

Bases: `pydantic.BaseModel`

Record representing a data representation for topic content.

A representation is a pointer to processed topic data stored in a specific format and location. Representations enable efficient access to topic data by providing multiple storage formats optimized for different use cases.

Most message paths within a topic point to the same representation (e.g., an MCAP or Parquet file containing all topic data). However, some message paths may have multiple representations for analytics or preview formats.

Representations are versioned and associated with specific files or storage locations through the association field.

**Parameters**

- **data** (`Any`)

**Attributes**

- **RepresentationRecord.association** (`roboto.association.Association`): Identifier and entity type with which this Representation is associated. E.g., a file, a database.

- **RepresentationRecord.created** (`datetime.datetime`)

- **RepresentationRecord.format** (`str | None`) = `None`: Content format descriptor for this representation. For image topics: the image encoding (e.g. "jpeg", "png") for simplified representations, or the ROS schema name (e.g. "sensor_msgs/Image") for original/passthrough representations. None for non-image topics or legacy representations.

- **RepresentationRecord.modified** (`datetime.datetime`)

- **RepresentationRecord.representation_id** (`str`)

- **RepresentationRecord.storage_format** (`RepresentationStorageFormat`)

- **RepresentationRecord.topic_id** (`str`)

- **RepresentationRecord.transformations** (`list[str]`) = `None`: Ordered list of transformation descriptors applied to produce this representation. Empty for original/passthrough representations.

  Each entry is a `"<kind>:<param>"` string where `<kind>` is a [`TransformationKind`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.TransformationKind) member. Construct entries via [`TransformationKind.with_param()`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.TransformationKind.with_param) and parse them via [`TransformationKind.parse()`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.TransformationKind.parse) to keep the vocabulary centralized.

  Example: `["downsample:0.5", "encode:jpeg"]`

- **RepresentationRecord.version** (`int`)

### RepresentationSelector

```python
class roboto.domain.topics.record.RepresentationSelector(/, **data: Any)
```

`from roboto.domain.topics import RepresentationSelector`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L22-L120)

Bases: `pydantic.BaseModel`

Criteria for selecting among multiple representations of the same data.

When a message path has multiple representations (e.g., both raw sensor data and a processed JPEG encoding), this is a *hard filter*: only matching representations qualify, and message paths with no matching representation are dropped from selection results — callers must handle empty or partial output.

**Legacy carve-out for \`\`content_format\`\`:** representations with no `format` set (i.e., predating the field) are treated as matching any `content_format` request. This keeps older data accessible. When both an explicit format match and a legacy representation are available for the same message path, the explicit match wins.

Instances are immutable (`frozen=True`) so they can be safely shared — including as default arguments to methods like [`Topic.get_data()`](/reference/python-sdk/roboto/domain/topics/topic#roboto.domain.topics.topic.Topic.get_data).

**Parameters**

- **data** (`Any`)

**Attributes**

- **RepresentationSelector.content_format** (`str | None`) = `None`: If set, only representations whose `format` field matches this value qualify (e.g., `"jpeg"`). Representations with no `format` also qualify under the legacy carve-out. `None` means no constraint.
- **RepresentationSelector.model_config**: Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- **RepresentationSelector.transformations** (`list[str] | None`) = `None`: If set, only representations whose `transformations` field matches exactly qualify. `[]` matches representations with no transformations (i.e., raw/original data). `None` means no constraint.

#### RepresentationSelector.matches()

```python
def matches(representation: RepresentationRecord) -> bool
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L57-L69)

Check whether a representation satisfies this selector's criteria.

A representation matches when each non-`None` selector field is satisfied. For `content_format`, representations with no `format` set are treated as matching (legacy carve-out — see class docstring).

**Parameters**

- **representation** (`RepresentationRecord`)

**Returns**

- `bool`

#### RepresentationSelector.raw()

```python
@classmethod
def raw() -> RepresentationSelector
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L53-L55)

Select representations with no transformations applied (original data).

**Returns**

- `RepresentationSelector`

#### RepresentationSelector.select_representations()

```python
def select_representations(
    mappings: list[MessagePathRepresentationMapping],
) -> list[MessagePathRepresentationMapping]
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L71-L120)

Select one representation per message path that matches this selector.

When the API returns multiple representations for the same message paths (e.g., both a raw MCAP and a processed JPEG MCAP for an image topic), this method picks a matching representation for each path and deduplicates so each message path appears in exactly one mapping.

Non-matching representations are excluded. When both an explicit format match and a legacy representation (no `format` set) cover the same message path, the explicit match wins. Message paths covered by no matching representation are dropped — callers must handle empty or partial results.

**Parameters**

- **mappings** (`list[MessagePathRepresentationMapping]`): All representation mappings, potentially with overlapping message paths.

**Returns**

- `list[MessagePathRepresentationMapping]`: Deduplicated mappings of message paths to matching representations. Empty if no representation matches.

### RepresentationStorageFormat

```python
class roboto.domain.topics.record.RepresentationStorageFormat(*args, **kwds)
```

`from roboto import RepresentationStorageFormat`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L123-L133)

Bases: `enum.Enum`

Supported storage formats for topic data representations.

Defines the available formats for storing and accessing topic data within the Roboto platform. Each format has different characteristics and use cases.

**Attributes**

- **RepresentationStorageFormat.MCAP** = `'mcap'`: MCAP format - optimized for robotics time-series data with efficient random access.
- **RepresentationStorageFormat.PARQUET** = `'parquet'`: Parquet format - columnar storage optimized for analytics and large-scale data processing.

### SchemaFieldRecord

```python
class roboto.domain.topics.record.SchemaFieldRecord(/, **data: Any)
```

`from roboto import SchemaFieldRecord`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L628-L660)

Bases: `pydantic.BaseModel`

A single field within a topic schema.

One entry per unique field path within a schema; field paths are deduplicated across topics that share the schema.

**Parameters**

- **data** (`Any`)

**Attributes**

- **SchemaFieldRecord.canonical_data_type** (`CanonicalDataType`): Normalized data type used for cross-framework compatibility and UI rendering decisions.
- **SchemaFieldRecord.created** (`datetime.datetime | None`) = `None`
- **SchemaFieldRecord.created_by** (`str`)
- **SchemaFieldRecord.data_type** (`str`): Native, framework-specific data type of the field. E.g. "float32", "uint8[]", "geometry_msgs/Pose".
- **SchemaFieldRecord.field_id** (`str`)
- **SchemaFieldRecord.model_config**: Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- **SchemaFieldRecord.modified** (`datetime.datetime | None`) = `None`
- **SchemaFieldRecord.modified_by** (`str`)
- **SchemaFieldRecord.name** (`str`): Human-readable display name of the field (typically the final component of `path_in_schema`).
- **SchemaFieldRecord.org_id** (`str`)
- **SchemaFieldRecord.path_in_schema** (`FieldPath`): Path components locating this field in the source data schema. Each component is a schema-native attribute name, in order from the schema root to the leaf.
- **SchemaFieldRecord.schema_id** (`str`)
- **SchemaFieldRecord.unit** (`str | None`) = `None`: Optional unit of the field's values (e.g., `"ns"`, `"m/s"`). None if the field is unitless or unknown.

### TimelineExtentRecord

```python
class roboto.domain.topics.record.TimelineExtentRecord(/, **data: Any)
```

`from roboto import TimelineExtentRecord`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L768-L808)

Bases: `pydantic.BaseModel`

Min/max timestamp bounds for one topic partition measured against one timeline source.

Written by ingest when a partition's timestamps are summarized for a given source (e.g., a schema timestamp field, or message log/publish time).

Stored timestamps come through verbatim from the data source: they may be absolute nanoseconds since the Unix epoch, or partition-relative (e.g., monotonic from zero). `unix_epoch_offset_ns` is the calibration that projects stored values onto Unix-epoch wall-clock: `session_time_ns = stored_time_ns + unix_epoch_offset_ns`. A value of 0 means the stored timestamps are already absolute Unix-epoch ns, or that no calibration has been applied yet.

**Parameters**

- **data** (`Any`)

**Attributes**

- **TimelineExtentRecord.created** (`datetime.datetime | None`) = `None`
- **TimelineExtentRecord.created_by** (`str`)
- **TimelineExtentRecord.max_timestamp** (`int | None`) = `None`: Largest stored timestamp in this extent, in nanoseconds. Absolute or partition-relative per the source.
- **TimelineExtentRecord.min_timestamp** (`int | None`) = `None`: Smallest stored timestamp in this extent, in nanoseconds. Absolute or partition-relative per the source.
- **TimelineExtentRecord.model_config**: Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- **TimelineExtentRecord.modified** (`datetime.datetime | None`) = `None`
- **TimelineExtentRecord.modified_by** (`str`)
- **TimelineExtentRecord.org_id** (`str`)
- **TimelineExtentRecord.timeline_extent_id** (`str`)
- **TimelineExtentRecord.timeline_source_id** (`str`): ID of the timeline source these bounds are measured against.
- **TimelineExtentRecord.topic_part_id** (`str`): ID of the topic partition these bounds apply to.
- **TimelineExtentRecord.unix_epoch_offset_ns** (`int`) = `0`: Nanoseconds to add to each stored timestamp to obtain Unix-epoch wall-clock time: `session_time_ns = stored_time_ns + unix_epoch_offset_ns`. 0 when stored timestamps are already absolute Unix-epoch ns, or when no calibration has been recorded for this partition/source pair.

### TimelineSourceKind

```python
type roboto.domain.topics.record.TimelineSourceKind = typing.Literal['schema_field', 'message_log_time', 'message_publish_time']
```

`from roboto import TimelineSourceKind`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L711-L711)

Discriminator for how a `TimelineSourceRecord` derives its timestamps.

`"schema_field"` points at a timestamp field inside the schema (`field_id` is set). `"message_log_time"` and `"message_publish_time"` point at the message envelope's log or publish timestamp respectively (`field_id` is `None`).

### TimelineSourceRecord

```python
class roboto.domain.topics.record.TimelineSourceRecord(/, **data: Any)
```

`from roboto import TimelineSourceRecord`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L721-L764)

Bases: `pydantic.BaseModel`

A registered timeline source for a schema.

A timeline source either points at a timestamp field inside the schema (`source="schema_field"`, `field_id` set) or at the message envelope's log or publish timestamp (`source` in `{"message_log_time", "message_publish_time"}`, `field_id` is `None`). Timeline sources are scoped to a schema, not a topic, so topics that share a schema share their timeline sources.

**Parameters**

- **data** (`Any`)

**Attributes**

- **TimelineSourceRecord.created** (`datetime.datetime | None`) = `None`
- **TimelineSourceRecord.created_by** (`str`)
- **TimelineSourceRecord.field_id** (`str | None`) = `None`: ID of the schema field supplying timestamps. Set when `source == "schema_field"`; otherwise `None`.
- **TimelineSourceRecord.is_default** (`bool`) = `False`: Whether this timeline source is the default for its schema when no source is specified explicitly.
- **TimelineSourceRecord.model_config**: Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- **TimelineSourceRecord.modified** (`datetime.datetime | None`) = `None`
- **TimelineSourceRecord.modified_by** (`str`)
- **TimelineSourceRecord.name** (`str`): Human-readable label for this timeline source.
- **TimelineSourceRecord.org_id** (`str`)
- **TimelineSourceRecord.schema_id** (`str`): ID of the schema this timeline source is registered against.
- **TimelineSourceRecord.source** (`TimelineSourceKind`): Where timestamps come from: a schema field (`"schema_field"`), or the message envelope's log or publish timestamp (`"message_log_time"` / `"message_publish_time"`).
- **TimelineSourceRecord.timeline_source_id** (`str`)

### TopicIdentityRecord

```python
class roboto.domain.topics.record.TopicIdentityRecord(/, **data: Any)
```

`from roboto import TopicIdentityRecord`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L690-L708)

Bases: `pydantic.BaseModel`

A durable identity for a topic.

Within an organization, topic names are unique: data logged under the same topic name in different files shares a single identity record.

**Parameters**

- **data** (`Any`)

**Attributes**

- **TopicIdentityRecord.created** (`datetime.datetime | None`) = `None`
- **TopicIdentityRecord.created_by** (`str`)
- **TopicIdentityRecord.model_config**: Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- **TopicIdentityRecord.modified** (`datetime.datetime | None`) = `None`
- **TopicIdentityRecord.modified_by** (`str`)
- **TopicIdentityRecord.name** (`str`): Human-readable topic name (e.g., `"/camera/image_raw"`). Unique within an organization.
- **TopicIdentityRecord.org_id** (`str`)
- **TopicIdentityRecord.topic_id** (`str`): Stable identifier for this topic identity.

### TopicPartitionRecord

```python
class roboto.domain.topics.record.TopicPartitionRecord(/, **data: Any)
```

`from roboto import TopicPartitionRecord`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L812-L848)

Bases: `pydantic.BaseModel`

One file's data for a topic.

Pairs a topic identity with a file and carries the facts that vary from file to file: the schema the file's messages follow (`schema_id`), the device that produced them, and the `data_range` locating them inside the file, for formats that pack several slices of data into one shared file. A partition references a file, not a specific version; reads always resolve to the current version.

**Parameters**

- **data** (`Any`)

**Attributes**

- **TopicPartitionRecord.created** (`datetime.datetime | None`) = `None`

- **TopicPartitionRecord.created_by** (`str`)

- **TopicPartitionRecord.data_range** (`DataRange | None`) = `None`: The slice of the file this partition's data occupies, as `(start, end)`, or `None` for the whole file.

  `start` alone identifies the partition within its (topic, file) pair, since a slice's starting position is stable across re-ingest: re-declaring a slice that begins at the same position updates the existing partition instead of adding a second, overlapping one.

- **TopicPartitionRecord.device_id** (`str | None`) = `None`: ID of the device that produced this partition's data, if known.

- **TopicPartitionRecord.fs_node_id** (`str`): ID of the file this partition's data lives in.

- **TopicPartitionRecord.model_config**: Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

- **TopicPartitionRecord.modified** (`datetime.datetime | None`) = `None`

- **TopicPartitionRecord.modified_by** (`str`)

- **TopicPartitionRecord.org_id** (`str`)

- **TopicPartitionRecord.schema_id** (`str`): ID of the schema this partition's messages follow.

- **TopicPartitionRecord.topic_id** (`str`): ID of the topic identity this partition belongs to.

- **TopicPartitionRecord.topic_part_id** (`str`)

### TopicRecord

```python
class roboto.domain.topics.record.TopicRecord(/, **data: Any)
```

`from roboto import TopicRecord`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L467-L547)

Bases: `pydantic.BaseModel`

Record representing a topic in the Roboto platform.

A topic is a collection of timestamped data records that share a common name and association (typically a file). Topics represent logical data streams from robotics systems, such as sensor readings, robot state information, or other time-series data.

Data from the same file with the same topic name are considered part of the same topic. Data from different files or with different topic names belong to separate topics, even if they have similar schemas.

When source files are chunked by time or size but represent the same logical data collection, they will produce multiple topic records for the same "logical topic" (same name and schema) across those chunks.

**Parameters**

- **data** (`Any`)

**Attributes**

- **TopicRecord.association** (`roboto.association.Association`): Identifier and entity type with which this Topic is associated. E.g., a file, a dataset.
- **TopicRecord.created** (`datetime.datetime`)
- **TopicRecord.created_by** (`str`)
- **TopicRecord.default_representation** (`RepresentationRecord | None`) = `None`: Default Representation for this Topic. Assume that if a MessagePath is not more specifically associated with a Representation, it should use this one.
- **TopicRecord.end_time** (`int | None`) = `None`: Timestamp of oldest message in topic, in nanoseconds since epoch (assumed Unix epoch).
- **TopicRecord.message_count** (`int | None`) = `None`
- **TopicRecord.message_paths** (`collections.abc.MutableSequence[MessagePathRecord]`) = `None`: Zero to many MessagePathRecords associated with this TopicSource.
- **TopicRecord.metadata** (`collections.abc.Mapping[str, Any]`) = `None`: Arbitrary metadata.
- **TopicRecord.modified** (`datetime.datetime`)
- **TopicRecord.modified_by** (`str`)
- **TopicRecord.org_id** (`str`)
- **TopicRecord.schema_checksum** (`str | None`) = `None`: Checksum of topic schema. May be None if topic does not have a known/named schema.
- **TopicRecord.schema_id** (`str | None`) = `None`: ID of the schema record for this topic. May be None if the topic has no schema, or if the schema record has not yet been populated.
- **TopicRecord.schema_name** (`str | None`) = `None`: Type of messages in topic. E.g., "sensor_msgs/PointCloud2". May be None if topic does not have a known/named schema.
- **TopicRecord.start_time** (`int | None`) = `None`: Timestamp of earliest message in topic, in nanoseconds since epoch (assumed Unix epoch).
- **TopicRecord.topic_id** (`str`)
- **TopicRecord.topic_name** (`str`)

### TopicSchemaRecord

```python
class roboto.domain.topics.record.TopicSchemaRecord(/, **data: Any)
```

`from roboto import TopicSchemaRecord`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L664-L686)

Bases: `pydantic.BaseModel`

A content-addressed topic schema.

Within an organization, two schemas with identical fields share a single record (identified by a deterministic checksum of the fields). `name` is a mutable, informational label (last-writer-wins) and is not part of the schema's identity.

**Parameters**

- **data** (`Any`)

**Attributes**

- **TopicSchemaRecord.checksum** (`str`): Deterministic checksum computed over the schema's fields; identical schemas share a checksum.
- **TopicSchemaRecord.created** (`datetime.datetime | None`) = `None`
- **TopicSchemaRecord.created_by** (`str`)
- **TopicSchemaRecord.model_config**: Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- **TopicSchemaRecord.modified** (`datetime.datetime | None`) = `None`
- **TopicSchemaRecord.modified_by** (`str`)
- **TopicSchemaRecord.name** (`str | None`) = `None`: Informational label for the schema (e.g., `"sensor_msgs/PointCloud2"`). Not part of identity.
- **TopicSchemaRecord.org_id** (`str`)
- **TopicSchemaRecord.schema_id** (`str`): Stable identifier for this schema record.

### TopicTimeBounds

```python
class roboto.domain.topics.record.TopicTimeBounds(/, **data: Any)
```

`from roboto.domain.topics import TopicTimeBounds`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L550-L568)

Bases: `pydantic.BaseModel`

Earliest start and latest end, in epoch nanoseconds, across a set of topics.

The aggregate of the `start_time` and `end_time` of every topic in the set, computed server-side so a caller does not have to page the whole set to fold them.

Either field is None when no topic in the set carries that timestamp — because the set is empty, or because every topic in it left that bound unset.

**Parameters**

- **data** (`Any`)

**Attributes**

- **TopicTimeBounds.end_time** (`int | None`) = `None`: Latest `end_time` across the set, in nanoseconds since epoch (assumed Unix epoch).
- **TopicTimeBounds.start_time** (`int | None`) = `None`: Earliest `start_time` across the set, in nanoseconds since epoch (assumed Unix epoch).

### TransformationKind

```python
class roboto.domain.topics.record.TransformationKind
```

`from roboto.domain.topics import TransformationKind`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L136-L171)

Bases: `roboto.compat.StrEnum`

Canonical vocabulary of transformations that can be applied when producing a representation.

A transformation is serialized into `RepresentationRecord.transformations` as a `"<kind>:<param>"` string (e.g. `"downsample:0.5"`, `"encode:jpeg"`). This enum is the source of truth for the set of supported kinds; the parameter tail remains free-form because different kinds carry different parameter shapes (floats, format tokens, etc.).

Producers should construct transformation strings via [`with_param()`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.TransformationKind.with_param) and consumers should destructure them via [`parse()`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.TransformationKind.parse) to keep the vocabulary centralized.

**Usage**

```python
TransformationKind.DOWNSAMPLE.with_param(0.5)
# 'downsample:0.5'
TransformationKind.parse("encode:jpeg")
# (<TransformationKind.ENCODE: 'encode'>, 'jpeg')
```

**Attributes**

- **TransformationKind.DOWNSAMPLE** = `'downsample'`: Spatial or temporal downsampling. Parameter is a float scale factor in `(0, 1]`.
- **TransformationKind.ENCODE** = `'encode'`: Re-encoding to a different content format. Parameter is the target format token (e.g. `"jpeg"`).

#### TransformationKind.parse()

```python
@classmethod
def parse(descriptor: str) -> tuple[TransformationKind, str]
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L164-L171)

Parse a `"<kind>:<param>"` transformation descriptor into its kind and raw parameter.

**Parameters**

- **descriptor** (`str`)

**Raises**

- `ValueError`: If the kind prefix is not a known [`TransformationKind`](/reference/python-sdk/roboto/domain/topics/record#roboto.domain.topics.record.TransformationKind) member.

**Returns**

- `tuple[TransformationKind, str]`

#### TransformationKind.with_param()

```python
def with_param(param: object) -> str
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L159-L161)

Construct a transformation descriptor string for this kind with the given parameter.

**Parameters**

- **param** (`object`)

**Returns**

- `str`

### validate_data_range()

```python
def roboto.domain.topics.record.validate_data_range(
    data_range: tuple[int, int],
) -> tuple[int, int]
```

`from roboto.domain.topics.record import validate_data_range`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/domain/topics/record.py#L587-L613)

Check that `data_range` is a pair of non-negative positions with `start < end`.

Both positions must fit in a signed 64-bit integer, which is how the platform stores them.

**Parameters**

- **data_range** (`tuple[int, int]`): The `(start, end)` pair to check, with `start` included and `end` excluded.

**Returns**

- `tuple[int, int]`: `data_range`, unchanged.

**Raises**

- `ValueError`: `start` is negative, `end` is not greater than `start`, or a position is too large for a signed 64-bit integer.
