Hello and sorry for the delay in this answer. This is a section that is best suited for just actual tutorials and guides we provide, so my response is delayed.
You can join and control Live Sessions programmatically from a Kit‑based microservice, but you still need a running Kit process (with the Live stack loaded), and you must either provide a headless display environment or run a truly headless Kit build. Pure “one‑shot HTTP POST with no Kit process” is not enough.
Below I’ll walk through each of your questions.
1. Using omni.kit.collaboration.channel_manager in a microservice
Yes, omni.kit.collaboration.channel_manager is intended to let code join a Live channel and send/receive messages; it works from Python code running inside a Kit app (including a microservice built on Kit). docs.omniverse.nvidia
A typical flow is:
import omni.kit.collaboration.channel_manager as cm
channel = await cm.join_channel_async(channel_url, create_if_missing=False)
# channel is a Channel object; you can listen for messages, send messages, etc.
Key points:
join_channel_async(base_url, create_if_missing) connects to the Live channel for a given URL and starts listening. docs.omniverse.nvidia
- It does not by itself create or open the USD stage or LiveSession; you usually:
- Open the base USD layer.
- Create or get a
LiveSession for that layer (omni.kit.usd.layers.LiveSession). docs.omniverse.nvidia
- Join the LiveSession, which adds the
.live sublayer and sets the edit target. docs.omniverse.nvidia
- Use the channel only for Live messaging (user list, chat, etc.).
The connect-samples repo has a liveSession.py script that shows the more complete, non‑GUI flow: it opens a stage, finds/creates a LiveSession, joins it, and then attaches to the LiveSessionChannel to process messages in a loop. github
So, for a microservice:
- Start Kit in headless mode with the needed extensions (USD,
omni.kit.usd.layers, omni.connect.core, omni.kit.collaboration.channel_manager, your own service ext).
- In your extension’s startup:
- Open the USD stage (or wait for it to exist).
- Create or open the LiveSession (
LiveSession(stage_or_identifier)).
- Call
live_session.join(session_name) to get the .live layer attached. github
- Use
channel_manager.join_channel_async(live_session.getInfo().getChannelUri(), False) if you also need to interact with the Live message channel (e.g., user list, custom messages). docs.omniverse.nvidia
Permissions and discovery:
- “Joining” a Live Session is basically joining its
.live sublayer and its channel; you must have read/write access to the Nucleus path (via your Nucleus credentials / tokens).
- There is no automatic “discover sessions” HTTP index; in practice you either:
- Already know the Nucleus path and session name you want to join, or
- Use Nucleus browsing APIs or a custom service to enumerate
.live layers on a given USD file.
2. Joining / controlling a Live Session via HTTP POST only
The /open_live_session endpoint you tested is not a self‑contained Live client. It is typically an HTTP endpoint exposed by a running Kit app that:
- Receives a POST, and
- In response, tells that Kit app to open/join a Live Session on a given stage. github
Therefore:
- You cannot join and drive a Live Session purely by calling HTTP against Nucleus alone; you always need a Kit‑based process that:
- Maintains the WebSocket / Live channel connection.
- Holds the USD stage and
.live layer in memory.
- A persistent Python/Kit process is required; the HTTP POST is just a trigger into that process, not a substitute for it.
If you want a pure HTTP interface to Live from other services, the usual pattern is:
- Build a Kit microservice that runs headless and exposes your own REST or gRPC endpoints.
- Those endpoints call into
omni.kit.usd.layers.LiveSession, channel_manager, and USD APIs inside the long‑running Kit process. docs.omniverse.nvidia
3. Error: no DISPLAY environment variable specified
This error indicates that the Kit binary you’re invoking expects an X/GLFW windowing environment, even if you don’t plan to draw anything. Some standard Composer/Viewer configs try to load windowing plugins, which check DISPLAY on Linux and fail if there is no X server. github
Implications:
- It doesn’t mean Live itself “requires a GUI,” but your chosen Kit config likely includes UI and windowing extensions. Those try to initialize a display as part of startup, and that fails in a bare headless environment.
- That’s why you see
no DISPLAY when you hit /open_live_session from a terminal: behind that endpoint, a UI‑configured Kit is trying to open or change a stage and hits windowing init.
Headless options:
- Use a headless Kit configuration (no
omni.appwindow, carb.windowing-glfw, etc.). Omniverse docs emphasize that Kit can be run headless to create microservices. docs.omniverse.nvidia
- Or, provide a virtual X server (e.g., Xvfb) and set
DISPLAY=:99 so the existing config can initialize windowing without a physical monitor. This is a common workaround when you must reuse a UI‑oriented kit file in a headless environment. stackoverflow
Recommended for a clean microservice:
- Start from the Kit App Template or a minimal headless
.kit file provided in the docs, which omits UI/windowing extensions and is designed for service use. docs.omniverse.nvidia
- Add only what you need: Nucleus client, USD, LiveSession, collaboration channel, any message/HTTP service extension.
- Run it in Docker or on a server as a long‑lived service process. No X server needed if you avoid windowing extensions.
Putting it together: a workable microservice pattern
For your use case (“join and control Live Session programmatically, no GUI”):
- Yes – use
omni.kit.usd.layers.LiveSession and omni.kit.collaboration.channel_manager from Python running in a headless Kit process. docs.omniverse.nvidia
- No – you can’t rely on a single
/open_live_session POST to Nucleus without any Kit process; that endpoint must be handled by Kit.
- Headless – either:
- Use a Kit config built explicitly for headless/microservice (preferred), or
- Run an Xvfb/similar virtual display and set
DISPLAY so that a UI‑centric config can still start.