Skip to content

Experimental

rerun.experimental

Experimental features for Rerun.

These features are not yet stable and may change in future releases without going through the normal deprecation cycle.

The stable chunk API and readers (RrdReader, McapReader, …) now live in rerun.chunk. The old rerun.experimental names still work for one release but warn on use.

StoreId module-attribute

StoreId = str

Identifies one recording open in the viewer, as {kind}:{application_id}:{recording_id}.

kind is Recording or Blueprint. The application id is the application that logged it, or the dataset id for a catalog-backed recording; the recording id is the recording itself, or its segment id. Pass the whole string back to the methods that take a recording.

Both ids may contain a colon, so the application id's are escaped as \: (and a backslash as \\): the kind runs to the first colon, the application id to the next unescaped one, and the recording id is the rest.

DatasetInfo dataclass

Structural metadata for a single HDF5 dataset.

ATTRIBUTE DESCRIPTION
path

Full path of the dataset within the file (e.g. /observations/qpos).

TYPE: str

shape

Dataset dimensions (e.g. (272, 128, 128, 3)).

TYPE: tuple[int, ...]

dtype

Element type name (e.g. "uint8", "float64").

TYPE: str

Hdf5Reader

Read chunks from an HDF5 file.

The reader is a lightweight handle over the file: inspect the raw structure with groups(), datasets(), and attributes(), and produce chunks with stream(...). All loading options live on stream(), so one reader can drive several differently-configured streams over the same file.

Each HDF5 group is mapped to a Rerun entity, and the group's leaf datasets become the columns of that entity. The file root maps to the entity /, and nested groups map to nested entity paths (/observations/images becomes the entity /observations/images). See stream() for how datasets, timelines, and attributes are turned into chunks.

PARAMETER DESCRIPTION
path

Path to the .hdf5 / .h5 file.

TYPE: str | Path

RAISES DESCRIPTION
FileNotFoundError

If path does not exist.

path property
path: Path

The file path of the HDF5 file.

attributes
def attributes(
    path: str = "/",
) -> dict[
    str, int | float | str | bytes | list[int | float | str]
]

Read the HDF5 attributes attached to an object as a typed Python dict.

This is a convenience accessor for the same attributes that stream() emits under __hdf5_properties (see the class docstring). It reads the raw file directly.

PARAMETER DESCRIPTION
path

Path to the object whose attributes are read. Defaults to the root group /, i.e. the file-level (global) attributes. May reference any group or dataset.

TYPE: str DEFAULT: '/'

RETURNS DESCRIPTION
A mapping from attribute name to value. Scalar attributes are returned
as Python scalars (`int`, `float`, `str`, `bytes`); array-valued
attributes are returned as lists. Empty if the object has no attributes.
RAISES DESCRIPTION
KeyError

If path does not exist in the file.

datasets
def datasets(path: str = '/') -> list[DatasetInfo]

List the datasets under path, recursively, with their shape and dtype.

Metadata only — no dataset values are read; reflects the raw file.

PARAMETER DESCRIPTION
path

Group under which to list. Defaults to the root group /, i.e. the whole file.

TYPE: str DEFAULT: '/'

groups
def groups(path: str = '/') -> list[str]

List the group paths under path, recursively.

Metadata only — no dataset values are read; reflects the raw file.

PARAMETER DESCRIPTION
path

Group under which to list. Defaults to the root group /, i.e. the whole file.

TYPE: str DEFAULT: '/'

stream
def stream(
    *,
    root_group: str | None = None,
    entity_path_prefix: str | None = None,
    index_column: IndexColumn | None = None,
    ignore_datasets: list[str] | None = None,
    use_structs: bool = True,
) -> LazyChunkStream

Return a lazy stream over all chunks in the HDF5 file.

Each call is independent: the same reader can be streamed several times with different configurations.

