roboto.domain.sessions#

Submodules#

Package Contents#

class roboto.domain.sessions.AddFilesRequest(/, **data)#

Bases: pydantic.BaseModel

Request body for POST /v1/sessions/id/<session_id>/files.

Adds one or more files as contributions to the session.

Parameters:

data (Any)

files: list[SessionFile]#
model_config#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class roboto.domain.sessions.AttachToDeviceRequest(/, **data)#

Bases: pydantic.BaseModel

Request body for POST /v1/sessions/id/<session_id>/devices.

Attaches a device as a subject of the session.

Parameters:

data (Any)

device_id: str#
model_config#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class roboto.domain.sessions.CreateSessionRequest(/, **data)#

Bases: pydantic.BaseModel

Request body for POST /v1/sessions.

Creates a new session with zero, one, or many devices attached as subjects.

Parameters:

data (Any)

custom_fields: dict[str, Any] | None = None#

Initial values for Ready custom fields on this session.

Each key must be the name of a CustomField that is Ready for the caller’s org and the Session entity type; each value must satisfy the field’s declared type. Names that are undefined or not Ready, and values that don’t match the field’s type, are rejected with a structured error.

description: str | None = None#

Optional description of the Session.

device_ids: list[str] = None#
metadata: dict[str, Any] = None#

Key-value metadata to associate with the Session.

Sessions cannot be filtered or sorted by metadata keys; for queryable structured attributes, define a custom field on the Session entity type.

model_config#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str | None = None#
tags: list[str] = None#

Tags to associate with the Session.

class roboto.domain.sessions.DetachFromDeviceRequest(/, **data)#

Bases: pydantic.BaseModel

Request body for DELETE /v1/sessions/id/<session_id>/devices.

Detaches a device from the session; the session itself is not deleted.

Parameters:

data (Any)

device_id: str#
model_config#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class roboto.domain.sessions.RemoveFilesRequest(/, **data)#

Bases: pydantic.BaseModel

Request body for DELETE /v1/sessions/id/<session_id>/files.

Removes the listed files’ contributions from the session.

Parameters:

data (Any)

file_ids: list[str]#
model_config#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class roboto.domain.sessions.Session(record, roboto_client=None)#

An operational time window of a Device.

A Session is a drone flight, a vehicle drive, a robot arm test run — some contiguous activity in the real world. It groups the recordings, logs, and other data produced during that window. Because a Session is bounded by the activity rather than by the recordings, it can span many files or cover just a slice of one. Files participate as contributions, each optionally narrowed to a sub-window of the file.

The Session’s aggregate bounds — min_timestamp_ns and max_timestamp_ns, in Unix-epoch nanoseconds — are recomputed by Roboto across all file contributions on every add or remove, and the returned instance reflects the updated bounds.

A Session can reference one or many devices: a single drone for a solo mission, or all of the drones in a formation flight. Use attach_to_device() and detach_from_device() to change which devices it references.

How to create a Session:

  • Session.create() accepts zero, one, or many devices.

  • create_session() is a shortcut for the common single-device case.

  • create_session() creates a Session for an existing Dataset, inferring the devices involved and pre-populating files from the Dataset.

Once created, include files with add_file() or add_files().

Examples

Create a Session for a drone flight, include a recording, and list its topics:

>>> from roboto.domain.sessions import Session
>>> session = Session.create(name="flight-2026-04-23-001", device_ids=["dv_abc"])
>>> session = session.add_file("fl_0123456789abcdef")
>>> for topic in session.list_topics():
...     print(topic.name)
Parameters:
add_file(file, range_min_timestamp_ns=None, range_max_timestamp_ns=None)#

Include a single file in this Session as a contribution.

Thin convenience over add_files() for the common one-file case.

Parameters:
  • file (Union[roboto.domain.files.File, str]) – A File or a raw file id.

  • range_min_timestamp_ns (Optional[int]) – Optional lower bound (Unix-epoch nanoseconds) of this file’s contribution to the Session. Must be paired with range_max_timestamp_ns; leaving both None contributes the whole file’s time window.

  • range_max_timestamp_ns (Optional[int]) – Optional upper bound paired with range_min_timestamp_ns.

Returns:

This Session, refreshed from the server response.

Return type:

Session

Examples

Include a whole file:

>>> session.add_file("fl_0123456789abcdef")

Include only a sub-window of a file:

>>> session.add_file(
...     "fl_0123456789abcdef",
...     range_min_timestamp_ns=1_700_000_000_000_000_000,
...     range_max_timestamp_ns=1_700_000_060_000_000_000,
... )
add_files(files)#

