rocket-welder-sdk 1.1.33__py3-none-any.whl → 1.1.34a2__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.
@@ -15,6 +15,14 @@ from .gst_metadata import GstCaps, GstMetadata
15
15
  from .opencv_controller import OpenCvController
16
16
  from .periodic_timer import PeriodicTimer, PeriodicTimerSync
17
17
  from .rocket_welder_client import RocketWelderClient
18
+ from .session_id import (
19
+ get_actions_url,
20
+ get_keypoints_url,
21
+ get_nng_urls,
22
+ get_segmentation_url,
23
+ get_session_id_from_env,
24
+ parse_session_id,
25
+ )
18
26
 
19
27
  # Alias for backward compatibility and README examples
20
28
  Client = RocketWelderClient
@@ -58,4 +66,11 @@ __all__ = [
58
66
  "PeriodicTimerSync",
59
67
  "Protocol",
60
68
  "RocketWelderClient",
69
+ # SessionId utilities for NNG URL generation
70
+ "get_actions_url",
71
+ "get_keypoints_url",
72
+ "get_nng_urls",
73
+ "get_segmentation_url",
74
+ "get_session_id_from_env",
75
+ "parse_session_id",
61
76
  ]
@@ -16,6 +16,8 @@ from .connection_string import ConnectionMode, ConnectionString, Protocol
16
16
  from .controllers import DuplexShmController, IController, OneWayShmController
17
17
  from .frame_metadata import FrameMetadata # noqa: TC001 - used at runtime in callbacks
18
18
  from .opencv_controller import OpenCvController
19
+ from .session_id import get_nng_urls, get_session_id_from_env
20
+ from .transport.nng_transport import NngFrameSink
19
21
 
20
22
  if TYPE_CHECKING:
21
23
  import numpy.typing as npt
@@ -53,6 +55,9 @@ class RocketWelderClient:
53
55
  self._controller: Optional[IController] = None
54
56
  self._lock = threading.Lock()
55
57
 
58
+ # NNG publishers for streaming results (auto-created if SessionId env var is set)
59
+ self._nng_publishers: dict[str, NngFrameSink] = {}
60
+
56
61
  # Preview support