Datasets are loaded according to their dimensionality:

  • A 0-D (scalar) dataset is loaded as static data — a single value with no timeline.
  • A 1-D dataset [N] becomes a column of N scalar rows.
  • A 2-D dataset [N, K] becomes a column of N rows, each a fixed-size list of K elements.
  • A 3-D-or-higher dataset [N, d1, …, dk] becomes a column of N rows, each a single blob of the matching type (an Arrow List<PRIMITIVE_TYPE>) holding the row's raw row-major values. The original per-row shape is not recorded in the emitted data; recover it via datasets.

For 1-D and higher-dimensional datasets the leading dimension is always the row axis. Element types are mapped to their natural Arrow equivalents (signed and unsigned integers, floats, and strings); no semantic interpretation is applied.

HDF5 attributes are emitted as static chunks under a dedicated __hdf5_properties entity, mirroring the source layout: root attributes land on __hdf5_properties, and attributes on object /a/b on __hdf5_properties/a/b. Each attribute becomes one static component named after it, typed with the same mapping as datasets. This keeps the general __properties entity free for user-defined property layers.

Row alignment

Every loaded, non-ignored, non-scalar dataset is aligned positionally to the file-wide timeline and must therefore share the same number of rows (scalar datasets are static and exempt):

  • With an index_column, that shared count is the index dataset's length.
  • Without one, the datasets must all agree on a single row count, which becomes the length of the generated row_index timeline.

A dataset that violates this raises unless it is listed in ignore_datasets; nothing is dropped automatically to satisfy alignment.

PARAMETER DESCRIPTION
root_group

The group to treat as the file root (default: the whole file). Only its subtree is loaded and aligned, its own attributes act as the root attributes, and every other path — index_column, ignore_datasets, and the emitted entity paths — is interpreted relative to it.

Attributes on groups above root_group are not emitted; read them with attributes instead.

TYPE: str | None DEFAULT: None

entity_path_prefix

Optional prefix prepended to every entity path (for example "/world").

TYPE: str | None DEFAULT: None

index_column

Dataset to use as the file-wide timeline index, built with IndexColumn, e.g. IndexColumn.timestamp("/time", input_unit="s") or IndexColumn.sequence("/frame_id"). Interpreted relative to root_group.

The referenced dataset must be 1-dimensional. When omitted, a single row_index sequence timeline (0, 1, …) is generated for the whole file and every loaded dataset must align to it (see Row alignment).

TYPE: IndexColumn | None DEFAULT: None

ignore_datasets

Datasets or groups to exclude entirely. Each entry is a dataset path or a group path (which excludes the whole subtree), interpreted relative to root_group. Ignored datasets are neither loaded nor considered for row alignment.

TYPE: list[str] | None DEFAULT: None

use_structs

When True (default), all columns of an entity are packed into a single Arrow Struct component, with one field per dataset named after that dataset. When False, each dataset becomes a separate component on the same entity. A group holding a single dataset always emits that dataset as a bare component, never as a one-field struct.

TYPE: bool DEFAULT: True

RAISES DESCRIPTION
ValueError