Include the given files in this Session as contributions.

Each file may carry optional range_min_timestamp_ns / range_max_timestamp_ns bounds (Unix-epoch nanoseconds) narrowing its contribution to a sub-window of the file’s data. The service recomputes the Session’s aggregate bounds across all contributions, and the Session instance reflects the new min_timestamp_ns / max_timestamp_ns on return.

Parameters:

files (collections.abc.Sequence[roboto.domain.sessions.operations.SessionFile]) – Files to contribute to the Session.

Returns:

This Session, refreshed from the server response.

Return type:

Session

Examples

>>> from roboto.domain.sessions import SessionFile
>>> session.add_files(
...     [
...         SessionFile(file_id="fl_aaa"),
...         SessionFile(
...             file_id="fl_bbb",
...             range_min_timestamp_ns=1_700_000_000_000_000_000,
...             range_max_timestamp_ns=1_700_000_060_000_000_000,
...         ),
...     ]
... )
attach_to_device(device_id)#

Attach a Device to this Session as a subject.

A Session may have many device attachments. For example, a formation flight where multiple drones operate within a single activity window.

Parameters:

device_id (str) – ID of the Device to add as a subject of this Session.

Return type:

None

Examples

>>> session.attach_to_device("dv_wingman")
>>> list(session.list_devices())
['dv_lead', 'dv_wingman']
clear_custom_field(name)#

Clear a single custom-field value on this session to None.

Parameters:

name (str)

Return type:

Session

clear_custom_fields(names)#

Clear multiple custom-field values on this session to None.

Parameters:

names (collections.abc.Sequence[str])

Return type:

Session

classmethod create(name=None, device_ids=(), description=None, metadata=None, tags=None, custom_fields=None, caller_org_id=None, roboto_client=None)#

Create a new Session, optionally associating it with one or more devices.

Prefer create_session() for the common single-device case. To add devices to an existing Session later, see attach_to_device().

Parameters:
  • name (Optional[str]) – Optional short name for the Session (max 120 characters).

  • device_ids (collections.abc.Sequence[str]) – Devices to associate with the Session at creation. Empty (the default) creates a Session with no associated devices.

  • description (Optional[str]) – Optional description of the Session.

  • metadata (Optional[dict[str, Any]]) – Optional initial metadata. Sessions are not filterable or sortable by metadata keys; for queryable structured attributes, define a custom cield on the Session entity type.

  • tags (Optional[collections.abc.Sequence[str]]) – Optional initial tags. Sessions can be filtered by tag membership but are not sortable by tag.

  • custom_fields (Optional[dict[str, Any]]) – Optional initial values for Ready custom fields defined on Sessions in the caller’s org. Keys must match Ready field names; values must satisfy each field’s declared type.

  • caller_org_id (Optional[str]) – Caller’s org scope. Required when the caller belongs to multiple orgs.

  • roboto_client (Optional[roboto.http.RobotoClient]) – Optional RobotoClient; defaults to the ambient one.

Returns:

The created Session.

Return type:

Session

Examples

>>> from roboto.domain.sessions import Session
>>> session = Session.create(
...     name="flight-2026-04-23-001",
...     device_ids=["dv_a", "dv_b"],
...     description="formation flight #4",
...     metadata={"pilot": "alice"},
...     tags=["pre-flight-check"],
... )
property created: datetime.datetime | None#

UTC timestamp when this Session was created.

Return type:

Optional[datetime.datetime]

property created_by: str#

Identifier of the user or service which created this Session.

Return type:

str

property custom_fields: dict[str, Any]#

Custom-field values defined on Sessions in this org.

Every Ready CustomField defined for (org_id, Session) appears as a key. Values that have not been set on this session surface as None rather than being absent. Empty when no custom fields are defined for the org.

Return type:

dict[str, Any]

delete()#

Delete this Session. Its file contributions and device attachments are removed alongside it.

Return type:

None

property description: str | None#

Optional description of this Session.

Return type:

Optional[str]

detach_from_device(device_id)#

Remove a Device from this Session’s subjects.

Parameters:

device_id (str) – ID of the Device to remove as a subject of this Session.

Return type:

None

classmethod for_dataset(dataset_id, owner_org_id=None, roboto_client=None)#

Iterate Sessions whose composition includes any file in the given dataset.

Parameters:
  • dataset_id (str) – Dataset whose sessions to list.

  • owner_org_id (Optional[str]) – Org that owns the dataset. Required when the caller belongs to multiple orgs.

  • roboto_client (Optional[roboto.http.RobotoClient]) – Optional RobotoClient; defaults to the ambient one.

