Skip to content

Add experimental send_recording python api #9148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Apr 4, 2025
Merged

Add experimental send_recording python api #9148

merged 20 commits into from
Apr 4, 2025

Conversation

oxkitsune
Copy link
Member

@oxkitsune oxkitsune commented Feb 26, 2025

Related

What

Adds api to send a recording loaded from RRD to a new recording stream, cloning the data in the process

@oxkitsune oxkitsune added 🐍 Python API Python logging API include in changelog 🪵 Log & send APIs Affects the user-facing API for all languages feat-dataframe-api Everything related to the dataframe API labels Feb 26, 2025
@oxkitsune oxkitsune changed the title Add send_recording python api Add send_recording python api Feb 26, 2025
Copy link

github-actions bot commented Feb 26, 2025

Web viewer built successfully. If applicable, you should also test it:

  • I have tested the web viewer
Result Commit Link Manifest
13562f5 https://rerun.io/viewer/pr/9148 +nightly +main

Note: This comment is updated whenever you push a commit.

@Wumpf Wumpf self-requested a review March 3, 2025 11:23
Copy link
Member

@Wumpf Wumpf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent on whether we want to solve this differently in the future, the APIs are very valuable to have I believe.
There's some todos left though for documenting this out etc.
Also, I don't think we should close the linked issue until we implement this in all SDKs (right now the PR auto closes #2044)

@@ -472,6 +473,31 @@ def send_blueprint(
)


def send_recording(recording: Recording, stream: RecordingStream | None = None) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this Python function at all? Can this logic be done in the Rust implementation instead? @jleibs has recently implemented a bunch of APIs for the Python SDK that don't have a single line of Python in them (AFAIK?), and I would very much like to keep that trend...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked into it, but it doesn’t seem super straightforward in this case. There are a few things that make it a bit tricky, e.g. RecordingStream wrapping PyRecordingStream

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This can only be done correctly once everything else is done correctly. By "correctly", I mean according to this issue:

@@ -488,6 +490,31 @@ def send_blueprint(
)


def send_recording(embedded_recording: Recording, recording: RecordingStream | None = None) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This absolutely needs to also be a RecordingStream method.

Also, I don't know if this has been discussed, but our naming is all over the place, as this signature makes it explicit.

As they say, in for a penny, in for a pound. My actionable (if drastic) suggestion is either:

  • either rename all recording: RecordingStream arguments of the stateful API to stream: RecordingStream,
  • or preferably remove those arguments altogether! (if you want to act on an existing recording stream, just use one of its method)

I'm strongly advocating for the latter option.

cc @nikolausWest @jleibs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is relevant: #9187

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm late to the party on this one, but we should really think about the flow between the Recording and a RecordingStream object a bit more.

For example: the MemoryRecording would ideally go away and just be a Recording. Would be so nice to be able to log to the in-memory recording and then query it without needing to re-load it from an rrd.

Copy link
Member

@Wumpf Wumpf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.rrd isn't checked in as a LFS file, should be though

otherwise (and remaining comment) looks all good to me now. I'd be in favor of landing this prior to additional Python refactors, but I'll let you and @abey79 figure that out ;-)

Comment on lines +20 to +29
if let Some(info) = store.info().cloned() {
let new_recording = rerun::RecordingStreamBuilder::new(info.application_id.clone())
.recording_id(store_id.to_string())
.spawn()?;

new_recording.record_msg(LogMsg::SetStoreInfo(SetStoreInfo {
row_id: Tuid::new(),
info,
}));

Copy link
Member

@Wumpf Wumpf Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[not actionable] oof this is pretty wild, going way more into Rerun's guts as a would like. Ah well, why not. At least this gives us a great reference point testing the python layer! 👍

@@ -89,6 +89,7 @@ class Section:
"disconnect",
"save",
"send_blueprint",
"send_recording",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't really an "initialize" function, right? All the others here are about setup, whereas send_recording is technically more like a logging function 🤔

@oxkitsune
Copy link
Member Author

So I think this PR solves a problem we have, but I think the solution can be improved.

  • Currently all data is copied over, but it might make more sense to only take a small portion instead.
  • Would perhaps be nice to instead create a Dataframe from a RecordingStream kind of like Create Dataframe directly from RecordingStream #9302
  • Rust example makes use of too much of Rerun's internals for my liking

@Wumpf Wumpf marked this pull request as draft March 19, 2025 08:51
@oxkitsune oxkitsune force-pushed the gijs/to-stream branch 2 times, most recently from 17fbeac to eee8364 Compare March 31, 2025 07:18
@Wumpf Wumpf self-requested a review April 2, 2025 13:39
Copy link
Member

@Wumpf Wumpf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

examples/assets/example.rrd is already checked in as an lfs file by now, this overrides it with an regular binary

@oxkitsune oxkitsune marked this pull request as ready for review April 3, 2025 08:22
@oxkitsune oxkitsune requested a review from abey79 April 4, 2025 06:49
Copy link
Member

@abey79 abey79 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

@oxkitsune oxkitsune changed the title Add send_recording python api Add experimental send_recording python api Apr 4, 2025
@oxkitsune oxkitsune merged commit 68ecaee into main Apr 4, 2025
39 of 40 checks passed
@oxkitsune oxkitsune deleted the gijs/to-stream branch April 4, 2025 07:27
@emilk emilk mentioned this pull request Apr 11, 2025
16 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat-dataframe-api Everything related to the dataframe API include in changelog 🪵 Log & send APIs Affects the user-facing API for all languages 🐍 Python API Python logging API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RecordingStream should be able to forward an existing RRD file
5 participants