If a loaded, non-ignored, non-scalar dataset cannot be aligned to the applicable row count (the index length, or the file's shared row count when no index_column is set). Resolve by adding the offending dataset to ignore_datasets or by choosing a compatible index_column.

Also raised when root_group does not exist or is not a group, and when the file exists but cannot be parsed as HDF5: the layout is validated eagerly here, so such failures surface at stream() rather than lazily mid-iteration.

LeRobotReader

Read chunks from a LeRobot dataset, one episode at a time.

The reader is a lightweight handle over the dataset directory: constructing it validates that the path is a v2 or v3 LeRobot dataset and loads its metadata. Enumerate episodes with episodes() and produce chunks with stream(episode, ...).

PARAMETER DESCRIPTION
path

Path to the LeRobot dataset directory (the one containing meta/ and data/).

TYPE: str | Path

RAISES DESCRIPTION
FileNotFoundError

If path does not exist.

ValueError

If path is not a v2 or v3 LeRobot dataset.

path property
path: Path

The dataset directory this reader was constructed with.

version property
version: Literal['v2', 'v3']

The detected dataset format version: "v2" or "v3".

episodes
def episodes() -> list[int]

The episode indices available in this dataset, ascending.

stream
def stream(
    episode: int,
    *,
    entity_path_prefix: str | None = None,
    timeline: str | None = None,
    video_mode: Literal["native", "skip"] = "native",
) -> LazyChunkStream

Return a lazy stream over one episode's chunks.

Most video streams directly; a stream that must be re-encoded — H.264 with B-frames, or an episode window starting mid-GOP — needs ffmpeg on the system PATH.

Each call is independent: the same reader can stream several episodes (or the same episode several times) with different configurations. The typical loop is:

reader = LeRobotReader("path/to/dataset")
for episode in reader.episodes():
    reader.stream(episode).write_rrd(
        f"episode_{episode}.rrd",
        application_id="my_dataset",
        recording_id=f"episode_{episode}",
    )
PARAMETER DESCRIPTION
episode

The episode index to stream; must be one of episodes().

TYPE: int

entity_path_prefix

Prepended to every feature's entity path.

TYPE: str | None DEFAULT: None

timeline

Overrides the derived timeline name (frame_index or timestamp).

TYPE: str | None DEFAULT: None

video_mode

"native" emits video as-is (v2: whole-file asset, v3: stream samples cut to the episode's time window); "skip" omits video features.

TYPE: Literal['native', 'skip'] DEFAULT: 'native'

RAISES DESCRIPTION
ValueError

If episode is not a valid episode index or the configuration is invalid. Data problems surface while the stream is drained, not here.

LoadingSource dataclass

A data source the viewer is still loading from.

name instance-attribute
name: str

What is being loaded: a file path, a URL's display name, or a segment id.

status instance-attribute
status: str

The same thing the viewer's own loading screen says, e.g. Loading /path/to/dataset….

LogEntry dataclass

One message the viewer logged.

level instance-attribute
level: str

INFO, WARN, or ERROR.

sequence instance-attribute
sequence: int

Increases by one per message. Pass the last one back to fetch only what is new.

target instance-attribute
target: str

The module that logged it, starting with the crate name.

MetricsCollector

Accumulator yielded by query_metrics on __enter__.

Use last_query() / queries to read snapshots accumulated so far; both are non-destructive. On context-manager exit any remaining snapshots are drained into this collector and the scope is unbound from the ContextVar, so the collector is still readable after the scope ends.

queries property
queries: list[QueryMetrics]

Non-destructive snapshot of all queries captured so far.

clear
def clear() -> None

Drop all captured snapshots from both the Rust buffer and this collector.

last_query
def last_query() -> QueryMetrics | None

Most recently captured query, or None if none yet.

Mp4Reader

Read chunks from an MP4 file.

entity_path property
entity_path: str

The entity path under which chunks are emitted.

path property
path: Path

The file path of the MP4 file.

__init__
def __init__(
    path: str | Path,
    *,
    mode: Literal["stream"] = "stream",
    chunk_by_gop: bool = True,
    timeline_name: str = "video",
    timeline_type: TemporalTimelineType = "duration_ns",
    transcode: Mp4TranscodeOptions | None = None,
    entity_path: str | None = None,
) -> None
def __init__(
    path: str | Path,
    *,
    mode: Literal["asset"],
    timeline_name: str = "video",
    timeline_type: TemporalTimelineType = "duration_ns",
    entity_path: str | None = None,
) -> None
def __init__(
    path: str | Path,
    *,
    mode: Literal["asset", "stream"] = "stream",
    chunk_by_gop: bool = True,
    timeline_name: str = "video",
    timeline_type: TemporalTimelineType = "duration_ns",
    transcode: Mp4TranscodeOptions | None = None,
    entity_path: str | None = None,
) -> None

Construct a new MP4 reader.

PARAMETER DESCRIPTION
path

Path to the .mp4 file to read.

TYPE: str | Path

mode

How to convert the mp4 into chunks.

  • "stream" (default): emit a static VideoStream(codec=…) chunk, then per-GOP (or per-sample) VideoSample chunks, then one VideoStream:is_keyframe chunk with a True row per keyframe. The mp4 must use a codec representable as VideoCodec. A source containing B-frames — or any source for which a transform is requested via transcode — is transcoded with FFmpeg into an equivalent B-frame-free stream before emission, which requires an ffmpeg executable.
  • "asset": emit an AssetVideo blob chunk plus a VideoFrameReference index chunk, matching the behavior of rerun video.mp4.

TYPE: Literal['asset', 'stream'] DEFAULT: 'stream'

chunk_by_gop

Only meaningful when mode="stream". When True (default), each emitted Rerun chunk contains a keyframe plus all dependent samples up to (but not including) the next keyframe. When False, each sample becomes its own one-row Rerun chunk.

Passing chunk_by_gop=False together with mode="asset" raises ValueError.

TYPE: bool DEFAULT: True

timeline_name

Name of the timeline used for stream-mode samples and for the VideoFrameReference index chunk in asset mode. Defaults to "video".

TYPE: str DEFAULT: 'video'

timeline_type

How to interpret the timeline values. "duration" and "timestamp" are accepted as aliases of "duration_ns" and "timestamp_ns".

The emitted values are the mp4 PTS (nanoseconds since the start of the video) only the declared Arrow type changes:

  • "duration_ns" (default): the values are typed as a duration, the natural mp4 PTS interpretation.
  • "timestamp_ns": the same PTS values, typed as nanoseconds since the Unix epoch. The reader does not shift them, so until you retag them — via a downstream .map(...) on the chunk stream with caller-supplied wall-clock times (e.g. from a trajectory file) — they render as timestamps near 1970.

TYPE: TemporalTimelineType DEFAULT: 'duration_ns'

transcode

Only meaningful when mode="stream". An Mp4TranscodeOptions describing an optional re-encode.

TYPE: Mp4TranscodeOptions | None DEFAULT: None

entity_path

Entity path under which chunks are emitted. When None (default), the entity path is derived from the absolute file path (e.g. foo/video.mp4 run from /data becomes /data/foo/video.mp4). The path is resolved to absolute up front, so the result is independent of any later change to the working directory.

TYPE: str | None DEFAULT: None

stream
def stream() -> LazyChunkStream

Return a lazy stream over all chunks in the MP4 file.

Mp4TranscodeOptions dataclass

How to transcode an mp4.

ffmpeg_override class-attribute instance-attribute
ffmpeg_override: str | Path | None = None

Override the ffmpeg executable used to transcode. When None (default), ffmpeg is looked up on PATH. Ignored when no transcode happens.

gop_size class-attribute instance-attribute
gop_size: int | None = None

Force a keyframe every gop_size frames in the transcoded output. Requesting it triggers a re-encode. None (default) keeps the encoder's default GOP.

output_codec class-attribute instance-attribute
output_codec: VideoCodec | None = None

Re-encode to this VideoCodec instead of keeping the source codec; the emitted VideoStream codec follows it. None (default) keeps the source codec.

try_gpu class-attribute instance-attribute
try_gpu: bool = False

Try to use a hardware (GPU) encoder if the local FFmpeg provides one for the output codec, otherwise fall back to software (best-effort). GPU encoding is drawn from the NVENC and VideoToolbox families only, so it realistically applies to H264/H265 and, on newer NVIDIA hardware, AV1. VP8/VP9 always fall back to software — their only GPU encoders are Intel QSV/VAAPI, which are not yet used. Has no effect unless a transcode is already happening.

ParquetReader

Read chunks from a Parquet file.

The reader turns raw parquet columns into grouped, time-indexed Chunks of struct/scalar components. To map those struct fields into Rerun archetypes (translation, rotation, scalars, …), apply lenses to the resulting .stream() — see DeriveLens:

Example
from rerun.chunk import DeriveLens, IndexColumn
from rerun.experimental import ParquetReader

store = (
    ParquetReader(path)
    .stream(index_columns=[IndexColumn.sequence("frame_index")])
    .lenses(
        [
            DeriveLens("data", output_entity="/pose")
            .to_translation("pos_x", "pos_y", "pos_z")
            .to_quaternion("quat_x", "quat_y", "quat_z", "quat_w")
        ],
        content="/transform",
    )
    .collect()
)
PARAMETER DESCRIPTION
path

Path to the .parquet file.

TYPE: str | Path

RAISES DESCRIPTION
FileNotFoundError

If path does not exist.

path property
path: Path

The file path of the Parquet file.

stream
def stream(
    *,
    entity_path_prefix: str | None = None,
    column_grouping: str = "prefix",
    delimiter: str = "_",
    prefixes: list[str] | None = None,
    use_structs: bool = True,
    static_columns: list[str] | None = None,
    index_columns: list[IndexColumn] | None = None,
) -> LazyChunkStream

Return a lazy stream over all chunks in the Parquet file.

PARAMETER DESCRIPTION
entity_path_prefix

Optional prefix for all entity paths (e.g. "/world").

TYPE: str | None DEFAULT: None

column_grouping

How to group columns into chunks. "prefix" splits column names on delimiter and groups by the first segment. "individual" gives each column its own chunk. "explicit_prefixes" groups columns by the explicit prefix strings in prefixes.

TYPE: str DEFAULT: 'prefix'

delimiter

Character used to split column names when column_grouping="prefix".

TYPE: str DEFAULT: '_'

prefixes

Explicit prefix strings for grouping columns. Required when column_grouping="explicit_prefixes". Columns starting with a prefix are grouped together; the prefix is stripped from the component name. Prefixes are tried longest-first to avoid ambiguity.

TYPE: list[str] | None DEFAULT: None

use_structs

When True (default) and column_grouping="prefix" or "explicit_prefixes", columns sharing a prefix are packed into a single Arrow Struct component. When False, each column becomes a separate component (the pre-struct layout). Ignored when column_grouping="individual".

TYPE: bool DEFAULT: True

static_columns

Column names whose values are constant across all rows. These are emitted once as timeless/static data. An error is raised if a listed column contains varying values.

TYPE: list[str] | None DEFAULT: None

index_columns

Columns to use as timeline indices, each built with IndexColumn, e.g. IndexColumn.timestamp("ts", input_unit="ms") or IndexColumn.sequence("frame_index").

When omitted, a synthetic row_index sequence timeline is generated automatically (one entry per row).

TYPE: list[IndexColumn] | None DEFAULT: None

QueryMetrics dataclass

One query's metrics, captured at the moment its last per-partition stream finished.

Mirrors the Rust-side re_datafusion::QuerySnapshot. The same numbers are produced via three transports: this dataclass (Python), DataFusion's EXPLAIN ANALYZE, and the PostHog analytics OTLP span. Field naming differs across the three:

  • Timing fields here are datetime.timedelta (total_duration, time_to_first_chunk, …). EXPLAIN ANALYZE uses DataFusion Time metrics, which print their own units. The OTLP analytics attributes keep an explicit _us suffix and carry integer microseconds (total_duration_us, time_to_first_chunk_us, …) because OTLP attribute values are scalar (i64 / f64 / bool / string) and can't carry a duration natively.
  • query_chunks_per_segment_mean is a float and does not appear in EXPLAIN ANALYZE, since DataFusion Count metrics are integer-only. The corresponding _min / _max integer fields are surfaced in all three transports.

fetch_direct_max_attempt is the true maximum attempt number across all partitions.

fetch_bytes property
fetch_bytes: int

Total bytes fetched across both gRPC and direct transports.

fetch_requests property
fetch_requests: int

Total fetch requests across both gRPC and direct transports.

waste_ratio property
waste_ratio: float | None

Bytes fetched per byte delivered — the over-fetch signal.

A large value means the query pulled far more data than it handed back (e.g. "fetched 4 GB, delivered 200 rows"). None when nothing was delivered, so the ratio is undefined.

Recording dataclass

One recording open in the viewer.

current_time instance-attribute
current_time: int | None

Where the cursor sits on that timeline, if set.

current_timeline instance-attribute
current_timeline: str | None

The timeline the cursor sits on, if any.

Timeline dataclass

One timeline of a recording, with the range of times it holds.

end instance-attribute
end: int | None

Last time on the timeline, or None if it holds no data yet.

name instance-attribute
name: str

Name of the timeline, e.g. log_time.

start instance-attribute
start: int | None

First time on the timeline, or None if it holds no data yet.

time_type instance-attribute
time_type: str

sequence, duration, or timestamp.

View dataclass

One view of the viewer's current blueprint.

reports instance-attribute
reports: list[ViewReport]

What failed to visualize. Empty when the view is healthy.

ViewReport dataclass

A warning or an error a view reported the last time it was shown.

severity instance-attribute
severity: str

warning or error.

ViewerClient

A connection to an instance of a Rerun viewer.

Use the connect classmethod to attach to an already-running viewer, or spawn to start a fresh one (e.g. in headless mode for CI screenshots).

Spawned-viewer teardown:

  • Explicit close always terminates the spawned viewer.
  • For an attached viewer (detach_process=False), exiting a with block or garbage-collecting the client also terminates the viewer.
  • A detached viewer keeps running through with exits and garbage collection. Only an explicit close() shuts it down.

Warning

This API is experimental and may change or be removed in future versions.

url property
url: str

The rerun+http://…/proxy URL of the viewer this client is connected to.

__init__
def __init__(
    url: str = _DEFAULT_URL,
    *,
    _pid: int | None = None,
    _kill_on_exit: bool = False,
) -> None

Low-level constructor.

Prefer ViewerClient.connect or ViewerClient.spawn.

PARAMETER DESCRIPTION
url

The URL to connect to. The scheme must be one of rerun://, rerun+http://, or rerun+https://, and the pathname must be /proxy — the same form accepted by rerun.connect_grpc. Defaults to rerun+http://127.0.0.1:9876/proxy.

TYPE: str DEFAULT: _DEFAULT_URL

_pid

Internal — set by spawn() to the pid of the launched viewer so that close() can terminate it.

TYPE: int | None DEFAULT: None

_kill_on_exit

Internal — set by spawn() to indicate that implicit teardown (__exit__, __del__) should call close(). See the class docstring for the full teardown rules.

TYPE: bool DEFAULT: False

close
def close() -> None

Close the client, terminating the spawned viewer.

Emits a UserWarning and is a no-op if there is no spawned viewer to terminate (either the client never spawned one, or it has already been closed). Safe to call multiple times — only the first call has an effect.

close_recordings
def close_recordings(
    target: str | Sequence[StoreId] = "current",
) -> list[StoreId]

Close recordings in the viewer, and return what was closed.

This only removes them from the viewer. Files on disk are untouched, and registered recordings stay in the catalog and can be reopened, but unsaved blueprint edits are lost.

Warning

This API is experimental and may change or be removed in future versions.

PARAMETER DESCRIPTION
target

"current" to close the active recording, "all" to close every open one, or the StoreId of a recording to close, or several of them. viewer_state() reports the open recordings and their ids.

TYPE: str | Sequence[StoreId] DEFAULT: 'current'

connect classmethod
def connect(url: str = _DEFAULT_URL) -> ViewerClient

Connect to an already-running viewer.

PARAMETER DESCRIPTION
url

The URL to connect to. The scheme must be one of rerun://, rerun+http://, or rerun+https://, and the pathname must be /proxy — the same form accepted by rerun.connect_grpc. Defaults to rerun+http://127.0.0.1:9876/proxy.

TYPE: str DEFAULT: _DEFAULT_URL

open_url
def open_url(url: str) -> None

Open a URL in the viewer.

Warning

This API is experimental and may change or be removed in future versions.

PARAMETER DESCRIPTION
url

A recording or blueprint file, a rerun:// dataset URI, a redap server or catalog URL, or an intra-recording link.

TYPE: str

save_screenshot
def save_screenshot(
    file_path: str, view_id: str | UUID | None = None
) -> None

Save a screenshot to a file.

Warning

This API is experimental and may change or be removed in future versions.

PARAMETER DESCRIPTION
file_path

The path where the screenshot will be saved.

Important

This path is relative to the viewer's filesystem, not the client's. If your viewer runs on a different machine, the screenshot will be saved there.

TYPE: str

view_id

Optional view ID to screenshot. If None, screenshots the entire viewer.

TYPE: str | UUID | None DEFAULT: None

send_table
def send_table(
    name: str,
    table: RecordBatch | list[RecordBatch] | DataFrame,
) -> None

Send a table to the viewer.

A table is represented as a dataframe defined by an Arrow record batch.

PARAMETER DESCRIPTION
name

The table name.

Note

The table name serves as an identifier. If you send a table with the same name twice, the second table will replace the first one.

TYPE: str

table

The Arrow RecordBatch containing the table data to send.

TYPE: RecordBatch | list[RecordBatch] | DataFrame

set_time
def set_time(
    timeline: str | None = None,
    *,
    sequence: int,
    play: bool = False,
    recording: StoreId | None = None,
) -> None
def set_time(
    timeline: str | None = None,
    *,
    duration: int | float | timedelta | timedelta64,
    play: bool = False,
    recording: StoreId | None = None,
) -> None
def set_time(
    timeline: str | None = None,
    *,
    timestamp: int | float | datetime | datetime64,
    play: bool = False,
    recording: StoreId | None = None,
) -> None
def set_time(
    timeline: str | None = None,
    *,
    sequence: int | None = None,
    duration: int
    | float
    | timedelta
    | timedelta64
    | None = None,
    timestamp: int
    | float
    | datetime
    | datetime64
    | None = None,
    play: bool = False,
    recording: StoreId | None = None,
) -> None

Set the viewer's time cursor.

PARAMETER DESCRIPTION
timeline

The timeline to seek on. If omitted, the viewer uses its active timeline.

TYPE: str | None DEFAULT: None

sequence

A sequence index.

TYPE: int | None DEFAULT: None

duration

A duration in seconds, or a duration value with nanosecond precision.

TYPE: int | float | timedelta | timedelta64 | None DEFAULT: None

timestamp

Seconds since Unix epoch, or a timestamp value with nanosecond precision.

TYPE: int | float | datetime | datetime64 | None DEFAULT: None

play

Start playing from the new position. The viewer pauses by default.

TYPE: bool DEFAULT: False

recording

The recording to seek, as reported by viewer_state(). If omitted, the viewer uses its active recording.

TYPE: StoreId | None DEFAULT: None

spawn classmethod
def spawn(
    *,
    headless: bool = False,
    port: int = 9876,
    memory_limit: str = "75%",
    server_memory_limit: str = "1GiB",
    hide_welcome_screen: bool = False,
    detach_process: bool | None = None,
    executable_name: str = "rerun",
    executable_path: str | None = None,
) -> ViewerClient

Spawn a fresh viewer process and connect to it.

PARAMETER DESCRIPTION
headless

Run the spawned viewer in headless mode (no OS window). The viewer still listens for gRPC connections, so the SDK can keep logging data and request screenshots via save_screenshot.

A working graphics stack must be present — either a real GPU/driver or a software rasterizer like Mesa's lavapipe. In a bare CI container with no Vulkan adapter, the viewer panics on startup with "No graphics adapter was found".

TYPE: bool DEFAULT: False

port

The port to listen on.

TYPE: int DEFAULT: 9876

memory_limit

An upper limit on how much memory the Rerun Viewer should use. When this limit is reached, Rerun will drop the oldest data. Example: 16GB or 50% (of system total).

TYPE: str DEFAULT: '75%'

server_memory_limit

An upper limit on how much memory the gRPC server running in the same process as the Rerun Viewer should use. When this limit is reached, Rerun will drop the oldest data. Example: 16GB or 50% (of system total).

Defaults to 1GiB.

TYPE: str DEFAULT: '1GiB'

hide_welcome_screen

Hide the normal Rerun welcome screen.

TYPE: bool DEFAULT: False

detach_process

Detach the spawned viewer from this Python process.

A detached viewer survives unexpected parent termination (e.g. crashes or terminal hang-up), with block exits, and garbage collection — to take it down you must call close explicitly. An attached viewer is killed by all of those.

Defaults to True for a regular GUI viewer and False when headless=True, since a leftover invisible viewer is rarely what you want.

TYPE: bool | None DEFAULT: None

executable_name

Specifies the name of the Rerun executable. You can omit the .exe suffix on Windows.

Defaults to rerun.

TYPE: str DEFAULT: 'rerun'

executable_path

Enforce a specific executable to use instead of searching through PATH for executable_name.

Unspecified by default.

TYPE: str | None DEFAULT: None

viewer_logs
def viewer_logs(
    after_sequence: int | None = None,
) -> list[LogEntry]

Return the viewer's recent log messages, oldest first.

The viewer keeps a bounded buffer, so old entries drop out.

Warning

This API is experimental and may change or be removed in future versions.

PARAMETER DESCRIPTION
after_sequence

Only return entries newer than this sequence number. Pass the last one you saw to fetch only what is new. None returns everything buffered.

TYPE: int | None DEFAULT: None

viewer_state
def viewer_state() -> ViewerState

Report what the viewer is currently showing.

Call this to learn which recording and timeline to drive, and which time values are valid, before moving the time cursor. A view's reports say what failed to visualize.

Warning

This API is experimental and may change or be removed in future versions.

ViewerState dataclass

A snapshot of what the viewer is currently showing.

catalog_url instance-attribute
catalog_url: str | None

Origin of the catalog server the viewer hosts.

Hand this to CatalogClient to read the data behind the open recordings; this API drives the viewer and deliberately does not serve data itself.

loading instance-attribute
loading: list[LoadingSource]

What the viewer is still loading, empty once everything has arrived.

open_url returns as soon as the load starts, and a recording appears in recordings as soon as its first message lands, so a recording with no timelines yet means "still arriving" rather than "empty". Poll until this is empty before concluding that a load finished.

url instance-attribute
url: str

The current page, as a sharable URL. Empty for a page that has none.

viewer_version instance-attribute
viewer_version: str | None

Version of the viewer answering, e.g. 0.38.0-alpha.1.

Which Rerun this is decides which API and which docs apply, so read it here rather than shelling out to rerun --version and hoping it found the same binary.

query_metrics

def query_metrics() -> Iterator[MetricsCollector]

Capture DataFusion query metrics for every query that runs inside the with block.

Yields a MetricsCollector; read .last_query() or .queries mid-scope or after the scope exits.

The scope is bound to the current contextvars.Context: every re_datafusion query built from dataset.reader(…) while this scope is open contributes a QueryMetrics record. Nested query_metrics() scopes each see queries built inside them. Queries built in another thread or asyncio task that did not inherit this context (e.g. a raw threading.Thread rather than one started via contextvars.copy_context()) are not captured.

The collectors are bound to a query at reader() time, so a df built inside the with block whose .collect() runs after __exit__ still flows to the collector; a df built outside but executed inside does not.

Examples:

import rerun as rr
from rerun.experimental import query_metrics

client = rr.catalog.CatalogClient("rerun://…")
dataset = client.get_dataset(name="…")

with query_metrics() as m:
    df = dataset.reader(index="time_1").limit(100)
    df.collect()
    print(m.last_query())