Yields:

Sessions, one at a time, following pagination automatically.

Return type:

collections.abc.Generator[Session, None, None]

Examples

>>> from roboto.domain.sessions import Session
>>> for session in Session.for_dataset("ds_abc"):
...     print(session.session_id, session.name)
classmethod for_org(org_id=None, roboto_client=None)#

Iterate all Sessions visible to the caller’s org.

Parameters:
  • org_id (Optional[str]) – Caller’s org scope. Required when the caller belongs to multiple orgs.

  • roboto_client (Optional[roboto.http.RobotoClient]) – Optional RobotoClient; defaults to the ambient one.

Yields:

Sessions, one at a time, following pagination automatically.

Return type:

collections.abc.Generator[Session, None, None]

classmethod from_id(session_id, owner_org_id=None, roboto_client=None)#

Load a Session by ID.

Parameters:
  • session_id (str) – Session primary key.

  • owner_org_id (Optional[str]) – Caller’s org scope. Required when the caller belongs to multiple orgs.

  • roboto_client (Optional[roboto.http.RobotoClient]) – Optional RobotoClient; defaults to the ambient one.

Returns:

The Session.

Return type:

Session

list_devices()#

Iterate the device IDs attached as subjects of this Session, paginated.

Return type:

collections.abc.Generator[str, None, None]

list_files()#

Iterate this Session’s file contributions, following pagination automatically.

Yields:

SessionFile entries, each carrying its optional range_min_timestamp_ns / range_max_timestamp_ns sub-window bounds.

Return type:

collections.abc.Generator[roboto.domain.sessions.operations.SessionFile, None, None]

list_metrics()#

Return all metrics published to this Session.

Returns:

List of Metric instances for this Session.

Return type:

list[roboto.domain.metrics.metric.Metric]

Examples

>>> metrics = session.list_metrics()
>>> for m in metrics:
...     print(m.name, m.value)
list_topics()#

Iterate topic identities reachable from this Session, following pagination.

Results are range-filtered: a topic identity is yielded only when the Session’s time window overlaps at least one of the topic’s timeline extents (TimelineExtentRecord). Results are deduplicated across files and partitions, ordered by name with topic_id as a deterministic tiebreaker.

Yields:

roboto.domain.topics.TopicIdentityRecord entries.

Return type:

collections.abc.Generator[roboto.domain.topics.record.TopicIdentityRecord, None, None]

Examples

>>> for topic in session.list_topics():
...     print(topic.topic_id, topic.name)
property max_timestamp_ns: int | None#

Upper aggregate bound across this Session’s recording data contributions, in Unix-epoch nanoseconds.

None when the Session has no contributions.

Return type:

Optional[int]

property metadata: dict[str, Any]#

User-supplied metadata attached to this Session.

Sessions are not filterable or sortable by metadata keys. For queryable structured attributes on a Session, define a custom field on the Session entity type.

Return type:

dict[str, Any]

property min_timestamp_ns: int | None#

Lower aggregate bound across this Session’s recording data contributions, in Unix-epoch nanoseconds.

None when the Session has no contributions.

Return type:

Optional[int]

property modified: datetime.datetime | None#

UTC timestamp when this Session was last modified.

Return type:

Optional[datetime.datetime]

property modified_by: str#

Identifier of the user or service which last modified this Session.

Return type:

str

property name: str | None#

Optional short name of this Session.

Return type:

Optional[str]

property org_id: str#

Identifier of the organization that owns this Session.

Return type:

str

publish_metrics(metrics, device_id=NotSet)#

Record metric values for this Session in a single network call.

Convenience wrapper around publish() that supplies this Session’s session_id and org_id. Each (metric, session) pair is upserted: republishing under the same name replaces the previous value.

If a metric definition does not already exist for a given name it is created automatically.

Parameters:
  • metrics (list[roboto.domain.metrics.record.MetricEntry]) – Metric names and numeric values to record.

  • device_id (Union[roboto.sentinels.NotSetType, Optional[str]]) – Device to associate with each published value, or None to opt out. When omitted, the server infers a device from this Session’s attached devices: the call succeeds only if exactly one device is associated and is rejected when zero or more than one are.

Returns:

A BulkPublishMetricsResult with succeeded and failed lists.

Raises:

RobotoInvalidRequestExceptiondevice_id was omitted and this Session has zero or more than one attached devices.

Return type:

roboto.domain.metrics.metric.BulkPublishMetricsResult

Examples

Let the server infer the device from this Session’s single attached device:

