rocket-welder-sdk 1.1.36.dev14__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. rocket_welder_sdk/__init__.py +95 -0
  2. rocket_welder_sdk/bytes_size.py +234 -0
  3. rocket_welder_sdk/connection_string.py +291 -0
  4. rocket_welder_sdk/controllers.py +831 -0
  5. rocket_welder_sdk/external_controls/__init__.py +30 -0
  6. rocket_welder_sdk/external_controls/contracts.py +100 -0
  7. rocket_welder_sdk/external_controls/contracts_old.py +105 -0
  8. rocket_welder_sdk/frame_metadata.py +138 -0
  9. rocket_welder_sdk/gst_metadata.py +411 -0
  10. rocket_welder_sdk/high_level/__init__.py +54 -0
  11. rocket_welder_sdk/high_level/client.py +235 -0
  12. rocket_welder_sdk/high_level/connection_strings.py +331 -0
  13. rocket_welder_sdk/high_level/data_context.py +169 -0
  14. rocket_welder_sdk/high_level/frame_sink_factory.py +118 -0
  15. rocket_welder_sdk/high_level/schema.py +195 -0
  16. rocket_welder_sdk/high_level/transport_protocol.py +238 -0
  17. rocket_welder_sdk/keypoints_protocol.py +642 -0
  18. rocket_welder_sdk/opencv_controller.py +278 -0
  19. rocket_welder_sdk/periodic_timer.py +303 -0
  20. rocket_welder_sdk/py.typed +2 -0
  21. rocket_welder_sdk/rocket_welder_client.py +497 -0
  22. rocket_welder_sdk/segmentation_result.py +420 -0
  23. rocket_welder_sdk/session_id.py +238 -0
  24. rocket_welder_sdk/transport/__init__.py +31 -0
  25. rocket_welder_sdk/transport/frame_sink.py +122 -0
  26. rocket_welder_sdk/transport/frame_source.py +74 -0
  27. rocket_welder_sdk/transport/nng_transport.py +197 -0
  28. rocket_welder_sdk/transport/stream_transport.py +193 -0
  29. rocket_welder_sdk/transport/tcp_transport.py +154 -0
  30. rocket_welder_sdk/transport/unix_socket_transport.py +339 -0
  31. rocket_welder_sdk/ui/__init__.py +48 -0
  32. rocket_welder_sdk/ui/controls.py +362 -0
  33. rocket_welder_sdk/ui/icons.py +21628 -0
  34. rocket_welder_sdk/ui/ui_events_projection.py +226 -0
  35. rocket_welder_sdk/ui/ui_service.py +358 -0
  36. rocket_welder_sdk/ui/value_types.py +72 -0
  37. rocket_welder_sdk-1.1.36.dev14.dist-info/METADATA +845 -0
  38. rocket_welder_sdk-1.1.36.dev14.dist-info/RECORD +40 -0
  39. rocket_welder_sdk-1.1.36.dev14.dist-info/WHEEL +5 -0
  40. rocket_welder_sdk-1.1.36.dev14.dist-info/top_level.txt +1 -0
