Skip to content

Server

SimViewServer is the FastAPI app that serves a scene's model/states (or per-blob columnar endpoints) to the browser, and handles WebSocket live-push. Most users won't instantiate this directly — see SimulationScene.show(), LiveViewer, or the simview CLI instead.

simview.server.SimViewServer

SimViewServer(
    sim_path: str
    | Path
    | Sequence[str | Path]
    | None = None,
    data: dict | None = None,
    live: bool = False,
    frame_buffer_size: int = _LIVE_FRAME_BUFFER_MAXLEN,
    batch_selections: Sequence[str | Sequence[int] | None]
    | None = None,
)

Serve one scene's model/states (and their binary blobs) to the viewer.

Built from a scene file (sim_path), an already-loaded data dict, or both (merged inputs keep their paths for the batch-names sidecar). With live=True, frames are pushed over /ws/states instead of served from /states -- see simview.live.LiveViewer.

broadcast_episodes async

broadcast_episodes(episodes: list[dict]) -> None

Push updated episode boundaries to every connected /ws/states client.

A separate message kind from the frame broadcasts -- episodes describe the model, not a frame, and arrive far more rarely. See the onmessage handler in SimView.js.

broadcast_frame async

broadcast_frame(frame: dict, frame_index: int) -> None

Send one newly-pushed frame to every connected /ws/states client.

frame_index is the frame's absolute index (see frames_pushed). Must run on self.loop (the server thread's event loop) -- LiveViewer schedules this via asyncio.run_coroutine_threadsafe from its sender thread rather than calling it directly.

push_frame

push_frame(frame: dict) -> None

Record one new frame for catch-up (live mode). The caller broadcasts it separately via broadcast_frame.

run

run(
    host: str = "127.0.0.1",
    port: int = 5420,
    open_browser: bool = False,
)

Serve on host:port, blocking until the server stops.

set_episodes

set_episodes(episodes: list[dict]) -> None

Replace the served model's episode boundaries (live mode).

Re-serializes /model so a viewer connecting later sees them; already connected viewers are told separately via broadcast_episodes.

start staticmethod

start(
    sim_path: str | Path | Sequence[str | Path],
    host: str = "127.0.0.1",
    preferred_port: int = 5420,
    open_browser: bool = False,
    batch_selections: Sequence[str | Sequence[int] | None]
    | None = None,
)

Load sim_path (one file or several to merge) and serve it, blocking.

Several files, or any batch selection, are merged first via simview.merge.merge_simulation_files. Serves on preferred_port, or the next free port if that one is taken.