>>> from roboto.domain.metrics import MetricEntry
>>> result = session.publish_metrics(
...     [
...         MetricEntry(name="cpu.usage_max", value=87.2),
...         MetricEntry(name="memory.peak_mb", value=2048.0),
...     ]
... )
>>> len(result.succeeded)
2

Attach to an explicit device, overriding inference:

>>> session.publish_metrics(
...     [MetricEntry(name="cpu.usage_max", value=87.2)],
...     device_id="dv_robot01",
... )
put_metadata(metadata)#

Add or update metadata fields on this Session.

Parameters:

metadata (dict[str, Any]) – Field-to-value map. Existing fields are overwritten; fields not in this map are left unchanged.

Returns:

This Session, refreshed from the server response.

Return type:

Session

Examples

>>> session.put_metadata({"weather": "clear", "pilot": "alice"})
put_tags(tags)#

Add tags to this Session.

Tags already present on the Session are not duplicated.

Parameters:

tags (roboto.updates.StrSequence) – Tags to add.

Returns:

This Session, refreshed from the server response.

Return type:

Session

Examples

>>> session.put_tags(["pre-flight-check", "training"])
property record: roboto.domain.sessions.record.SessionRecord#

Underlying data record for this Session.

Return type:

roboto.domain.sessions.record.SessionRecord

remove_file(file)#

Remove a single file’s contributions from this Session.

Thin convenience over remove_files() for the common one-file case.

Parameters:

file (Union[roboto.domain.files.File, str]) – A File or a file id.

Returns:

This Session, refreshed from the server response.

Return type:

Session

remove_files(file_ids)#

Remove the given files’ contributions from this Session.

The service recomputes the Session’s aggregate bounds across the remaining contributions, and the Session instance reflects the new min_timestamp_ns / max_timestamp_ns on return.

Parameters:

file_ids (collections.abc.Sequence[str]) – File IDs whose contributions should be removed.

Returns:

This Session, refreshed from the server response.

Return type:

Session

remove_metadata(metadata)#

Remove metadata keys from this Session.

Parameters:

metadata (roboto.updates.StrSequence) – Metadata keys to remove. Dot notation addresses nested keys ("weather.condition").

Returns:

This Session, refreshed from the server response.

Return type:

Session

Examples

>>> session.remove_metadata(["pilot", "weather.condition"])
remove_tags(tags)#

Remove the given tags from this Session.

Parameters:

tags (roboto.updates.StrSequence) – Tags to remove. Tags not present on the Session are silently ignored.

Returns:

This Session, refreshed from the server response.

Return type:

Session

Examples

>>> session.remove_tags(["training"])
property session_id: str#

Globally unique identifier assigned to this Session on creation.

Return type:

str

set_custom_field(name, value)#

Set a single custom-field value on this session.

name must be the name of a Ready custom field for this session’s org and the Session entity type; value must satisfy the field’s declared type.

Parameters:
  • name (str)

  • value (Any)

Return type:

Session

set_custom_fields(fields)#

Set or overwrite multiple custom-field values on this session.

Each key must name a Ready custom field for this session’s org and the Session entity type; each value must satisfy the field’s declared type.

Parameters:

fields (dict[str, Any])

Return type:

Session

property tags: list[str]#

User-supplied tags on this Session.

Return type:

list[str]

update(description=NotSet, metadata_changeset=NotSet, name=NotSet, custom_fields_changeset=None)#

Update mutable Session fields.

Fields left at the NotSet default are preserved; for nullable string fields (description, name), pass None to clear.

Parameters:
Return type:

Session

:param See put_tags(): :param remove_tags(): :param put_metadata(): :param : :param and remove_metadata() for shorthand helpers.: :param name: New name for the Session. Set to None to clear the name.

Leave at the default to leave the name unchanged.

Parameters:
Returns:

This Session, refreshed from the server response.

Return type:

Session

Examples

>>> session.update(description="formation flight #4", name="flight-2026-04-23-001")
class roboto.domain.sessions.SessionFile(/, **data)#

Bases: pydantic.BaseModel

A file’s contribution to a session, optionally narrowed to a time range.

range_min_timestamp_ns and range_max_timestamp_ns are absolute nanoseconds since the Unix epoch, the same coordinate system in which the session’s aggregate bounds are expressed. Leaving both bounds as None contributes the whole file’s time window. Both bounds must be set together or both omitted; half-open windows are rejected.

Parameters:

data (Any)

file_id: str#
model_config#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

range_max_timestamp_ns: int | None = None#
range_min_timestamp_ns: int | None = None#
class roboto.domain.sessions.SessionFileRecord(/, **data)#

