chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
<!--[metadata]
|
||||
title = "Table blueprints"
|
||||
tags = ["Tables", "Blueprints", "Server"]
|
||||
include_in_manifest = false
|
||||
-->
|
||||
|
||||
## Table blueprints
|
||||
|
||||
Creates tables whose rows link to recording segment URIs.
|
||||
The viewer can load those recordings on demand and render row previews with a registered `.rbl` table blueprint.
|
||||
|
||||
The example also adds a boolean `marker_flag` column and names it in the table blueprint.
|
||||
That column is the per-row flag state: the Viewer renders it as a clickable flag on each grid card, updates the visible table immediately when toggled, and upserts the changed boolean value back to the server using the `rerun:is_table_index` column as the row key.
|
||||
The column is still regular table data, so its saved values are what you get back when you query the table later.
|
||||
|
||||
Blueprints can also be registered on a dataset's **own segment table** instead of on a separate demo table, using `DatasetEntry.register_blueprint(..., segment_table=True)`. <!-- NOLINT -->
|
||||
Use `--target` to choose (see [Run the code](#run-the-code)):
|
||||
|
||||
- `tables`: create the demo tables, each with its own table blueprint.
|
||||
- `dataset`: register a blueprint on the dataset's segment table (no tables created).
|
||||
- `both`: do both.
|
||||
|
||||
The segment-table blueprint leaves `segment_preview_column` and `flag_column` unset — the viewer auto-picks the column to preview, and segment tables have no demo flag column.
|
||||
Flagging does **not** yet work on dataset segment tables: segment tables have no write operations yet, so flag changes cannot be persisted back to the server. Flagging therefore only works on the demo tables created with `--target tables`.
|
||||
|
||||
<!-- TODO(#12746): this is still experimental -->
|
||||
Table cards and blueprints are experimental.
|
||||
Enable `Settings > Experimental > Table cards and blueprints` in the viewer.
|
||||
|
||||
## Dataset-specific setup
|
||||
|
||||
This sample contains a small `Dataset-specific customization` section near the top of `table_blueprints.py`.
|
||||
Please edit these functions before using it with your own data — the defaults are geared towards RRDs from the DROID dataset and assume that segment-table schema, timeline, entity paths, coordinate frame, and card-title column:
|
||||
|
||||
- `extract_dataset_property_columns` — which segment-table columns get copied into the demo tables.
|
||||
- `setup_preview_views` — all views (plot, 3D, 2D) shared by the table and segment-table blueprints. Any view type can be used for previews!
|
||||
- `make_dataset_blueprints` — the table blueprints (preview/flag/card-title columns, timeline).
|
||||
- `make_segment_table_blueprint` — the blueprint registered on the dataset's own segment table (views, timeline).
|
||||
|
||||
## Run the code
|
||||
|
||||
The sample has two run modes.
|
||||
|
||||
### Local server mode
|
||||
|
||||
Without `--url`, the script starts a temporary local Rerun server, serves a directory of `.rrd` files
|
||||
as a dataset named `local`, writes the `.rbl` blueprint files, and (depending on `--target`) creates
|
||||
the demo tables and registers their blueprints with
|
||||
`TableEntry.register_blueprint(...)` and/or registers a blueprint on the dataset's segment table with `DatasetEntry.register_blueprint(..., segment_table=True)`. <!-- NOLINT -->
|
||||
|
||||
Run without arguments to serve the checked-in sample files from `tests/assets/rrd/sample_5`:
|
||||
|
||||
```bash
|
||||
pip install -e examples/python/table_blueprints
|
||||
table_blueprints
|
||||
```
|
||||
|
||||
Or pass any dataset directory containing `.rrd` files:
|
||||
|
||||
```bash
|
||||
table_blueprints /path/to/dataset
|
||||
```
|
||||
|
||||
Choose what the blueprints apply to with `--target` (`tables` by default):
|
||||
|
||||
```bash
|
||||
table_blueprints --target dataset # only the dataset's segment table
|
||||
table_blueprints --target both # demo tables and the segment table
|
||||
```
|
||||
|
||||
Use `--port` if you want the local server to listen on a specific port:
|
||||
|
||||
```bash
|
||||
table_blueprints /path/to/dataset --port 9876
|
||||
```
|
||||
|
||||
Via pixi/uv:
|
||||
|
||||
```bash
|
||||
pixi run py-build && pixi run uv run examples/python/table_blueprints/table_blueprints.py /path/to/dataset
|
||||
```
|
||||
|
||||
### Remote client mode
|
||||
|
||||
With `--url`, the script connects as a client to an existing Rerun server or catalog and looks up the dataset by name.
|
||||
The generated `.rbl` files must be visible to that server before registration.
|
||||
Use `--write-blueprints-only` to write them locally (both the table blueprints and `segment_table.rbl`), upload them yourself, then rerun with `--blueprint-uri-base` pointing at the uploaded directory.
|
||||
`--target` works the same way in remote mode.
|
||||
|
||||
```bash
|
||||
table_blueprints --write-blueprints-only --blueprint-dir /tmp/table-blueprints
|
||||
# Upload /tmp/table-blueprints/*.rbl to a server-visible location, for example s3://my-bucket/table-blueprints/
|
||||
table_blueprints <dataset-name> --url rerun+https://… --blueprint-dir /tmp/table-blueprints --blueprint-uri-base s3://my-bucket/table-blueprints/
|
||||
# …or register on the dataset's segment table instead:
|
||||
table_blueprints <dataset-name> --url rerun+https://… --target dataset --blueprint-dir /tmp/table-blueprints --blueprint-uri-base s3://my-bucket/table-blueprints/
|
||||
```
|
||||
@@ -0,0 +1,12 @@
|
||||
[project]
|
||||
name = "table_blueprints"
|
||||
version = "0.1.0"
|
||||
readme = "README.md"
|
||||
dependencies = ["pyarrow", "rerun-sdk"]
|
||||
|
||||
[project.scripts]
|
||||
table_blueprints = "table_blueprints:main"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
@@ -0,0 +1,453 @@
|
||||
"""
|
||||
Demo for table blueprints & segment previews.
|
||||
|
||||
Table blueprints allow configuring table layouts and use segment previews.
|
||||
|
||||
**TODO(#12745, #12746): This feature is experimental.** Enable it in the
|
||||
viewer under Settings > Experimental > Table cards and blueprints.
|
||||
|
||||
Each row can reference a recording via a URI column. The viewer loads those recordings
|
||||
on demand and renders them through the registered blueprint's view definition.
|
||||
|
||||
The demo also includes a boolean `marker_flag` column and points the registered table
|
||||
blueprint at it. The Viewer uses that column as the per-row flag state: toggling a
|
||||
card's flag updates the visible table immediately and upserts the new boolean value
|
||||
back to the server using the `rerun:is_table_index` column as the row key.
|
||||
|
||||
For testing you can use this droid rrd dataset:
|
||||
https://huggingface.co/datasets/rerun/droid_sample/tree/main
|
||||
|
||||
Usage:
|
||||
table_blueprints
|
||||
table_blueprints /path/to/dataset
|
||||
table_blueprints --target dataset
|
||||
table_blueprints --target both
|
||||
table_blueprints --write-blueprints-only --blueprint-dir /tmp/table-blueprints
|
||||
table_blueprints <dataset-name> --url rerun+https://… --blueprint-uri-base s3://bucket/table-blueprints/
|
||||
|
||||
`--target` selects what the blueprints are applied to:
|
||||
- `tables` (default): create the demo tables, each with its own table blueprint.
|
||||
- `dataset`: register a blueprint on the dataset's own segment table (no tables created).
|
||||
- `both`: do both.
|
||||
|
||||
Without `--url`, this starts a temporary local Rerun server for the given directory of
|
||||
`.rrd` files. With `--url`, this connects as a client to an existing Rerun server or
|
||||
catalog and expects `dataset` to be the remote dataset name.
|
||||
Remote registration requires `--blueprint-uri-base` pointing at a server-visible
|
||||
location containing the `.rbl` files written by this script.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from typing import Any, NamedTuple
|
||||
|
||||
import pyarrow as pa
|
||||
|
||||
import rerun as rr
|
||||
import rerun.blueprint as rrb
|
||||
from rerun import bindings
|
||||
from rerun.recording_stream import RecordingStream
|
||||
from rerun.server import Server
|
||||
|
||||
|
||||
def save_table_blueprint(
|
||||
path: Path,
|
||||
*views: rrb.View,
|
||||
segment_preview_column: str | None = None,
|
||||
flag_column: str | None = None,
|
||||
grid_view_card_title: str | None = None,
|
||||
timeline: str | None = None,
|
||||
) -> None:
|
||||
"""
|
||||
Write a table blueprint with one or more views into a `.rbl` file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
path:
|
||||
File path to write the serialized `.rbl` blueprint to.
|
||||
*views:
|
||||
One or more view definitions to embed (e.g. `Spatial3DView`, `TimeSeriesView`).
|
||||
segment_preview_column:
|
||||
If set, names the column whose values are `rerun://` recording URIs.
|
||||
The viewer will load those recordings and render inline previews.
|
||||
flag_column:
|
||||
If set, names the boolean column used for flag/annotation toggles.
|
||||
The column must exist in the table schema.
|
||||
grid_view_card_title:
|
||||
If set, names the column to use as card titles in grid view.
|
||||
If unset, the first visible string column is used.
|
||||
timeline:
|
||||
If set, configures the time panel to display this timeline.
|
||||
|
||||
"""
|
||||
blueprint = rrb.Blueprint(*views)
|
||||
|
||||
with RecordingStream._from_native(
|
||||
bindings.new_blueprint(
|
||||
application_id="embedded",
|
||||
make_default=False,
|
||||
make_thread_default=False,
|
||||
default_enabled=True,
|
||||
),
|
||||
) as blueprint_stream:
|
||||
blueprint_stream.save(str(path))
|
||||
blueprint_stream.set_time("blueprint", sequence=0)
|
||||
blueprint._log_to_stream(blueprint_stream)
|
||||
|
||||
table_blueprint_kwargs = {}
|
||||
if segment_preview_column is not None:
|
||||
table_blueprint_kwargs["segment_preview_column"] = segment_preview_column
|
||||
if flag_column is not None:
|
||||
table_blueprint_kwargs["flag_column"] = flag_column
|
||||
if grid_view_card_title is not None:
|
||||
table_blueprint_kwargs["grid_view_card_title"] = grid_view_card_title
|
||||
if table_blueprint_kwargs:
|
||||
blueprint_stream.log(
|
||||
"/table",
|
||||
rrb.experimental.TableBlueprint(**table_blueprint_kwargs),
|
||||
)
|
||||
|
||||
if timeline is not None:
|
||||
rrb.TimePanel(timeline=timeline)._log_to_stream(blueprint_stream)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Dataset-specific customization
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
DEFAULT_LOCAL_DATASET = Path(__file__).resolve().parents[3] / "tests/assets/rrd/sample_5"
|
||||
MARKER_FLAG_COLUMN = "marker_flag"
|
||||
SEGMENT_TABLE_BLUEPRINT_NAME = "segment_table"
|
||||
PropertyColumn = tuple[str, pa.Field, list[Any]]
|
||||
|
||||
# Please edit the functions in this section to match your own dataset.
|
||||
# The defaults below are geared towards RRDs from the DROID dataset and its schema,
|
||||
# timelines, entity paths, and coordinate frames; they are intended as a starting point only.
|
||||
|
||||
|
||||
def extract_dataset_property_columns(seg_arrow: pa.Table, num_segments: int) -> list[PropertyColumn]:
|
||||
"""
|
||||
Pick which segment-table columns should be copied into the demo tables.
|
||||
|
||||
PLEASE EDIT THIS for your dataset. The default implementation looks for
|
||||
columns named `property:episode:*` and strips that prefix.
|
||||
"""
|
||||
episode_prefix = "property:episode:"
|
||||
props: list[PropertyColumn] = []
|
||||
for field in seg_arrow.schema:
|
||||
if field.name.startswith(episode_prefix):
|
||||
original_name = field.name
|
||||
short_name = original_name[len(episode_prefix) :]
|
||||
values = seg_arrow.column(original_name).to_pylist()[:num_segments]
|
||||
props.append((short_name, pa.field(short_name, field.type, field.nullable), values))
|
||||
|
||||
return props
|
||||
|
||||
|
||||
class PreviewViews(NamedTuple):
|
||||
"""The views shared by the table and segment-table blueprints."""
|
||||
|
||||
plot: rrb.TimeSeriesView
|
||||
spatial_3d: rrb.Spatial3DView
|
||||
spatial_2d: rrb.Spatial2DView
|
||||
|
||||
|
||||
def setup_preview_views() -> PreviewViews:
|
||||
"""
|
||||
Build all views used by the demo blueprints.
|
||||
|
||||
PLEASE EDIT THIS for your dataset: view origins, contents, target frame, and excluded paths.
|
||||
"""
|
||||
return PreviewViews(
|
||||
plot=rrb.TimeSeriesView(
|
||||
origin="/observation/joint_positions",
|
||||
plot_legend=rrb.PlotLegend(visible=False),
|
||||
),
|
||||
spatial_3d=rrb.Spatial3DView(
|
||||
contents=[
|
||||
"+ /**",
|
||||
"- /camera/**",
|
||||
"- /**/collision_0/**",
|
||||
"- /thumbnail/**",
|
||||
],
|
||||
spatial_information=rrb.SpatialInformation(
|
||||
target_frame="panda_link0",
|
||||
),
|
||||
background=rrb.Background(
|
||||
color=[0.1, 0.1, 0.1, 1.0],
|
||||
),
|
||||
),
|
||||
spatial_2d=rrb.Spatial2DView(
|
||||
contents=["+ /camera/wrist/**"],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def make_dataset_blueprints(blueprint_dir: Path) -> dict[str, Path]:
|
||||
"""
|
||||
Write the table blueprints used by this demo to `blueprint_dir` and return their paths by name.
|
||||
|
||||
These target the demo *tables* created by this script, whose schema has `recording_uri`,
|
||||
`marker_flag`, and `uuid` columns. For the dataset's own segment table, see
|
||||
`make_segment_table_blueprint`.
|
||||
|
||||
PLEASE EDIT THIS for your dataset. In particular, update:
|
||||
- `grid_view_card_title` to a string column that exists in your copied properties.
|
||||
- `timeline` to the timeline used by your recordings.
|
||||
"""
|
||||
common_bp_kwargs = {
|
||||
"segment_preview_column": "recording_uri",
|
||||
"flag_column": MARKER_FLAG_COLUMN,
|
||||
"grid_view_card_title": "uuid",
|
||||
"timeline": "real_time",
|
||||
}
|
||||
|
||||
views = setup_preview_views()
|
||||
|
||||
blueprint_dir.mkdir(parents=True, exist_ok=True)
|
||||
paths = {
|
||||
name: blueprint_dir / f"{name}.rbl" for name in ("previews_plot", "previews_3d_only", "previews_3d_and_2d")
|
||||
}
|
||||
|
||||
save_table_blueprint(paths["previews_plot"], views.plot, **common_bp_kwargs)
|
||||
save_table_blueprint(paths["previews_3d_only"], views.spatial_3d, **common_bp_kwargs)
|
||||
save_table_blueprint(paths["previews_3d_and_2d"], views.spatial_3d, views.spatial_2d, **common_bp_kwargs)
|
||||
|
||||
return paths
|
||||
|
||||
|
||||
def make_segment_table_blueprint(blueprint_dir: Path) -> Path:
|
||||
"""
|
||||
Write the blueprint used for the dataset's own segment table and return its path.
|
||||
|
||||
Unlike the table blueprints, this targets the dataset's native segment table, so:
|
||||
- `segment_preview_column` is left unset, letting the viewer auto-pick the column to preview.
|
||||
- `flag_column` is left unset (segment tables have no demo flag column).
|
||||
|
||||
PLEASE EDIT THIS for your dataset. By default it uses the combined 3D & 2D views and the
|
||||
`real_time` timeline; adjust the views (via `setup_preview_views`) and timeline to match your
|
||||
recordings.
|
||||
"""
|
||||
blueprint_dir.mkdir(parents=True, exist_ok=True)
|
||||
path = blueprint_dir / f"{SEGMENT_TABLE_BLUEPRINT_NAME}.rbl"
|
||||
|
||||
views = setup_preview_views()
|
||||
save_table_blueprint(path, views.spatial_3d, views.spatial_2d, timeline="real_time")
|
||||
|
||||
return path
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Generic demo plumbing: start a local server, query segments, and create tables.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def query_segment_data(
|
||||
dataset: rr.catalog.DatasetEntry,
|
||||
) -> tuple[list[str], list[str], list[PropertyColumn]]:
|
||||
"""
|
||||
Query segment table and return (segment_ids, segment_uris, property_columns).
|
||||
|
||||
Returns all entries from the segment table.
|
||||
"""
|
||||
seg_df = dataset.segment_table()
|
||||
seg_arrow = pa.Table.from_batches(seg_df.collect())
|
||||
|
||||
segment_ids = seg_arrow.column("rerun_segment_id").to_pylist()
|
||||
n = len(segment_ids)
|
||||
segment_uris = [dataset.segment_url(sid) for sid in segment_ids]
|
||||
props = extract_dataset_property_columns(seg_arrow, n)
|
||||
|
||||
return segment_ids, segment_uris, props
|
||||
|
||||
|
||||
def create_table(
|
||||
client: rr.catalog.CatalogClient,
|
||||
*,
|
||||
table_name: str,
|
||||
segment_uris: list[str],
|
||||
property_columns: list[PropertyColumn],
|
||||
) -> rr.catalog.TableEntry:
|
||||
"""Create a table with the given segment data."""
|
||||
n = len(segment_uris)
|
||||
|
||||
fields: list[pa.Field] = [
|
||||
pa.field("id", pa.int64(), metadata={rr.SORBET_IS_TABLE_INDEX: "true"}),
|
||||
pa.field("recording_uri", pa.utf8()),
|
||||
]
|
||||
data: dict[str, list[Any]] = {
|
||||
"id": list(range(n)),
|
||||
"recording_uri": segment_uris,
|
||||
}
|
||||
|
||||
for short_name, field, values in property_columns:
|
||||
fields.append(field)
|
||||
data[short_name] = values
|
||||
|
||||
fields.append(pa.field(MARKER_FLAG_COLUMN, pa.bool_()))
|
||||
data[MARKER_FLAG_COLUMN] = [False] * n
|
||||
|
||||
schema = pa.schema(fields)
|
||||
table = client.create_table(table_name, schema)
|
||||
table.append(**data)
|
||||
return table
|
||||
|
||||
|
||||
def blueprint_uri(name: str, local_path: Path, blueprint_uri_base: str | None) -> str:
|
||||
"""Return the URI to register for a blueprint."""
|
||||
if blueprint_uri_base is None:
|
||||
return local_path.absolute().as_uri()
|
||||
return blueprint_uri_base.rstrip("/") + f"/{name}.rbl"
|
||||
|
||||
|
||||
def create_demo_tables(
|
||||
client: rr.catalog.CatalogClient,
|
||||
dataset: rr.catalog.DatasetEntry,
|
||||
dataset_name: str,
|
||||
*,
|
||||
blueprint_dir: Path,
|
||||
blueprint_uri_base: str | None,
|
||||
) -> None:
|
||||
"""Create one demo table per table blueprint, populated from the dataset's segment properties."""
|
||||
_, segment_uris, props = query_segment_data(dataset)
|
||||
print(f"Using {len(segment_uris)} segments from dataset '{dataset_name}'")
|
||||
|
||||
blueprint_paths = make_dataset_blueprints(blueprint_dir)
|
||||
|
||||
existing_table_names = set(client.table_names())
|
||||
for name in blueprint_paths:
|
||||
if name in existing_table_names:
|
||||
client.get_table(name).delete()
|
||||
print(f" {name}: deleted existing table")
|
||||
table = create_table(
|
||||
client,
|
||||
table_name=name,
|
||||
segment_uris=segment_uris,
|
||||
property_columns=props,
|
||||
)
|
||||
uri = blueprint_uri(name, blueprint_paths[name], blueprint_uri_base)
|
||||
table.register_blueprint(uri)
|
||||
print(f" {name}: registered table blueprint {uri}")
|
||||
|
||||
|
||||
def apply_segment_table_blueprint(
|
||||
dataset: rr.catalog.DatasetEntry,
|
||||
*,
|
||||
blueprint_dir: Path,
|
||||
blueprint_uri_base: str | None,
|
||||
) -> None:
|
||||
"""Register the segment-table blueprint on the dataset's own segment table."""
|
||||
path = make_segment_table_blueprint(blueprint_dir)
|
||||
uri = blueprint_uri(SEGMENT_TABLE_BLUEPRINT_NAME, path, blueprint_uri_base)
|
||||
dataset.register_blueprint(uri, segment_table=True)
|
||||
print(f" segment table: registered blueprint {uri}")
|
||||
|
||||
|
||||
def run_with_client(
|
||||
client: rr.catalog.CatalogClient,
|
||||
dataset_name: str,
|
||||
*,
|
||||
target: str,
|
||||
blueprint_dir: Path,
|
||||
blueprint_uri_base: str | None,
|
||||
) -> None:
|
||||
"""Create demo tables and/or register a blueprint on the dataset's segment table, per `target`."""
|
||||
dataset = client.get_dataset(dataset_name)
|
||||
|
||||
if target in ("tables", "both"):
|
||||
create_demo_tables(
|
||||
client,
|
||||
dataset,
|
||||
dataset_name,
|
||||
blueprint_dir=blueprint_dir,
|
||||
blueprint_uri_base=blueprint_uri_base,
|
||||
)
|
||||
|
||||
if target in ("dataset", "both"):
|
||||
apply_segment_table_blueprint(
|
||||
dataset,
|
||||
blueprint_dir=blueprint_dir,
|
||||
blueprint_uri_base=blueprint_uri_base,
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Create table-blueprint demo tables.")
|
||||
parser.add_argument(
|
||||
"dataset",
|
||||
nargs="?",
|
||||
help=(f"Local dataset directory to serve. Defaults to {DEFAULT_LOCAL_DATASET}."),
|
||||
)
|
||||
|
||||
connection_group = parser.add_mutually_exclusive_group()
|
||||
connection_group.add_argument("--port", type=int, default=None, help="Port for local server mode.")
|
||||
connection_group.add_argument("--url", help="Remote server/catalog URL for client mode.")
|
||||
parser.add_argument(
|
||||
"--blueprint-dir",
|
||||
type=Path,
|
||||
default=Path.cwd(),
|
||||
help="Directory where generated .rbl table blueprints are written.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--blueprint-uri-base",
|
||||
help=(
|
||||
"Server-visible URI prefix used when registering generated .rbl files. "
|
||||
"Required with --url unless --write-blueprints-only is used."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--target",
|
||||
choices=("tables", "dataset", "both"),
|
||||
default="both",
|
||||
help=(
|
||||
"What to apply blueprints to:\n"
|
||||
"* 'tables' creates the demo tables\n"
|
||||
"* 'dataset' registers a blueprint on the dataset's own segment table\n"
|
||||
"* 'both' (default) does both."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--write-blueprints-only",
|
||||
action="store_true",
|
||||
help="Only write generated .rbl files to --blueprint-dir, then exit.",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.write_blueprints_only:
|
||||
make_dataset_blueprints(args.blueprint_dir)
|
||||
make_segment_table_blueprint(args.blueprint_dir)
|
||||
return
|
||||
|
||||
if args.url is not None:
|
||||
if args.dataset is None:
|
||||
parser.error("Provide a remote dataset name when using --url")
|
||||
if args.blueprint_uri_base is None:
|
||||
parser.error("Provide --blueprint-uri-base with --url after uploading the generated .rbl files")
|
||||
client = rr.catalog.CatalogClient(args.url)
|
||||
run_with_client(
|
||||
client,
|
||||
dataset_name=args.dataset,
|
||||
target=args.target,
|
||||
blueprint_dir=args.blueprint_dir,
|
||||
blueprint_uri_base=args.blueprint_uri_base,
|
||||
)
|
||||
else:
|
||||
local_dataset = args.dataset or str(DEFAULT_LOCAL_DATASET)
|
||||
with Server(port=args.port, datasets={"local": local_dataset}) as srv:
|
||||
print(srv.url())
|
||||
client = srv.client()
|
||||
run_with_client(
|
||||
client,
|
||||
dataset_name="local",
|
||||
target=args.target,
|
||||
blueprint_dir=args.blueprint_dir,
|
||||
blueprint_uri_base=args.blueprint_uri_base,
|
||||
)
|
||||
input("Press Enter to stop the server…")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user