57
62
  self._preview_enabled = (
58
63
  self._connection.parameters.get("preview", "false").lower() == "true"
@@ -72,6 +77,44 @@ class RocketWelderClient:
72
77
  with self._lock:
73
78
  return self._controller is not None and self._controller.is_running
74
79
 
80
+ @property
81
+ def nng_publishers(self) -> dict[str, NngFrameSink]:
82
+ """Get NNG publishers for streaming results.
83
+
84
+ Returns:
85
+ Dictionary with 'segmentation', 'keypoints', 'actions' keys.
86
+ Empty if SessionId env var was not set at startup.
87
+
88
+ Example:
89
+ client.nng_publishers["segmentation"].write_frame(seg_data)
90
+ """
91
+ return self._nng_publishers
92
+
93
+ def _create_nng_publishers(self, session_id: str) -> None:
94
+ """Create NNG publishers for result streaming.
95
+
96
+ Args:
97
+ session_id: SessionId string (e.g., "ps-{guid}")
98
+ """
99
+ try:
100
+ urls = get_nng_urls(session_id)
101
+
102
+ for name, url in urls.items():
103
+ sink = NngFrameSink.create_publisher(url)
104
+ self._nng_publishers[name] = sink
105
+ logger.info("NNG publisher ready: %s at %s", name, url)
106
+
107
+ logger.info(
108
+ "NNG publishers created for SessionId=%s: seg=%s, kp=%s, actions=%s",
109
+ session_id,
110
+ urls["segmentation"],
111
+ urls["keypoints"],
112
+ urls["actions"],
113
+ )
114
+ except Exception as ex:
115
+ logger.warning("Failed to create NNG publishers: %s", ex)
116
+ # Don't fail start() - NNG is optional for backwards compatibility
117
+
75
118
  def get_metadata(self) -> Optional[GstMetadata]:
76
119
  """
77
120
  Get the current GStreamer metadata.
@@ -119,6 +162,11 @@ class RocketWelderClient:
119
162
  else:
120
163
  raise ValueError(f"Unsupported protocol: {self._connection.protocol}")
121
164
 
165
+ # Auto-create NNG publishers if SessionId env var is set
166
+ session_id = get_session_id_from_env()
167
+ if session_id:
168
+ self._create_nng_publishers(session_id)
169
+
122
170
  # If preview is enabled, wrap the callback to capture frames
123
171
  if self._preview_enabled:
124
172
  self._original_callback = on_frame
@@ -189,6 +237,15 @@ class RocketWelderClient:
189
237
  if self._preview_enabled:
190
238
  self._preview_queue.put(None) # Sentinel value
191
239
 
240
+ # Clean up NNG publishers
241
+ for name, sink in self._nng_publishers.items():
242
+ try:
243
+ sink.close()
244
+ logger.debug("Closed NNG publisher: %s", name)
245
+ except Exception as ex:
246
+ logger.warning("Failed to close NNG publisher %s: %s", name, ex)
247
+ self._nng_publishers.clear()
248
+
192
249
  logger.info("RocketWelder client stopped")
193
250
 
194
251
  def show(self, cancellation_token: Optional[threading.Event] = None) -> None:
@@ -0,0 +1,115 @@
1
+ """SessionId parsing utilities for NNG URL generation.
2
+
3
+ SessionId format: ps-{guid} (e.g., ps-a1b2c3d4-e5f6-7890-abcd-ef1234567890)
4
+ Prefix "ps" = PipelineSession.
5
+
6
+ This module provides utilities to:
7
+ 1. Parse SessionId from environment variable
8
+ 2. Extract the Guid portion
9
+ 3. Generate NNG IPC URLs for streaming results
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import logging
15
+ import os
16
+ import uuid
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+ SESSION_ID_PREFIX = "ps-"
21
+ SESSION_ID_ENV_VAR = "SessionId"
22
+
23
+
24
+ def parse_session_id(session_id: str) -> uuid.UUID:
25
+ """Parse SessionId (ps-{guid}) to extract Guid.
26
+
27
+ Args:
28
+ session_id: SessionId string (e.g., "ps-a1b2c3d4-...")
29
+
30
+ Returns:
31
+ UUID extracted from SessionId
32
+
33
+ Raises:
34
+ ValueError: If session_id format is invalid
35
+
36
+ Examples:
37
+ >>> parse_session_id("ps-a1b2c3d4-e5f6-7890-abcd-ef1234567890")
38
+ UUID('a1b2c3d4-e5f6-7890-abcd-ef1234567890')
39
+ >>> parse_session_id("a1b2c3d4-e5f6-7890-abcd-ef1234567890") # backwards compat
40
+ UUID('a1b2c3d4-e5f6-7890-abcd-ef1234567890')
41
+ """
42
+ if session_id.startswith(SESSION_ID_PREFIX):
43
+ return uuid.UUID(session_id[len(SESSION_ID_PREFIX) :])
44
+ # Fallback: try parsing as raw guid for backwards compatibility
45
+ return uuid.UUID(session_id)
46
+
47
+
48
+ def get_session_id_from_env() -> str | None:
49
+ """Get SessionId from environment variable.
50
+
51
+ Returns:
52
+ SessionId string or None if not set
53
+ """
54
+ return os.environ.get(SESSION_ID_ENV_VAR)
55
+
56
+
57
+ def get_nng_urls(session_id: str) -> dict[str, str]:
58
+ """Generate NNG IPC URLs from SessionId.
59
+
60
+ Args:
61
+ session_id: SessionId string (e.g., "ps-a1b2c3d4-...")
62
+
63
+ Returns:
64
+ Dictionary with 'segmentation', 'keypoints', 'actions' URLs
65
+
66
+ Examples:
67
+ >>> urls = get_nng_urls("ps-a1b2c3d4-e5f6-7890-abcd-ef1234567890")
68
+ >>> urls["segmentation"]
69
+ 'ipc:///tmp/rw-a1b2c3d4-e5f6-7890-abcd-ef1234567890-seg.sock'
70
+ """
71
+ guid = parse_session_id(session_id)
72
+ return {
73
+ "segmentation": f"ipc:///tmp/rw-{guid}-seg.sock",
74
+ "keypoints": f"ipc:///tmp/rw-{guid}-kp.sock",
75
+ "actions": f"ipc:///tmp/rw-{guid}-actions.sock",
76
+ }
77
+
78
+
79
+ def get_segmentation_url(session_id: str) -> str:
80
+ """Get NNG URL for segmentation stream.
81
+
82
+ Args:
83
+ session_id: SessionId string (e.g., "ps-a1b2c3d4-...")
84
+
85
+ Returns:
86
+ IPC URL for segmentation stream
87
+ """
88
+ guid = parse_session_id(session_id)
89
+ return f"ipc:///tmp/rw-{guid}-seg.sock"
90
+
91
+
92
+ def get_keypoints_url(session_id: str) -> str:
93
+ """Get NNG URL for keypoints stream.
94
+
95
+ Args:
96
+ session_id: SessionId string (e.g., "ps-a1b2c3d4-...")
97
+
98
+ Returns:
99
+ IPC URL for keypoints stream
100
+ """
101
+ guid = parse_session_id(session_id)
102
+ return f"ipc:///tmp/rw-{guid}-kp.sock"
103
+
104
+
105
+ def get_actions_url(session_id: str) -> str:
106
+ """Get NNG URL for actions stream.
107
+
108
+ Args:
109
+ session_id: SessionId string (e.g., "ps-a1b2c3d4-...")
110
+
111
+ Returns:
112
+ IPC URL for actions stream
113
+ """
114
+ guid = parse_session_id(session_id)
115
+ return f"ipc:///tmp/rw-{guid}-actions.sock"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rocket-welder-sdk
3
- Version: 1.1.33
3
+ Version: 1.1.34a2
4
4
  Summary: High-performance video streaming SDK for RocketWelder services using ZeroBuffer IPC
5
5
  Home-page: https://github.com/modelingevolution/rocket-welder-sdk
6
6
  Author: ModelingEvolution
@@ -1,4 +1,4 @@
1
- rocket_welder_sdk/__init__.py,sha256=nxaj88kgewtAbyTw7wLGvgjIkY9VOYUuBVtzw1MMW7c,2033
1
+ rocket_welder_sdk/__init__.py,sha256=7jawqof-tt0S0G7CMMOmHRsVLbUf-o8sSREP1VxEeJ4,2400
2
2
  rocket_welder_sdk/bytes_size.py,sha256=Myl29-wyWCIYdbMmgaxXebT8Dz8_Fwcr3fnfaNW81P0,7463
3
3
  rocket_welder_sdk/connection_string.py,sha256=NIC6OiOXF-DeBFCWzgMFOWsenrSS45hY81j_HLMSpgo,9974
4
4
  rocket_welder_sdk/controllers.py,sha256=X7D7OyiuHhGTrmrSNG2Tljsy1_4PGRObytB4dLyvRrg,32600
@@ -8,8 +8,9 @@ rocket_welder_sdk/keypoints_protocol.py,sha256=NKiSPrevWG4_RrD6jtFxPjwftlaPWe1Cq
8
8
  rocket_welder_sdk/opencv_controller.py,sha256=MDM6_yFBB9BaMa5jnZRqw7xZZB-WuLr7EPrrfHQ2DK4,9905
9
9
  rocket_welder_sdk/periodic_timer.py,sha256=hnObybmrnf3J47QrNKJhYAytLKwria016123NvPRfQ0,9369
10
10
  rocket_welder_sdk/py.typed,sha256=0cXFZXmes4Y-vnl4lO3HtyyyWaFNw85B7tJdFeCtHDc,67
11
- rocket_welder_sdk/rocket_welder_client.py,sha256=mguSN8E4nV8JsNOJvhHFNv7yIz7Ppb25_-9m68d6iD4,15244
11
+ rocket_welder_sdk/rocket_welder_client.py,sha256=2tGL98hLXU_Xl2LzjhdLpQkp9oxzb4D3WmPOcMZMyw4,17474
12
12
  rocket_welder_sdk/segmentation_result.py,sha256=q3n8m1sooPcattfXisL9em5gZKbEZ1ueGqeXfOrdaHY,13417
13
+ rocket_welder_sdk/session_id.py,sha256=4RVNxuMzJsJ3Me1LveTe_RSDevEUsOozlamSRMXfXGA,3114
13
14
  rocket_welder_sdk/external_controls/__init__.py,sha256=ldOLGhLLS5BQL8m4VKFYV0SvsNNlV2tghlc7rkqadU8,699
14
15
  rocket_welder_sdk/external_controls/contracts.py,sha256=3DU6pdpteN50gF2fsS7C2279dGjDa0tZLrLntkBa2LM,2607
15
16
  rocket_welder_sdk/external_controls/contracts_old.py,sha256=XWriuXJZu5caTSS0bcTIOZcKnj-IRCm96voA4gqLBfU,2980
@@ -31,7 +32,7 @@ rocket_welder_sdk/ui/icons.py,sha256=DcDklZkPmiEzlOD4IR7VTJOtGPCuuh_OM_WN7ScghWE
31
32
  rocket_welder_sdk/ui/ui_events_projection.py,sha256=siiNhjLEBOPfTKw1ZhOPGkwIN5rLDH7V9VCZTNrhEtQ,7836
32
33
  rocket_welder_sdk/ui/ui_service.py,sha256=uRdpyJGoCQmtOli_HKSrxLwhZYG-XRuHIYdkmFz1zNk,12026
33
34
  rocket_welder_sdk/ui/value_types.py,sha256=f7OA_9zgXEDPoITc8v8SfAR23I4XeFhE3E2_GcAbR6k,1616
34
- rocket_welder_sdk-1.1.33.dist-info/METADATA,sha256=WK6edMkZs55WIe1AOJjECFfHB2SmTMS31IpschstdpE,24847
35
- rocket_welder_sdk-1.1.33.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
- rocket_welder_sdk-1.1.33.dist-info/top_level.txt,sha256=2iZvBjnwVCUW-uDE23-eJld5PZ9-mlPI69QiXM5IrTA,18
37
- rocket_welder_sdk-1.1.33.dist-info/RECORD,,
35
+ rocket_welder_sdk-1.1.34a2.dist-info/METADATA,sha256=XlxEOkkIEDYqUlxlPbBv3ZhWNeiqo9cXjnHm8yY_16A,24849
36
+ rocket_welder_sdk-1.1.34a2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ rocket_welder_sdk-1.1.34a2.dist-info/top_level.txt,sha256=2iZvBjnwVCUW-uDE23-eJld5PZ9-mlPI69QiXM5IrTA,18
38
+ rocket_welder_sdk-1.1.34a2.dist-info/RECORD,,