Bases: pydantic.BaseModel

Wire-format row for one file’s contribution to a Session, optionally clipped to a sub-range of the file’s recorded time.

The clipping range is expressed in Unix-epoch nanoseconds, the same coordinate system as the parent Session’s aggregate bounds.

Range contract:

  1. range_min_timestamp_ns and range_max_timestamp_ns are set together or both None; half-open windows are not a supported product concept and are rejected on write.

  2. When both are None, the file contributes its whole recorded time window.

  3. When both are set, range_min_timestamp_ns <= range_max_timestamp_ns, and consumers iterating session data must clamp the file’s data to that [range_min_timestamp_ns, range_max_timestamp_ns] window.

Parameters:

data (Any)

created: datetime.datetime | None = None#

When this file was added to the session.

created_by: str#

User ID or service account that added this file to the session.

fs_node_id: str#

Identifier of the contributing file.

model_config#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

modified: datetime.datetime | None = None#

When this file’s contribution was last modified.

modified_by: str#

User ID or service account that last modified this file’s contribution.

range_max_timestamp_ns: int | None = None#

Upper bound (inclusive) of the file’s contribution, in Unix-epoch nanoseconds. None means the contribution extends to the end of the file’s recorded time window; paired with range_min_timestamp_ns.

range_min_timestamp_ns: int | None = None#

Lower bound (inclusive) of the file’s contribution, in Unix-epoch nanoseconds. None means the contribution starts at the beginning of the file’s recorded time window; paired with range_max_timestamp_ns.

session_id: str#

Identifier of the session this file contributes to.

class roboto.domain.sessions.SessionRecord(/, **data)#

Bases: pydantic.BaseModel

Wire-format row for a session: an operational time window of a Device such as a drone flight, a vehicle drive, or a robot run.

A Session unifies the recordings and auxiliary data produced during its window; it may span many files or cover only a slice of one.

min_timestamp_ns and max_timestamp_ns are service-maintained aggregate bounds over the Session’s contributions, recomputed by the service in the same transaction as any composition write (add/remove files), so the row never disagrees with its contents.

Parameters:

data (Any)

created: datetime.datetime | None = None#

When the session was created.

created_by: str#

User ID or service account that created the session.

custom_fields: dict[str, Any] = None#

Values for the custom fields defined on Sessions in this org.

Every Ready custom field defined for (org_id, Session) appears as a key; values that have not been set surface as None rather than being absent. Empty when no custom fields are defined for the org.

description: str | None = None#

Optional description of the Session.

max_timestamp_ns: int | None = None#

Upper bound of the session’s aggregate timestamps, in Unix-epoch nanoseconds. None until the session has at least one file contribution.

metadata: dict[str, Any] = None#

User-supplied metadata.

Sessions cannot be filtered or sorted by metadata keys; for queryable structured attributes, define a custom field on the Session entity type.

min_timestamp_ns: int | None = None#

Lower bound of the session’s aggregate timestamps, in Unix-epoch nanoseconds. None until the session has at least one file contribution.

model_config#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

modified: datetime.datetime | None = None#

When the Session was last modified.

modified_by: str#

User ID or service account that last modified the Session.

name: str | None = None#

A short, human-readable name for the Session. If provided, must be 120 characters or less.

org_id: str#

Organization that owns the Session.

session_id: str#

Stable, unique identifier for the Session.

tags: list[str] = None#

User-supplied tags.

Sessions can be filtered by tag membership (e.g., tags CONTAINS '<tag>') but are not sortable by tag.

class roboto.domain.sessions.SessionUpdate(/, **data)#

Bases: pydantic.BaseModel

Partial update for a session.

Fields left at NotSet are not modified.

Parameters:

data (Any)

custom_fields_changeset: roboto.updates.CustomFieldChangeset | None = None#

Changes to apply to Ready custom-field values on this session.

Each referenced field name must be a Ready custom field for this session’s org and the Session entity type; each set_fields value must satisfy the field’s declared type. Names that are undefined or not Ready are rejected with a structured error. Field names not mentioned by the changeset are left unchanged.

description: str | roboto.sentinels.NotSetType | None#

New description for the Session. Set to None to clear the description.

metadata_changeset: roboto.updates.MetadataChangeset | roboto.sentinels.NotSetType#

Tag and metadata changes to merge into the Session (add, update, or remove fields and tags).

model_config#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: Annotated[str, pydantic.StringConstraints(max_length=120)] | roboto.sentinels.NotSetType | None#

New name for the Session (max 120 characters). Set to None to clear the name.