@@ -0,0 +1,195 @@
1
+ """
2
+ Schema types for KeyPoints and Segmentation.
3
+
4
+ Provides type-safe definitions for keypoints and segmentation classes
5
+ that are defined at initialization time and used during processing.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ from abc import ABC, abstractmethod
12
+ from dataclasses import dataclass
13
+ from typing import Any, Dict, List
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class KeyPointDefinition:
18
+ """
19
+ A keypoint definition with ID and name.
20
+
21
+ Created via IKeyPointsSchema.define_point().
22
+ Used as a type-safe handle when adding keypoints to data context.
23
+ """
24
+
25
+ id: int
26
+ name: str
27
+
28
+ def __str__(self) -> str:
29
+ return f"KeyPointDefinition({self.id}, '{self.name}')"
30
+
31
+
32
+ @dataclass(frozen=True)
33
+ class SegmentClass:
34
+ """
35
+ A segmentation class definition with class ID and name.
36
+
37
+ Created via ISegmentationSchema.define_class().
38
+ Used as a type-safe handle when adding instances to data context.
39
+ """
40
+
41
+ class_id: int
42
+ name: str
43
+
44
+ def __str__(self) -> str:
45
+ return f"SegmentClass({self.class_id}, '{self.name}')"
46
+
47
+
48
+ class IKeyPointsSchema(ABC):
49
+ """
50
+ Interface for defining keypoints schema.
51
+
52
+ Keypoints are defined once at initialization and referenced by handle
53
+ when adding data to the context.
54
+ """
55
+
56
+ @abstractmethod
57
+ def define_point(self, name: str) -> KeyPointDefinition:
58
+ """
59
+ Define a new keypoint.
60
+
61
+ Args:
62
+ name: Human-readable name for the keypoint (e.g., "nose", "left_eye")
63
+
64
+ Returns:
65
+ KeyPointDefinition handle for use with IKeyPointsDataContext.add()
66
+ """
67
+ pass
68
+
69
+ @property
70
+ @abstractmethod
71
+ def defined_points(self) -> List[KeyPointDefinition]:
72
+ """Get all defined keypoints."""
73
+ pass
74
+
75
+ @abstractmethod
76
+ def get_metadata_json(self) -> str:
77
+ """Get JSON metadata for serialization."""
78
+ pass
79
+
80
+
81
+ class ISegmentationSchema(ABC):
82
+ """
83
+ Interface for defining segmentation classes schema.
84
+
85
+ Classes are defined once at initialization and referenced by handle
86
+ when adding instances to the context.
87
+ """
88
+
89
+ @abstractmethod
90
+ def define_class(self, class_id: int, name: str) -> SegmentClass:
91
+ """
92
+ Define a new segmentation class.
93
+
94
+ Args:
95
+ class_id: Unique class identifier (0-255)
96
+ name: Human-readable name for the class (e.g., "person", "car")
97
+
98
+ Returns:
99
+ SegmentClass handle for use with ISegmentationDataContext.add()
100
+ """
101
+ pass
102
+
103
+ @property
104
+ @abstractmethod
105
+ def defined_classes(self) -> List[SegmentClass]:
106
+ """Get all defined classes."""
107
+ pass
108
+
109
+ @abstractmethod
110
+ def get_metadata_json(self) -> str:
111
+ """Get JSON metadata for serialization."""
112
+ pass
113
+
114
+
115
+ class KeyPointsSchema(IKeyPointsSchema):
116
+ """Implementation of keypoints schema."""
117
+
118
+ def __init__(self) -> None:
119
+ self._points: Dict[str, KeyPointDefinition] = {}
120
+ self._next_id = 0
121
+
122
+ def define_point(self, name: str) -> KeyPointDefinition:
123
+ """Define a new keypoint."""
124
+ if name in self._points:
125
+ raise ValueError(f"Keypoint '{name}' already defined")
126
+
127
+ point = KeyPointDefinition(id=self._next_id, name=name)
128
+ self._points[name] = point
129
+ self._next_id += 1
130
+ return point
131
+
132
+ @property
133
+ def defined_points(self) -> List[KeyPointDefinition]:
134
+ """Get all defined keypoints."""
135
+ return list(self._points.values())
136
+
137
+ def get_metadata_json(self) -> str:
138
+ """
139
+ Get JSON metadata for serialization.
140
+
141
+ Format matches C# SDK:
142
+ {
143
+ "version": 1,
144
+ "type": "keypoints",
145
+ "points": [{"id": 0, "name": "nose"}, ...]
146
+ }
147
+ """
148
+ metadata: Dict[str, Any] = {
149
+ "version": 1,
150
+ "type": "keypoints",
151
+ "points": [{"id": p.id, "name": p.name} for p in self._points.values()],
152
+ }
153
+ return json.dumps(metadata, indent=2)
154
+
155
+
156
+ class SegmentationSchema(ISegmentationSchema):
157
+ """Implementation of segmentation schema."""
158
+
159
+ def __init__(self) -> None:
160
+ self._classes: Dict[int, SegmentClass] = {}
161
+
162
+ def define_class(self, class_id: int, name: str) -> SegmentClass:
163
+ """Define a new segmentation class."""
164
+ if class_id < 0 or class_id > 255:
165
+ raise ValueError(f"class_id must be 0-255, got {class_id}")
166
+
167
+ if class_id in self._classes:
168
+ raise ValueError(f"Class ID {class_id} already defined")
169
+
170
+ segment_class = SegmentClass(class_id=class_id, name=name)
171
+ self._classes[class_id] = segment_class
172
+ return segment_class
173
+
174
+ @property
175
+ def defined_classes(self) -> List[SegmentClass]:
176
+ """Get all defined classes."""
177
+ return list(self._classes.values())
178
+
179
+ def get_metadata_json(self) -> str:
180
+ """
181
+ Get JSON metadata for serialization.
182
+
183
+ Format matches C# SDK:
184
+ {
185
+ "version": 1,
186
+ "type": "segmentation",
187
+ "classes": [{"classId": 1, "name": "person"}, ...]
188
+ }
189
+ """
190
+ metadata: Dict[str, Any] = {
191
+ "version": 1,
192
+ "type": "segmentation",
193
+ "classes": [{"classId": c.class_id, "name": c.name} for c in self._classes.values()],
194
+ }
195
+ return json.dumps(metadata, indent=2)
@@ -0,0 +1,238 @@
1
+ """
2
+ Unified transport protocol as a value type.
3
+
4
+ Supports: file://, socket://, nng+push+ipc://, nng+push+tcp://, etc.
5
+
6
+ Examples:
7
+ file:///home/user/output.bin - absolute file path
8
+ socket:///tmp/my.sock - Unix domain socket
9
+ nng+push+ipc://tmp/keypoints - NNG Push over IPC
10
+ nng+push+tcp://host:5555 - NNG Push over TCP
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from enum import Enum, auto
16
+ from typing import ClassVar, Dict, Optional
17
+
18
+
19
+ class TransportKind(Enum):
20
+ """Transport kind enumeration."""
21
+
22
+ FILE = auto()
23
+ """File output."""
24
+
25
+ SOCKET = auto()
26
+ """Unix domain socket (direct, no messaging library)."""
27
+
28
+ NNG_PUSH_IPC = auto()
29
+ """NNG Push over IPC."""
30
+
31
+ NNG_PUSH_TCP = auto()
32
+ """NNG Push over TCP."""
33
+
34
+ NNG_PULL_IPC = auto()
35
+ """NNG Pull over IPC."""
36
+
37
+ NNG_PULL_TCP = auto()
38
+ """NNG Pull over TCP."""
39
+
40
+ NNG_PUB_IPC = auto()
41
+ """NNG Pub over IPC."""
42
+
43
+ NNG_PUB_TCP = auto()
44
+ """NNG Pub over TCP."""
45
+
46
+ NNG_SUB_IPC = auto()
47
+ """NNG Sub over IPC."""
48
+
49
+ NNG_SUB_TCP = auto()
50
+ """NNG Sub over TCP."""
51
+
52
+
53
+ class TransportProtocol:
54
+ """
55
+ Unified transport protocol specification as a value type.
56
+
57
+ Supports: file://, socket://, nng+push+ipc://, nng+push+tcp://, etc.
58
+ """
59
+
60
+ # Predefined protocols
61
+ File: TransportProtocol
62
+ Socket: TransportProtocol
63
+ NngPushIpc: TransportProtocol
64
+ NngPushTcp: TransportProtocol
65
+ NngPullIpc: TransportProtocol
66
+ NngPullTcp: TransportProtocol
67
+ NngPubIpc: TransportProtocol
68
+ NngPubTcp: TransportProtocol
69
+ NngSubIpc: TransportProtocol
70
+ NngSubTcp: TransportProtocol
71
+
72
+ _SCHEMA_MAP: ClassVar[Dict[str, TransportKind]] = {
73
+ "file": TransportKind.FILE,
74
+ "socket": TransportKind.SOCKET,
75
+ "nng+push+ipc": TransportKind.NNG_PUSH_IPC,
76
+ "nng+push+tcp": TransportKind.NNG_PUSH_TCP,
77
+ "nng+pull+ipc": TransportKind.NNG_PULL_IPC,
78
+ "nng+pull+tcp": TransportKind.NNG_PULL_TCP,
79
+ "nng+pub+ipc": TransportKind.NNG_PUB_IPC,
80
+ "nng+pub+tcp": TransportKind.NNG_PUB_TCP,
81
+ "nng+sub+ipc": TransportKind.NNG_SUB_IPC,
82
+ "nng+sub+tcp": TransportKind.NNG_SUB_TCP,
83
+ }
84
+
85
+ _KIND_TO_SCHEMA: ClassVar[Dict[TransportKind, str]] = {}
86
+
87
+ def __init__(self, kind: TransportKind, schema: str) -> None:
88
+ self._kind = kind
89
+ self._schema = schema
90
+
91
+ @property
92
+ def kind(self) -> TransportKind:
93
+ """The transport kind."""
94
+ return self._kind
95
+
96
+ @property
97
+ def schema(self) -> str:
98
+ """The schema string (e.g., 'file', 'socket', 'nng+push+ipc')."""
99
+ return self._schema
100
+
101
+ # Classification properties
102
+
103
+ @property
104
+ def is_file(self) -> bool:
105
+ """True if this is a file transport."""
106
+ return self._kind == TransportKind.FILE
107
+
108
+ @property
109
+ def is_socket(self) -> bool:
110
+ """True if this is a Unix socket transport."""
111
+ return self._kind == TransportKind.SOCKET
112
+
113
+ @property
114
+ def is_nng(self) -> bool:
115
+ """True if this is any NNG-based transport."""
116
+ return self._kind in {
117
+ TransportKind.NNG_PUSH_IPC,
118
+ TransportKind.NNG_PUSH_TCP,
119
+ TransportKind.NNG_PULL_IPC,
120
+ TransportKind.NNG_PULL_TCP,
121
+ TransportKind.NNG_PUB_IPC,
122
+ TransportKind.NNG_PUB_TCP,
123
+ TransportKind.NNG_SUB_IPC,
124
+ TransportKind.NNG_SUB_TCP,
125
+ }
126
+
127
+ @property
128
+ def is_push(self) -> bool:
129
+ """True if this is a Push pattern."""
130
+ return self._kind in {TransportKind.NNG_PUSH_IPC, TransportKind.NNG_PUSH_TCP}
131
+
132
+ @property
133
+ def is_pull(self) -> bool:
134
+ """True if this is a Pull pattern."""
135
+ return self._kind in {TransportKind.NNG_PULL_IPC, TransportKind.NNG_PULL_TCP}
136
+
137
+ @property
138
+ def is_pub(self) -> bool:
139
+ """True if this is a Pub pattern."""
140
+ return self._kind in {TransportKind.NNG_PUB_IPC, TransportKind.NNG_PUB_TCP}
141
+
142
+ @property
143
+ def is_sub(self) -> bool:
144
+ """True if this is a Sub pattern."""
145
+ return self._kind in {TransportKind.NNG_SUB_IPC, TransportKind.NNG_SUB_TCP}
146
+
147
+ @property
148
+ def is_ipc(self) -> bool:
149
+ """True if this uses IPC layer."""
150
+ return self._kind in {
151
+ TransportKind.NNG_PUSH_IPC,
152
+ TransportKind.NNG_PULL_IPC,
153
+ TransportKind.NNG_PUB_IPC,
154
+ TransportKind.NNG_SUB_IPC,
155
+ }
156
+
157
+ @property
158
+ def is_tcp(self) -> bool:
159
+ """True if this uses TCP layer."""
160
+ return self._kind in {
161
+ TransportKind.NNG_PUSH_TCP,
162
+ TransportKind.NNG_PULL_TCP,
163
+ TransportKind.NNG_PUB_TCP,
164
+ TransportKind.NNG_SUB_TCP,
165
+ }
166
+
167
+ def create_nng_address(self, path_or_host: str) -> str:
168
+ """
169
+ Create the NNG address from a path/host.
170
+
171
+ For IPC: ipc:///path
172
+ For TCP: tcp://host:port
173
+
174
+ Raises:
175
+ ValueError: If this is not an NNG protocol.
176
+ """
177
+ if not self.is_nng:
178
+ raise ValueError(f"Cannot create NNG address for {self._kind} transport")
179
+
180
+ if self.is_ipc:
181
+ # IPC paths need leading "/" for absolute paths
182
+ if not path_or_host.startswith("/"):
183
+ return f"ipc:///{path_or_host}"
184
+ return f"ipc://{path_or_host}"
185
+
186
+ # TCP
187
+ return f"tcp://{path_or_host}"
188
+
189
+ def __str__(self) -> str:
190
+ return self._schema
191
+
192
+ def __repr__(self) -> str:
193
+ return f"TransportProtocol({self._kind.name}, '{self._schema}')"
194
+
195
+ def __eq__(self, other: object) -> bool:
196
+ if isinstance(other, TransportProtocol):
197
+ return self._kind == other._kind
198
+ return False
199
+
200
+ def __hash__(self) -> int:
201
+ return hash(self._kind)
202
+
203
+ @classmethod
204
+ def parse(cls, s: str) -> TransportProtocol:
205
+ """Parse a protocol string (e.g., 'nng+push+ipc')."""
206
+ result = cls.try_parse(s)
207
+ if result is None:
208
+ raise ValueError(f"Invalid transport protocol: {s}")
209
+ return result
210
+
211
+ @classmethod
212
+ def try_parse(cls, s: Optional[str]) -> Optional[TransportProtocol]:
213
+ """Try to parse a protocol string."""
214
+ if not s:
215
+ return None
216
+
217
+ schema = s.lower().strip()
218
+ kind = cls._SCHEMA_MAP.get(schema)
219
+ if kind is None:
220
+ return None
221
+
222
+ return cls(kind, schema)
223
+
224
+
225
+ # Initialize predefined protocols
226
+ TransportProtocol.File = TransportProtocol(TransportKind.FILE, "file")
227
+ TransportProtocol.Socket = TransportProtocol(TransportKind.SOCKET, "socket")
228
+ TransportProtocol.NngPushIpc = TransportProtocol(TransportKind.NNG_PUSH_IPC, "nng+push+ipc")
229
+ TransportProtocol.NngPushTcp = TransportProtocol(TransportKind.NNG_PUSH_TCP, "nng+push+tcp")
230
+ TransportProtocol.NngPullIpc = TransportProtocol(TransportKind.NNG_PULL_IPC, "nng+pull+ipc")
231
+ TransportProtocol.NngPullTcp = TransportProtocol(TransportKind.NNG_PULL_TCP, "nng+pull+tcp")
232
+ TransportProtocol.NngPubIpc = TransportProtocol(TransportKind.NNG_PUB_IPC, "nng+pub+ipc")
233
+ TransportProtocol.NngPubTcp = TransportProtocol(TransportKind.NNG_PUB_TCP, "nng+pub+tcp")
234
+ TransportProtocol.NngSubIpc = TransportProtocol(TransportKind.NNG_SUB_IPC, "nng+sub+ipc")
235
+ TransportProtocol.NngSubTcp = TransportProtocol(TransportKind.NNG_SUB_TCP, "nng+sub+tcp")
236
+
237
+ # Initialize reverse lookup map
238
+ TransportProtocol._KIND_TO_SCHEMA = {v: k for k, v in TransportProtocol._SCHEMA_MAP.items()}