rocket-welder-sdk 1.1.44__py3-none-any.whl → 1.1.46__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,7 +15,12 @@ import numpy as np
15
15
  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
- from .high_level.connection_strings import KeyPointsConnectionString, SegmentationConnectionString
18
+ from .graphics import ILayerCanvas, IStageSink, IStageWriter, RgbColor, StageSink
19
+ from .high_level.connection_strings import (
20
+ GraphicsConnectionString,
21
+ KeyPointsConnectionString,
22
+ SegmentationConnectionString,
23
+ )
19
24
  from .high_level.frame_sink_factory import FrameSinkFactory
20
25
  from .keypoints_protocol import IKeyPointsSink, IKeyPointsWriter, KeyPointsSink
21
26
  from .opencv_controller import OpenCvController
@@ -188,25 +193,26 @@ class RocketWelderClient:
188
193
 
189
194
  def start_with_writers(
190
195
  self,
191
- on_frame: Callable[[Mat, ISegmentationResultWriter, IKeyPointsWriter, Mat], None], # type: ignore[valid-type]
196
+ on_frame: Callable[[Mat, ISegmentationResultWriter, IKeyPointsWriter, IStageWriter, Mat], None], # type: ignore[valid-type]
192
197
  cancellation_token: Optional[threading.Event] = None,
193
198
  ) -> None:
194
199
  """
195
- Start receiving frames with segmentation and keypoints output support.
200
+ Start receiving frames with segmentation, keypoints, and graphics output support.
196
201
 
197
202
  Creates sinks for streaming AI results to rocket-welder2.
198
203
 
199
204
  Configuration via environment variables:
200
205
  - SEGMENTATION_SINK_URL: URL for segmentation output (e.g., socket:///tmp/seg.sock)
201
206
  - KEYPOINTS_SINK_URL: URL for keypoints output (e.g., socket:///tmp/kp.sock)
207
+ - STAGE_SINK_URL: URL for graphics/stage output (e.g., socket:///tmp/stage.sock)
202
208
 
203
209
  Args:
204
- on_frame: Callback receiving (input_mat, seg_writer, kp_writer, output_mat).
210
+ on_frame: Callback receiving (input_mat, seg_writer, kp_writer, stage_writer, output_mat).
205
211
  The writers are created per-frame and auto-flush on context exit.
206
212
  cancellation_token: Optional cancellation token
207
213
 
208
214
  Example:
209
- def process_frame(input_mat, seg_writer, kp_writer, output_mat):
215
+ def process_frame(input_mat, seg_writer, kp_writer, stage_writer, output_mat):
210
216
  # Run AI inference
211
217
  result = ai_model.infer(input_mat)
212
218
 
@@ -218,6 +224,11 @@ class RocketWelderClient:
218
224
  for kp in result.keypoints:
219
225
  kp_writer.append(kp.id, kp.x, kp.y, kp.confidence)
220
226
 
227
+ # Draw graphics overlay
228
+ layer = stage_writer[0]
229
+ layer.set_font_size(24)
230
+ layer.draw_text("Detection count: 5", 10, 30)
231
+
221
232
  # Copy/draw to output
222
233
  output_mat[:] = input_mat
223
234
 
@@ -248,11 +259,13 @@ class RocketWelderClient:
248
259
  # Create sinks from environment
249
260
  seg_sink = self._get_or_create_segmentation_sink()
250
261
  kp_sink = self._get_or_create_keypoints_sink()
262
+ stage_sink = self._get_or_create_stage_sink()
251
263
 
252
264
  logger.info(
253
- "Starting RocketWelder client with AI output support: seg=%s, kp=%s",
265
+ "Starting RocketWelder client with AI output support: seg=%s, kp=%s, stage=%s",
254
266
  "configured" if seg_sink else "null",
255
267
  "configured" if kp_sink else "null",
268
+ "configured" if stage_sink else "null",
256
269
  )
257
270
 
258
271
  # Wrapper callback that creates per-frame writers
@@ -269,23 +282,155 @@ class RocketWelderClient:
269
282
  frame_metadata.frame_number,
270
283
  )
271
284
  # Use no-op writers
272
- on_frame(
273
- input_mat, _NoOpSegmentationWriter(), _NoOpKeyPointsWriter(), output_mat
274
- )
285
+ with stage_sink.create_writer(frame_metadata.frame_number) as stage_writer:
286
+ on_frame(
287
+ input_mat,
288
+ _NoOpSegmentationWriter(),
289
+ _NoOpKeyPointsWriter(),
290
+ stage_writer,
291
+ output_mat,
292
+ )
275
293
  return
276
294
 
277
- # Create per-frame writers from sinks
295
+ # Create per-frame writers from sinks (all auto-flush on context exit)
278
296
  with seg_sink.create_writer(
279
297
  frame_metadata.frame_number, caps.width, caps.height
280
- ) as seg_writer, kp_sink.create_writer(frame_metadata.frame_number) as kp_writer:
298
+ ) as seg_writer, kp_sink.create_writer(
299
+ frame_metadata.frame_number
300
+ ) as kp_writer, stage_sink.create_writer(
301
+ frame_metadata.frame_number
302
+ ) as stage_writer:
281
303
  # Call user callback with writers
282
- on_frame(input_mat, seg_writer, kp_writer, output_mat)
304
+ on_frame(input_mat, seg_writer, kp_writer, stage_writer, output_mat)
283
305
  # Writers auto-flush on context exit
284
306
 
285
307
  # Start the controller with our wrapper
286
308
  self._controller.start(writer_callback, cancellation_token) # type: ignore[arg-type]
287
309
  logger.info("RocketWelder client started with writers: %s", self._connection)
288
310
 
311
+ def start_with_writers_oneway(
312
+ self,
313
+ on_frame: Callable[[Mat, ISegmentationResultWriter, IKeyPointsWriter, IStageWriter], None], # type: ignore[valid-type]
314
+ cancellation_token: Optional[threading.Event] = None,
315
+ ) -> None:
316
+ """
317
+ Start receiving frames with writers in ONE-WAY mode (no output frame).
318
+
319
+ This is for inference-only containers that consume frames but don't produce
320
+ modified output. Data is streamed via Unix sockets for downstream consumers.
321
+
322
+ Configuration via environment variables:
323
+ - SEGMENTATION_SINK_URL: URL for segmentation output (e.g., socket:///tmp/seg.sock)
324
+ - KEYPOINTS_SINK_URL: URL for keypoints output (e.g., socket:///tmp/kp.sock)
325
+ - GRAPHICS_SINK_URL: URL for graphics/stage output (e.g., socket:///tmp/stage.sock)
326
+
327
+ Args:
328
+ on_frame: Callback receiving (input_mat, seg_writer, kp_writer, stage_writer).
329
+ Note: NO output_mat parameter - this is one-way/sink mode.
330
+ cancellation_token: Optional cancellation token
331
+
332
+ Example:
333
+ def process_frame(input_mat, seg_writer, kp_writer, stage_writer):
334
+ # Run AI inference
335
+ result = ai_model.infer(input_mat)
336
+
337
+ # Write segmentation results
338
+ for instance in result.instances:
339
+ seg_writer.append(instance.class_id, instance.instance_id, instance.points)
340
+
341
+ # Write keypoints
342
+ for kp in result.keypoints:
343
+ kp_writer.append(kp.id, kp.x, kp.y, kp.confidence)
344
+
345
+ # Draw graphics overlay
346
+ layer = stage_writer[0]
347
+ layer.set_font_size(24)
348
+ layer.draw_text("Detection count: 5", 10, 30)
349
+
350
+ # NOTE: No output_mat - we don't modify frames in sink mode
351
+
352
+ client.start_with_writers_oneway(process_frame)
353
+
354
+ Raises:
355
+ RuntimeError: If already running
356
+ ValueError: If connection type is not supported
357
+ """
358
+ with self._lock:
359
+ if self._controller and self._controller.is_running:
360
+ raise RuntimeError("Client is already running")
361
+
362
+ # Create controller - OneWay mode uses OneWayShmController
363
+ if self._connection.protocol == Protocol.SHM:
364
+ if self._connection.connection_mode == ConnectionMode.DUPLEX:
365
+ # For duplex mode, use the other method
366
+ raise ValueError(
367
+ "start_with_writers_oneway() is for OneWay mode. "
368
+ "Use start_with_writers() for Duplex mode."
369
+ )
370
+ self._controller = OneWayShmController(self._connection)
371
+ elif self._connection.protocol == Protocol.FILE or bool(
372
+ self._connection.protocol & Protocol.MJPEG # type: ignore[operator]
373
+ ):
374
+ self._controller = OpenCvController(self._connection)
375
+ else:
376
+ raise ValueError(f"Unsupported protocol: {self._connection.protocol}")
377
+
378
+ # Create sinks from environment
379
+ seg_sink = self._get_or_create_segmentation_sink()
380
+ kp_sink = self._get_or_create_keypoints_sink()
381
+ stage_sink = self._get_or_create_stage_sink()
382
+
383
+ logger.info(
384
+ "Starting RocketWelder client with AI output support (one-way): seg=%s, kp=%s, stage=%s",
385
+ "configured" if seg_sink else "null",
386
+ "configured" if kp_sink else "null",
387
+ "configured" if stage_sink else "null",
388
+ )
389
+
390
+ # Track frame number manually for one-way mode (no FrameMetadata from controller)
391
+ frame_number_holder = [0] # Use list to allow mutation in nested function
392
+
393
+ # Wrapper callback that creates per-frame writers
394
+ # OneWay controller provides only input Mat, no output Mat
395
+ def writer_callback_oneway(input_mat: Mat) -> None: # type: ignore[valid-type]
396
+ frame_number_holder[0] += 1
397
+ frame_number = frame_number_holder[0]
398
+
399
+ # Get caps from controller metadata (width/height for segmentation)
400
+ metadata = self._controller.get_metadata() if self._controller else None
401
+ caps = metadata.caps if metadata else None
402
+
403
+ if caps is None:
404
+ logger.warning(
405
+ "GstCaps not available for frame %d, using no-op writers",
406
+ frame_number,
407
+ )
408
+ # Use no-op writers
409
+ with stage_sink.create_writer(frame_number) as stage_writer:
410
+ on_frame(
411
+ input_mat,
412
+ _NoOpSegmentationWriter(),
413
+ _NoOpKeyPointsWriter(),
414
+ stage_writer,
415
+ )
416
+ return
417
+
418
+ # Create per-frame writers from sinks (all auto-flush on context exit)
419
+ with seg_sink.create_writer(
420
+ frame_number, caps.width, caps.height
421
+ ) as seg_writer, kp_sink.create_writer(
422
+ frame_number
423
+ ) as kp_writer, stage_sink.create_writer(
424
+ frame_number
425
+ ) as stage_writer:
426
+ # Call user callback with writers (no output_mat for one-way)
427
+ on_frame(input_mat, seg_writer, kp_writer, stage_writer)
428
+ # Writers auto-flush on context exit
429
+
430
+ # Start the controller with our wrapper (single-Mat callback for OneWay)
431
+ self._controller.start(writer_callback_oneway, cancellation_token)
432
+ logger.info("RocketWelder client started with writers (one-way): %s", self._connection)
433
+
289
434
  def _get_or_create_segmentation_sink(self) -> ISegmentationResultSink:
290
435
  """Get or create segmentation result sink from environment."""
291
436
  import os
@@ -324,6 +469,23 @@ class RocketWelderClient:
324
469
  logger.warning("Failed to create keypoints sink from %s: %s", url, ex)
325
470
  return _NullKeyPointsSink()
326
471
 
472
+ def _get_or_create_stage_sink(self) -> IStageSink:
473
+ """Get or create graphics stage sink from environment."""
474
+ import os
475
+
476
+ url = os.environ.get("GRAPHICS_SINK_URL")
477
+ if not url:
478
+ logger.debug("GRAPHICS_SINK_URL not set, using null sink")
479
+ return _NullStageSink()
480
+
481
+ try:
482
+ cs = GraphicsConnectionString.parse(url)
483
+ frame_sink = FrameSinkFactory.create(cs.protocol, cs.address)
484
+ return StageSink(frame_sink=frame_sink, owns_sink=True)
485
+ except Exception as ex:
486
+ logger.warning("Failed to create graphics stage sink from %s: %s", url, ex)
487
+ return _NullStageSink()
488
+
327
489
  def stop(self) -> None:
328
490
  """Stop the client and clean up resources."""
329
491
  with self._lock:
@@ -620,3 +782,162 @@ class _NullSegmentationSink(ISegmentationResultSink):
620
782
  def close(self) -> None:
621
783
  """No-op close."""
622
784
  pass
785
+
786
+
787
+ class _NoOpLayerCanvas(ILayerCanvas):
788
+ """No-op layer canvas that discards all drawing operations."""
789
+
790
+ @property
791
+ def layer_id(self) -> int:
792
+ """The layer ID."""
793
+ return 0
794
+
795
+ # Frame type
796
+ def master(self) -> None:
797
+ """No-op."""
798
+ pass
799
+
800
+ def remain(self) -> None:
801
+ """No-op."""
802
+ pass
803
+
804
+ def clear(self) -> None:
805
+ """No-op."""
806
+ pass
807
+
808
+ # Context state - Styling
809
+ def set_stroke(self, color: RgbColor) -> None:
810
+ """No-op."""
811
+ pass
812
+
813
+ def set_fill(self, color: RgbColor) -> None:
814
+ """No-op."""
815
+ pass
816
+
817
+ def set_thickness(self, width: int) -> None:
818
+ """No-op."""
819
+ pass
820
+
821
+ def set_font_size(self, size: int) -> None:
822
+ """No-op."""
823
+ pass
824
+
825
+ def set_font_color(self, color: RgbColor) -> None:
826
+ """No-op."""
827
+ pass
828
+
829
+ # Context state - Transforms
830
+ def translate(self, dx: float, dy: float) -> None:
831
+ """No-op."""
832
+ pass
833
+
834
+ def rotate(self, degrees: float) -> None:
835
+ """No-op."""
836
+ pass
837
+
838
+ def scale(self, sx: float, sy: float) -> None:
839
+ """No-op."""
840
+ pass
841
+
842
+ def skew(self, kx: float, ky: float) -> None:
843
+ """No-op."""
844
+ pass
845
+
846
+ def set_matrix(
847
+ self,
848
+ scale_x: float,
849
+ skew_x: float,
850
+ trans_x: float,
851
+ skew_y: float,
852
+ scale_y: float,
853
+ trans_y: float,
854
+ ) -> None:
855
+ """No-op."""
856
+ pass
857
+
858
+ # Context stack
859
+ def save(self) -> None:
860
+ """No-op."""
861
+ pass
862
+
863
+ def restore(self) -> None:
864
+ """No-op."""
865
+ pass
866
+
867
+ def reset_context(self) -> None:
868
+ """No-op."""
869
+ pass
870
+
871
+ # Draw operations
872
+ def draw_polygon(self, points: Any) -> None:
873
+ """No-op."""
874
+ pass
875
+
876
+ def draw_text(self, text: str, x: int, y: int) -> None:
877
+ """No-op."""
878
+ pass
879
+
880
+ def draw_circle(self, center_x: int, center_y: int, radius: int) -> None:
881
+ """No-op."""
882
+ pass
883
+
884
+ def draw_rectangle(self, x: int, y: int, width: int, height: int) -> None:
885
+ """No-op."""
886
+ pass
887
+
888
+ def draw_line(self, x1: int, y1: int, x2: int, y2: int) -> None:
889
+ """No-op."""
890
+ pass
891
+
892
+ def draw_jpeg(self, jpeg_data: bytes, x: int, y: int, width: int, height: int) -> None:
893
+ """No-op."""
894
+ pass
895
+
896
+
897
+ # Singleton instance
898
+ _NO_OP_LAYER_CANVAS = _NoOpLayerCanvas()
899
+
900
+
901
+ class _NoOpStageWriter(IStageWriter):
902
+ """No-op stage writer that discards all graphics operations."""
903
+
904
+ @property
905
+ def frame_id(self) -> int:
906
+ """The frame ID."""
907
+ return 0
908
+
909
+ def __getitem__(self, layer_id: int) -> ILayerCanvas:
910
+ """Returns no-op layer canvas."""
911
+ return _NO_OP_LAYER_CANVAS
912
+
913
+ def layer(self, layer_id: int) -> ILayerCanvas:
914
+ """Returns no-op layer canvas."""
915
+ return _NO_OP_LAYER_CANVAS
916
+
917
+ def close(self) -> None:
918
+ """No-op close."""
919
+ pass
920
+
921
+ def __enter__(self) -> _NoOpStageWriter:
922
+ """Context manager entry."""
923
+ return self
924
+
925
+ def __exit__(self, exc_type: object, exc_val: object, exc_tb: object) -> None:
926
+ """Context manager exit."""
927
+ pass
928
+
929
+
930
+ # Singleton instance
931
+ _NO_OP_STAGE_WRITER = _NoOpStageWriter()
932
+
933
+
934
+ class _NullStageSink(IStageSink):
935
+ """Null stage sink that creates no-op writers."""
936
+
937
+ def create_writer(self, frame_id: int) -> IStageWriter:
938
+ """Create a no-op writer."""
939
+ return _NO_OP_STAGE_WRITER
940
+
941
+ def close(self) -> None:
942
+ """No-op close."""
943
+ pass
@@ -27,6 +27,7 @@ SESSION_ID_ENV_VAR = "SessionId"
27
27
  SEGMENTATION_SINK_URL_ENV = "SEGMENTATION_SINK_URL"
28
28
  KEYPOINTS_SINK_URL_ENV = "KEYPOINTS_SINK_URL"
29
29
  ACTIONS_SINK_URL_ENV = "ACTIONS_SINK_URL"
30
+ GRAPHICS_SINK_URL_ENV = "GRAPHICS_SINK_URL"
30
31
 
31
32
 
32
33
  def parse_session_id(session_id: str) -> uuid.UUID:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rocket-welder-sdk
3
- Version: 1.1.44
3
+ Version: 1.1.46
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=r2zUZzUMZuAPUy5Sat5EWaxeocIjRbdqBDoC1i0C89w,3413
1
+ rocket_welder_sdk/__init__.py,sha256=5hcsNb0zu8dtRHD9sgCAi4YbWJe-1g6cl9jSuLQZk_U,3889
2
2
  rocket_welder_sdk/binary_frame_reader.py,sha256=5IyYO7yv07gLpQ9Toyw1zLkTrnqHLjxIeMVRn8B40-E,6270
3
3
  rocket_welder_sdk/binary_frame_writer.py,sha256=2-VEJNHw0fL30TXsCBHyhHltvgx7KUahmbamwdSU8sw,6658
4
4
  rocket_welder_sdk/bytes_size.py,sha256=Myl29-wyWCIYdbMmgaxXebT8Dz8_Fwcr3fnfaNW81P0,7463
@@ -12,16 +12,22 @@ rocket_welder_sdk/keypoints_protocol.py,sha256=kN8ok6Ptpgl4txoQE9DpKhMoI7zr73vTw
12
12
  rocket_welder_sdk/opencv_controller.py,sha256=MDM6_yFBB9BaMa5jnZRqw7xZZB-WuLr7EPrrfHQ2DK4,9905
13
13
  rocket_welder_sdk/periodic_timer.py,sha256=hnObybmrnf3J47QrNKJhYAytLKwria016123NvPRfQ0,9369
14
14
  rocket_welder_sdk/py.typed,sha256=0cXFZXmes4Y-vnl4lO3HtyyyWaFNw85B7tJdFeCtHDc,67
15
- rocket_welder_sdk/rocket_welder_client.py,sha256=VqxP-GkJKCZCjGZq2tVJ7v5yrh-ztXxlF3CT__818vg,23384
15
+ rocket_welder_sdk/rocket_welder_client.py,sha256=4jfusvxMxAU5j2NXiOhYzgWEC1VNFFk_XXv7QEvwmSU,34481
16
16
  rocket_welder_sdk/segmentation_result.py,sha256=b3xpv6AZyWzm924cd1RfXwCuEwdkPL5TUA0gzT3HpBA,29153
17
- rocket_welder_sdk/session_id.py,sha256=9GM4T6xmcNxR9gxZnDUlQGviNd3x3hT71q8y85XtH6g,1884
17
+ rocket_welder_sdk/session_id.py,sha256=YgnDwmdOcdJTXIObjkrzIkxU2gbMzNko1h1ms4lNIfU,1928
18
18
  rocket_welder_sdk/varint.py,sha256=SmffemQCXToRzs3lb7hWQWDY7NmKv4XG_Wb0oeMrb_I,5058
19
19
  rocket_welder_sdk/external_controls/__init__.py,sha256=ldOLGhLLS5BQL8m4VKFYV0SvsNNlV2tghlc7rkqadU8,699
20
20
  rocket_welder_sdk/external_controls/contracts.py,sha256=3DU6pdpteN50gF2fsS7C2279dGjDa0tZLrLntkBa2LM,2607
21
21
  rocket_welder_sdk/external_controls/contracts_old.py,sha256=XWriuXJZu5caTSS0bcTIOZcKnj-IRCm96voA4gqLBfU,2980
22
+ rocket_welder_sdk/graphics/__init__.py,sha256=4sKaqeu391WfVX1c_TDxAbucy7OJF8Aw8CG77NeggFA,1230
23
+ rocket_welder_sdk/graphics/layer_canvas.py,sha256=FcgrrCaI-2XlVOs4qYTGvpJQdVw_NP2V7D4a1LgLtS4,4580
24
+ rocket_welder_sdk/graphics/protocol.py,sha256=57GOx9rlKGojm7jnXdM2t3bpa4Ykii1o3wQtQ5IO-Hs,1357
25
+ rocket_welder_sdk/graphics/rgb_color.py,sha256=do6y362CTROiLMqbQwdvJF07L8wMWRv3n7-PVWP-Flk,3497
26
+ rocket_welder_sdk/graphics/stage.py,sha256=2hgkKGCxLxcZ64cHBKgxxFHSZOlLue236x5f43cmYk0,15538
27
+ rocket_welder_sdk/graphics/vector_graphics_encoder.py,sha256=lD3cIOAVL_JvKZayIQ_TaQ5fa8S6d9Q45C91PubHMbk,16483
22
28
  rocket_welder_sdk/high_level/__init__.py,sha256=OKbI3l0PFo1Cb_v0kbv16Wr05urz8heVGps0dJcTcG4,1507
23
29
  rocket_welder_sdk/high_level/client.py,sha256=rVnnrn68PEvc68p5acuOBZfEjobWWed8XcssTRzxNr8,11502
24
- rocket_welder_sdk/high_level/connection_strings.py,sha256=3EpFafyrmX_QNhs2nPscC63EMg5ikscvthu-0C6xC1c,9861
30
+ rocket_welder_sdk/high_level/connection_strings.py,sha256=1Hp72V5qDngHGXyjBRFMckz365BMpGVjb3PMSGvCtow,12531
25
31
  rocket_welder_sdk/high_level/data_context.py,sha256=SXJvDpDBFi8Lm4XqSRSHK7YUUHuugXGo4ZRCb6_z5l0,4833
26
32
  rocket_welder_sdk/high_level/frame_sink_factory.py,sha256=tLhMV_qnY-ZUtffIzhycM9znNjYguRumba4vphpNx7E,3493
27
33
  rocket_welder_sdk/high_level/schema.py,sha256=2Vv0rDwahtGswWB_ceaCdc7JDtmbkx4wE2jQePzeTpU,5367
@@ -39,7 +45,7 @@ rocket_welder_sdk/ui/icons.py,sha256=DcDklZkPmiEzlOD4IR7VTJOtGPCuuh_OM_WN7ScghWE
39
45
  rocket_welder_sdk/ui/ui_events_projection.py,sha256=siiNhjLEBOPfTKw1ZhOPGkwIN5rLDH7V9VCZTNrhEtQ,7836
40
46
  rocket_welder_sdk/ui/ui_service.py,sha256=uRdpyJGoCQmtOli_HKSrxLwhZYG-XRuHIYdkmFz1zNk,12026
41
47
  rocket_welder_sdk/ui/value_types.py,sha256=f7OA_9zgXEDPoITc8v8SfAR23I4XeFhE3E2_GcAbR6k,1616
42
- rocket_welder_sdk-1.1.44.dist-info/METADATA,sha256=XszsJzlnvEQCiPGYl-QxGK6TCTEYmWvi0AzvlHOqYKA,24739
43
- rocket_welder_sdk-1.1.44.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
- rocket_welder_sdk-1.1.44.dist-info/top_level.txt,sha256=2iZvBjnwVCUW-uDE23-eJld5PZ9-mlPI69QiXM5IrTA,18
45
- rocket_welder_sdk-1.1.44.dist-info/RECORD,,
48
+ rocket_welder_sdk-1.1.46.dist-info/METADATA,sha256=SxDcR5ndRmpZSNO9fWlsVAns7NJ6h4aJCxlkl2Bq8ZA,24739
49
+ rocket_welder_sdk-1.1.46.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
50
+ rocket_welder_sdk-1.1.46.dist-info/top_level.txt,sha256=2iZvBjnwVCUW-uDE23-eJld5PZ9-mlPI69QiXM5IrTA,18
51
+ rocket_welder_sdk-1.1.46.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5