Skip to content

Commit 634452a

Browse files
favreaujeffamstutz
authored andcommitted
Add Python TSD client library (tsd_client)
Provides protocol, connection, DataTree codec, scene graph, interactive Jupyter viewer (orbit/animation/detach), and reusable panels (datatree, transfer function, clip planes, lights) for TSD-based render servers. Made-with: Cursor
1 parent d9bafb3 commit 634452a

19 files changed

Lines changed: 8665 additions & 0 deletions

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ docs/out/*
88
.anari_deps
99
.claude
1010
.codex
11+
*.egg-info*
12+
*.ipynb_checkpoints*

tsd/python/README.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<!--
2+
Copyright 2025-2026 NVIDIA Corporation
3+
SPDX-License-Identifier: Apache-2.0
4+
-->
5+
6+
# tsd_client
7+
8+
Python client library for [TSD](https://github.com/NVIDIA/VisRTX) (VisRTX) render servers over TCP.
9+
10+
Provides the base protocol, connection management, DataTree binary codec,
11+
scene graph abstraction, interactive Jupyter viewer widget, and reusable
12+
panels for TSD-based applications.
13+
14+
## Installation
15+
16+
```bash
17+
pip install -e .
18+
```
19+
20+
## Usage
21+
22+
### Base client (any TSD server)
23+
24+
```python
25+
from tsd_client import TSDClient
26+
27+
client = TSDClient("127.0.0.1", port=12345)
28+
client.start_rendering()
29+
client.send_frame_config(1920, 1080)
30+
31+
# Fetch and inspect the scene
32+
sg = client.scene_graph
33+
sg.print_layers()
34+
sg.print_objects()
35+
36+
# Modify a transform and push
37+
xfm = sg.transform_for_object(sg.ANARI_VOLUME, 0)
38+
if xfm:
39+
xfm.position = (0, 0, 0)
40+
xfm.scale = (100, 100, 100)
41+
xfm.commit(client)
42+
43+
client.disconnect()
44+
```
45+
46+
### Extending for a specific application
47+
48+
```python
49+
from enum import IntEnum
50+
from tsd_client import TSDClient, SceneGraph
51+
52+
class MyAppMessageType(IntEnum):
53+
SET_ANIMATION_TIME = 100
54+
REQUEST_STATUS = 101
55+
STATUS_INFO = 102
56+
57+
class MyAppClient(TSDClient):
58+
def __init__(self, host="127.0.0.1", port=12345, **kwargs):
59+
super().__init__(host, port, **kwargs)
60+
61+
def set_animation_time(self, t: float):
62+
import struct
63+
self.send(MyAppMessageType.SET_ANIMATION_TIME, struct.pack("<f", t))
64+
```
65+
66+
### DataTree codec
67+
68+
```python
69+
from tsd_client import DataTree
70+
71+
# Deserialize a DataTree from binary (e.g. from a StructuredMessage payload)
72+
tree = DataTree.from_bytes(raw_bytes)
73+
tree.print()
74+
75+
# Build and serialize
76+
tree = DataTree()
77+
tree.root["material"]["roughness"].set_float(0.4)
78+
data = tree.to_bytes()
79+
```
80+
81+
## Architecture
82+
83+
```
84+
tsd_client/
85+
├── __init__.py # Public API surface
86+
├── protocol.py # MessageType enum, wire format constants
87+
├── connection.py # TCP socket, 8-byte framed messaging, recv thread
88+
├── anari_types.py # ANARI type IDs, sizes, pack/unpack
89+
├── datatree.py # DataTree/DataNode binary codec (mirrors tsd::core::DataTree)
90+
├── scene.py # SceneGraph, ObjectRef, TransformRef, LayerNodeInfo
91+
├── client.py # TSDClient base class with scene graph management
92+
├── viewer.py # AnyWidget-based Jupyter viewer (orbit, animation, detach)
93+
├── session.py # TSDSession convenience wrapper (client + viewer + panels)
94+
├── utils.py # Shared math, TF parsers, Jupyter helpers
95+
└── panels/
96+
├── datatree_panel.py # Hierarchical scene tree inspector
97+
├── transfer_function_panel.py # Interactive colour-map & opacity editor
98+
├── clip_planes_panel.py # Volume clip plane controls
99+
└── light_panel.py # Light parameter editor
100+
```
101+
102+
## Protocol
103+
104+
The wire format matches the C++ `tsd::network::NetworkChannel`:
105+
106+
- **Header (8 bytes):** `uint8 type | 3 bytes padding | uint32 payload_length` (little-endian)
107+
- **Payload:** variable-length raw bytes
108+
109+
Message type values match `tsd::network::MessageType` in `RenderSession.hpp`. Application-specific extensions use values >= 100.
110+
111+
## License
112+
113+
Apache-2.0

0 commit comments

Comments
 (0)