chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: External importer example
|
||||
python: https://github.com/rerun-io/rerun/tree/latest/examples/python/external_importer/rerun-importer-python-file.py
|
||||
rust: https://github.com/rerun-io/rerun/tree/latest/examples/rust/external_importer/src/main.rs
|
||||
cpp: https://github.com/rerun-io/rerun/tree/latest/examples/cpp/external_importer/main.cpp
|
||||
thumbnail: https://static.rerun.io/external_data_loader_py/6c5609f5dd7d1de373c81babe19221b72d616da3/480w.png
|
||||
thumbnail_dimensions: [480, 302]
|
||||
---
|
||||
|
||||
<picture>
|
||||
<img src="https://static.rerun.io/external_data_loader_py/6c5609f5dd7d1de373c81babe19221b72d616da3/full.png" alt="">
|
||||
<source media="(max-width: 480px)" srcset="https://static.rerun.io/external_data_loader_py/6c5609f5dd7d1de373c81babe19221b72d616da3/480w.png">
|
||||
<source media="(max-width: 768px)" srcset="https://static.rerun.io/external_data_loader_py/6c5609f5dd7d1de373c81babe19221b72d616da3/768w.png">
|
||||
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/external_data_loader_py/6c5609f5dd7d1de373c81babe19221b72d616da3/1024w.png">
|
||||
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/external_data_loader_py/6c5609f5dd7d1de373c81babe19221b72d616da3/1200w.png">
|
||||
</picture>
|
||||
|
||||
This is an example executable importer plugin for the Rerun Viewer.
|
||||
|
||||
It will log Python source code files as markdown documents.
|
||||
|
||||
On Linux & Mac you can simply copy it in your $PATH as `rerun-importer-python-file.py`, then open a Python source file with Rerun (`rerun file.py`).
|
||||
Make sure the file has a shebang (`#!/usr/bin/env python3`) and is executable (`chmod +x`).
|
||||
|
||||
On Windows you have to install the script as an executable first and then put the executable under %PATH%.
|
||||
One way to do this is to use `pyinstaller`: `pyinstaller .\examples\python\external_importer\rerun-importer-python-file.py -n rerun-importer-python-file --onefile`
|
||||
|
||||
Consider using the [`send_columns`](https://ref.rerun.io/docs/python/stable/common/columnar_api/#rerun.send_columns) API for importers that ingest time series data from a file.
|
||||
This can be much more efficient that the stateful `log` API as it allows bundling
|
||||
component data over time into a single call consuming a continuous block of memory.
|
||||
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Example of an executable importer plugin for the Rerun Viewer."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
import rerun as rr # pip install rerun-sdk
|
||||
|
||||
# The Rerun Viewer will always pass these two pieces of information:
|
||||
# 1. The path to be loaded, as a positional arg.
|
||||
# 2. A shared recording ID, via the `--recording-id` flag.
|
||||
#
|
||||
# It is up to you whether you make use of that shared recording ID or not.
|
||||
# If you use it, the data will end up in the same recording as all other plugins interested in
|
||||
# that file, otherwise you can just create a dedicated recording for it. Or both.
|
||||
#
|
||||
# Check out `re_importer::ImporterSettings` documentation for an exhaustive listing of
|
||||
# the available CLI parameters.
|
||||
parser = argparse.ArgumentParser(
|
||||
description="""
|
||||
This is an example executable importer plugin for the Rerun Viewer.
|
||||
Any executable on your `$PATH` with a name that starts with `rerun-importer-` will be
|
||||
treated as an external importer.
|
||||
|
||||
This particular one will log Python source code files as markdown documents, and return a
|
||||
special exit code to indicate that it doesn't support anything else.
|
||||
|
||||
To try it out, copy it in your $PATH as `rerun-importer-python-file`, then open a Python source
|
||||
file with Rerun (`rerun file.py`).
|
||||
""",
|
||||
)
|
||||
parser.add_argument("filepath", type=str)
|
||||
parser.add_argument("--application-id", type=str, help="optional recommended ID for the application")
|
||||
parser.add_argument("--recording-id", type=str, help="optional recommended ID for the recording")
|
||||
parser.add_argument("--entity-path-prefix", type=str, help="optional prefix for all entity paths")
|
||||
parser.add_argument("--static", action="store_true", default=False, help="optionally mark data to be logged as static")
|
||||
parser.add_argument(
|
||||
"--time_sequence",
|
||||
type=str,
|
||||
action="append",
|
||||
help="optional sequences to log at (e.g. `--time_sequence sim_frame=42`)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--time_duration_nanos",
|
||||
type=str,
|
||||
action="append",
|
||||
help="optional duration(s) (in nanoseconds) to log at (e.g. `--time_duration_nanos sim_time=123`) (repeatable)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--time_timestamp_nanos",
|
||||
type=str,
|
||||
action="append",
|
||||
help="optional timestamp(s) (in nanoseconds since epochj) to log at (e.g. `--time_timestamp_nanos sim_time=1709203426123456789`) (repeatable)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
is_file = os.path.isfile(args.filepath)
|
||||
is_python_file = os.path.splitext(args.filepath)[1].lower() == ".py"
|
||||
|
||||
# Inform the Rerun Viewer that we do not support that kind of file.
|
||||
if not is_file or not is_python_file:
|
||||
sys.exit(rr.EXTERNAL_IMPORTER_INCOMPATIBLE_EXIT_CODE)
|
||||
|
||||
app_id = "rerun_example_external_importer"
|
||||
if args.application_id is not None:
|
||||
app_id = args.application_id
|
||||
rr.init(app_id, recording_id=args.recording_id)
|
||||
# The most important part of this: log to standard output so the Rerun Viewer can ingest it!
|
||||
rr.stdout()
|
||||
|
||||
set_time_from_args()
|
||||
|
||||
if args.entity_path_prefix:
|
||||
entity_path = f"{args.entity_path_prefix}/{args.filepath}"
|
||||
else:
|
||||
entity_path = args.filepath
|
||||
|
||||
with open(args.filepath, encoding="utf8") as file:
|
||||
body = file.read()
|
||||
text = f"""## Some Python code\n```python\n{body}\n```\n"""
|
||||
rr.log(entity_path, rr.TextDocument(text, media_type=rr.MediaType.MARKDOWN), static=args.static)
|
||||
|
||||
|
||||
def set_time_from_args() -> None:
|
||||
if not args.static and args.time is not None:
|
||||
for time_str in args.time_sequence:
|
||||
parts = time_str.split("=")
|
||||
if len(parts) != 2:
|
||||
continue
|
||||
timeline_name, sequence = parts
|
||||
rr.set_time(timeline_name, sequence=int(sequence))
|
||||
|
||||
for time_str in args.time_duration_nanos:
|
||||
parts = time_str.split("=")
|
||||
if len(parts) != 2:
|
||||
continue
|
||||
timeline_name, nanos = parts
|
||||
rr.set_time(timeline_name, duration=1e-9 * int(nanos))
|
||||
|
||||
for time_str in args.time_timestamp_nanos:
|
||||
parts = time_str.split("=")
|
||||
if len(parts) != 2:
|
||||
continue
|
||||
timeline_name, nanos = parts
|
||||
rr.set_time(timeline_name, timestamp=1e-9 * int(nanos))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user