One session, two clients. Client A leaves and comes back inside the same session. The model steps whenever at least one client is connected.
set_paused from one of them pauses generation for all of
them. What each client receives is up to you. A model with one output track shows everyone the
same video. A model can also declare several tracks, one per view, and each client subscribes to
the tracks it wants. Messages work the same way: send one to everyone, or to a single client
through its handle, covered below.
The four hooks
You get one hook for each edge in the diagram. Decorate a method with it and the runtime calls the method at that moment:@session_started runs before any client has connected, and self.state already exists by then,
built from the defaults, so this hook can write to it. @session_ended runs when the runtime tears
the session down, while the state is still readable. The two connection hooks run once per client,
each time one joins or leaves.
A hook can be async def or a plain def, and a model declares at most one of each. Hooks run
between steps, never in the middle of one.
When a session ends, the runtime tears down every connection at once and does not call
@disconnected for each of them. Anything that must happen no matter how the session ends
belongs in @session_ended.Which hook to use
Put work where its lifetime matches. Anything that outlives a single client goes in the session hooks. The typical job for@session_ended is to reset whatever your model holds outside the state, such as caches or a
world the model has been generating, so the next session starts clean. The runtime resets the
state for you but never touches your model:
load(). It runs once when the
container starts, long before either kind of hook.
The client handle
To know which client a hook or an@event handler is running for, add a client: ClientInfo
parameter to it. The runtime fills it in with the client that triggered the call. It is not part
of the command’s payload and does not appear in the schema.
ClientInfo carries the connection’s id, when it joined, and a send() that reaches that client
alone. The handle stays valid for as long as the client is connected, including inside its own
@disconnected hook.
Sessions & clients reference
The four decorators and every field on the client handle.
Serving several clients
self.send() broadcasts a message to everyone in the session. client.send() reaches one client.
To message a specific client later, outside the hook that gave you its handle, keep the handle:
self.connected is an asyncio.Event that is set while at least one client is connected and clear
when the last one has left. It tracks whether any client is connected, not which one.
Next
The Step Loop
How the runtime drives the three calls, when to refuse a step, and how playout is paced.
Events & Messages
Commands the client can call and messages the model sends back.