spatialdds 0.7.1__tar.gz → 0.7.2__tar.gz

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 (245) hide show
  1. {spatialdds-0.7.1 → spatialdds-0.7.2}/PKG-INFO +12 -2
  2. {spatialdds-0.7.1 → spatialdds-0.7.2}/README.md +11 -1
  3. {spatialdds-0.7.1 → spatialdds-0.7.2}/pyproject.toml +1 -1
  4. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/__init__.py +1 -1
  5. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/openapi.html +1 -1
  6. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/openapi.yaml +1 -1
  7. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/__init__.py +2 -2
  8. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/_participant.py +19 -0
  9. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/codec.py +155 -5
  10. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/record.py +4 -1
  11. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds.egg-info/PKG-INFO +12 -2
  12. {spatialdds-0.7.1 → spatialdds-0.7.2}/setup.cfg +0 -0
  13. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/anchors.idl +0 -0
  14. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/argeo.idl +0 -0
  15. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/common.idl +0 -0
  16. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/core.idl +0 -0
  17. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/discovery.idl +0 -0
  18. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/events.idl +0 -0
  19. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/lidar.idl +0 -0
  20. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/mapping.idl +0 -0
  21. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/provisional/owm.idl +0 -0
  22. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/provisional/radio.idl +0 -0
  23. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/provisional/rf_beam.idl +0 -0
  24. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/rad.idl +0 -0
  25. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/semantics.idl +0 -0
  26. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/slam_frontend.idl +0 -0
  27. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/types.idl +0 -0
  28. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/vio.idl +0 -0
  29. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/idl/vision.idl +0 -0
  30. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/registry.json +0 -0
  31. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/builtin_Time.json +0 -0
  32. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_anchors_AnchorDelta.json +0 -0
  33. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_anchors_AnchorEntry.json +0 -0
  34. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSet.json +0 -0
  35. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSetRequest.json +0 -0
  36. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSetResponse.json +0 -0
  37. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_argeo_NodeGeo.json +0 -0
  38. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_argeo_QualityRequirements.json +0 -0
  39. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_argeo_VpsRequest.json +0 -0
  40. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_argeo_VpsResponse.json +0 -0
  41. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_common_AssetRef.json +0 -0
  42. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_common_FrameRef.json +0 -0
  43. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_common_KV.json +0 -0
  44. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_common_MetaKV.json +0 -0
  45. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_common_Vec2.json +0 -0
  46. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_Aabb3.json +0 -0
  47. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_BlobChunk.json +0 -0
  48. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_BlobRef.json +0 -0
  49. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_ComponentRef.json +0 -0
  50. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_Edge.json +0 -0
  51. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_EntityBinding.json +0 -0
  52. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_FrameTransform.json +0 -0
  53. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_FramedPose.json +0 -0
  54. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_GeoAnchor.json +0 -0
  55. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_GeoPose.json +0 -0
  56. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_NavSatStatus.json +0 -0
  57. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_Node.json +0 -0
  58. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_PlannedTrajectory.json +0 -0
  59. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_PlannedWaypoint.json +0 -0
  60. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_PoseSE3.json +0 -0
  61. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_SnapshotRequest.json +0 -0
  62. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_SnapshotResponse.json +0 -0
  63. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_TileKey.json +0 -0
  64. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_TileMeta.json +0 -0
  65. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_core_TilePatch.json +0 -0
  66. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_Announce.json +0 -0
  67. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_Capabilities.json +0 -0
  68. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_ContentAnnounce.json +0 -0
  69. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_CoverageElement.json +0 -0
  70. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_CoverageFilter.json +0 -0
  71. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_CoverageHint.json +0 -0
  72. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_CoverageQuery.json +0 -0
  73. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_CoverageResponse.json +0 -0
  74. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_Depart.json +0 -0
  75. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_KV.json +0 -0
  76. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_ProfileSupport.json +0 -0
  77. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_ServiceSummary.json +0 -0
  78. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_TopicMeta.json +0 -0
  79. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_Transform.json +0 -0
  80. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_disco_ValidityWindow.json +0 -0
  81. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_events_CrossingLine.json +0 -0
  82. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_events_SpatialEvent.json +0 -0
  83. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_events_SpatialZone.json +0 -0
  84. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_events_ZoneState.json +0 -0
  85. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_mapping_Edge.json +0 -0
  86. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_mapping_MapAlignment.json +0 -0
  87. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_mapping_MapEvent.json +0 -0
  88. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_mapping_MapMeta.json +0 -0
  89. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_mapping_MapQuality.json +0 -0
  90. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_owm_Entity.json +0 -0
  91. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_owm_ModelCommand.json +0 -0
  92. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_owm_ModelPose.json +0 -0
  93. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_semantics_Detection2D.json +0 -0
  94. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_semantics_Detection2DSet.json +0 -0
  95. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_semantics_Detection3D.json +0 -0
  96. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_semantics_Detection3DSet.json +0 -0
  97. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_semantics_FusedTrack.json +0 -0
  98. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_semantics_FusedTrackSet.json +0 -0
  99. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_semantics_Keypoint3D.json +0 -0
  100. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_semantics_KeypointLink.json +0 -0
  101. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_common_Axis.json +0 -0
  102. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_common_FrameHeader.json +0 -0
  103. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_common_FrameQuality.json +0 -0
  104. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_common_Linspace.json +0 -0
  105. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_common_ROI.json +0 -0
  106. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_common_ROIReply.json +0 -0
  107. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_common_ROIRequest.json +0 -0
  108. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_common_StreamMeta.json +0 -0
  109. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarDetection.json +0 -0
  110. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarDetectionSet.json +0 -0
  111. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarFrame.json +0 -0
  112. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarMeta.json +0 -0
  113. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadDetection.json +0 -0
  114. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadDetectionSet.json +0 -0
  115. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadSensorMeta.json +0 -0
  116. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadTensorFrame.json +0 -0
  117. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadTensorMeta.json +0 -0
  118. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioObservation.json +0 -0
  119. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioScan.json +0 -0
  120. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioSensorMeta.json +0 -0
  121. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamArraySet.json +0 -0
  122. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamFrame.json +0 -0
  123. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamMeta.json +0 -0
  124. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_CamIntrinsics.json +0 -0
  125. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_Keypoint2D.json +0 -0
  126. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_Track2D.json +0 -0
  127. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionDetections.json +0 -0
  128. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionFrame.json +0 -0
  129. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionMeta.json +0 -0
  130. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_CameraInfo.json +0 -0
  131. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_Feature2D.json +0 -0
  132. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_FeatureMatch.json +0 -0
  133. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_KeyframeFeatures.json +0 -0
  134. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_Landmark.json +0 -0
  135. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_MatchSet.json +0 -0
  136. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_TrackObs.json +0 -0
  137. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_Tracklet.json +0 -0
  138. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_vio_FusedState.json +0 -0
  139. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_vio_ImuInfo.json +0 -0
  140. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_vio_ImuSample.json +0 -0
  141. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_vio_MagnetometerSample.json +0 -0
  142. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/schemas/spatial_vio_SensorFusionSample.json +0 -0
  143. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/artifacts/serializer_tables.json +0 -0
  144. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/canonical.py +0 -0
  145. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/canonjson.py +0 -0
  146. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/client.py +0 -0
  147. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/_extra.py +0 -0
  148. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/blob.py +0 -0
  149. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/qos.py +0 -0
  150. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/registry.py +0 -0
  151. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/__init__.py +0 -0
  152. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/_field_aliases.py +0 -0
  153. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/builtin/__init__.py +0 -0
  154. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/builtin/_types.py +0 -0
  155. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/__init__.py +0 -0
  156. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/anchors/__init__.py +0 -0
  157. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/anchors/_anchors.py +0 -0
  158. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/argeo/__init__.py +0 -0
  159. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/argeo/_argeo.py +0 -0
  160. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/common/__init__.py +0 -0
  161. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/common/_types.py +0 -0
  162. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/core/GnssService/__init__.py +0 -0
  163. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/core/GnssService/_core.py +0 -0
  164. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/core/__init__.py +0 -0
  165. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/core/_core.py +0 -0
  166. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/disco/__init__.py +0 -0
  167. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/disco/_discovery.py +0 -0
  168. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/__init__.py +0 -0
  169. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/_events.py +0 -0
  170. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/enums/__init__.py +0 -0
  171. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/enums/crossing_direction_enum/__init__.py +0 -0
  172. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/enums/crossing_direction_enum/_events.py +0 -0
  173. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/enums/event_state_enum/__init__.py +0 -0
  174. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/enums/event_state_enum/_events.py +0 -0
  175. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/enums/event_type_enum/__init__.py +0 -0
  176. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/enums/event_type_enum/_events.py +0 -0
  177. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/enums/severity_enum/__init__.py +0 -0
  178. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/enums/severity_enum/_events.py +0 -0
  179. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/enums/zone_kind_enum/__init__.py +0 -0
  180. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/events/enums/zone_kind_enum/_events.py +0 -0
  181. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/__init__.py +0 -0
  182. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/_mapping.py +0 -0
  183. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/enums/__init__.py +0 -0
  184. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/enums/alignment_method/__init__.py +0 -0
  185. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/enums/alignment_method/_mapping.py +0 -0
  186. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/enums/edge_type/__init__.py +0 -0
  187. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/enums/edge_type/_mapping.py +0 -0
  188. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/enums/map_event_kind/__init__.py +0 -0
  189. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/enums/map_event_kind/_mapping.py +0 -0
  190. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/enums/map_kind/__init__.py +0 -0
  191. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/enums/map_kind/_mapping.py +0 -0
  192. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/enums/map_status/__init__.py +0 -0
  193. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/mapping/enums/map_status/_mapping.py +0 -0
  194. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/owm/__init__.py +0 -0
  195. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/owm/_owm.py +0 -0
  196. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/semantics/__init__.py +0 -0
  197. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/semantics/_semantics.py +0 -0
  198. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/__init__.py +0 -0
  199. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/common/__init__.py +0 -0
  200. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/common/_common.py +0 -0
  201. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/lidar/__init__.py +0 -0
  202. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/lidar/_lidar.py +0 -0
  203. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/rad/__init__.py +0 -0
  204. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/rad/_rad.py +0 -0
  205. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/radio/__init__.py +0 -0
  206. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/radio/_radio.py +0 -0
  207. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/rf_beam/__init__.py +0 -0
  208. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/rf_beam/_rf_beam.py +0 -0
  209. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/vision/__init__.py +0 -0
  210. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/sensing/vision/_vision.py +0 -0
  211. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/slam_frontend/__init__.py +0 -0
  212. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/slam_frontend/_slam_frontend.py +0 -0
  213. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/vio/__init__.py +0 -0
  214. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/dds/types/spatial/vio/_vio.py +0 -0
  215. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/demo/assets/duck.gltf +0 -0
  216. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/demo/assets/fountain-label.txt +0 -0
  217. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/demo/assets/fountain-marker.gltf +0 -0
  218. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/demo/fountain-anchors.mcap +0 -0
  219. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/demo/manifests/content-fountain-label.json +0 -0
  220. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/demo/manifests/content-fountain-marker.json +0 -0
  221. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/errors.py +0 -0
  222. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/events.py +0 -0
  223. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/frames.py +0 -0
  224. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/journal.py +0 -0
  225. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/recency.py +0 -0
  226. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/records.py +0 -0
  227. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/serve.py +0 -0
  228. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/__init__.py +0 -0
  229. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/commands.py +0 -0
  230. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/gateway.py +0 -0
  231. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/gw_http.py +0 -0
  232. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/idlmodel.py +0 -0
  233. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/limits.py +0 -0
  234. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/mcapmeta.py +0 -0
  235. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/pin.py +0 -0
  236. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/publish.py +0 -0
  237. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/tenancy.py +0 -0
  238. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/webjson.py +0 -0
  239. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/server/xcdr2.py +0 -0
  240. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds/tokens.py +0 -0
  241. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds.egg-info/SOURCES.txt +0 -0
  242. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds.egg-info/dependency_links.txt +0 -0
  243. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds.egg-info/entry_points.txt +0 -0
  244. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds.egg-info/requires.txt +0 -0
  245. {spatialdds-0.7.1 → spatialdds-0.7.2}/spatialdds.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spatialdds
3
- Version: 0.7.1
3
+ Version: 0.7.2
4
4
  Summary: SpatialDDS for programs: a client for the web binding (Appendix N), a native DDS participant, and the reference registry behind one command.
5
5
  Author: Open AR Cloud
6
6
  License: Apache-2.0
@@ -152,6 +152,10 @@ scene:
152
152
  never speaks as the asserter.
153
153
  - **`sd.dds.class_for(name)`** is the generated class for a registered type
154
154
  name, a well-known message or a dotted identity.
155
+ - **`sd.dds.extend(name, cls, idl)`** registers a deployment's own type, with
156
+ the IDL it was generated from. After that it converts, keys, records and
157
+ opens by name like a pinned type, and validation checks N.1
158
+ representability, since it has no published schema.
155
159
 
156
160
  `Sample.data` is the typed sample (`sd.dds.types` carries every type in the
157
161
  pinned IDL). `sd.dds.to_json(sample)` is its N.1 form, produced by the gateway's
@@ -594,6 +598,12 @@ explicitly was tried first and is what missed two paths.
594
598
 
595
599
  If your clients are not browsers, nothing here changes anything for you.
596
600
 
601
+ ## New in 0.7.2: a deployment's own types
602
+
603
+ `sd.dds.extend(name, cls, idl)` brings a deployment's own documented type
604
+ into the native layer: N.1 conversion, its key, `class_for`, the recording
605
+ tap, and opening it by name. Additive, as 0.7.1 was.
606
+
597
607
  ## New in 0.7.1: for programs that own their loop
598
608
 
599
609
  Everything SpatialDDS-demo's adoption found missing, and nothing removed:
@@ -649,7 +659,7 @@ Two changes may need a line of yours:
649
659
  The security fixes, the limits table and the details are in the
650
660
  [changelog](https://github.com/OpenArCloud/spatialdds-py/blob/main/lib/spatialdds/CHANGELOG.md).
651
661
 
652
- ## Not in 0.7.1
662
+ ## Not in 0.7.2
653
663
 
654
664
  Stated so nobody waits for them:
655
665
 
@@ -124,6 +124,10 @@ scene:
124
124
  never speaks as the asserter.
125
125
  - **`sd.dds.class_for(name)`** is the generated class for a registered type
126
126
  name, a well-known message or a dotted identity.
127
+ - **`sd.dds.extend(name, cls, idl)`** registers a deployment's own type, with
128
+ the IDL it was generated from. After that it converts, keys, records and
129
+ opens by name like a pinned type, and validation checks N.1
130
+ representability, since it has no published schema.
127
131
 
128
132
  `Sample.data` is the typed sample (`sd.dds.types` carries every type in the
129
133
  pinned IDL). `sd.dds.to_json(sample)` is its N.1 form, produced by the gateway's
@@ -566,6 +570,12 @@ explicitly was tried first and is what missed two paths.
566
570
 
567
571
  If your clients are not browsers, nothing here changes anything for you.
568
572
 
573
+ ## New in 0.7.2: a deployment's own types
574
+
575
+ `sd.dds.extend(name, cls, idl)` brings a deployment's own documented type
576
+ into the native layer: N.1 conversion, its key, `class_for`, the recording
577
+ tap, and opening it by name. Additive, as 0.7.1 was.
578
+
569
579
  ## New in 0.7.1: for programs that own their loop
570
580
 
571
581
  Everything SpatialDDS-demo's adoption found missing, and nothing removed:
@@ -621,7 +631,7 @@ Two changes may need a line of yours:
621
631
  The security fixes, the limits table and the details are in the
622
632
  [changelog](https://github.com/OpenArCloud/spatialdds-py/blob/main/lib/spatialdds/CHANGELOG.md).
623
633
 
624
- ## Not in 0.7.1
634
+ ## Not in 0.7.2
625
635
 
626
636
  Stated so nobody waits for them:
627
637
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "spatialdds"
7
- version = "0.7.1"
7
+ version = "0.7.2"
8
8
  description = "SpatialDDS for programs: a client for the web binding (Appendix N), a native DDS participant, and the reference registry behind one command."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -41,7 +41,7 @@ __all__ = [
41
41
  "participant", "MissingExtra", "dds", "events", "frames", "Recency",
42
42
  ]
43
43
 
44
- __version__ = "0.7.1"
44
+ __version__ = "0.7.2"
45
45
  #: The SpatialDDS-spec commit whose Appendix N and generated artifacts this
46
46
  #: package implements. Package versions and specification versions move
47
47
  #: independently; this is the one that says what the wire looks like.
@@ -14,4 +14,4 @@ border-bottom:1px solid var(--line)}p{margin:.35rem 0}.mut,.sum .auth{color:
14
14
  var(--mut)}.auth{font-size:.85rem;margin-left:.4rem}.v{display:inline-block;
15
15
  min-width:4.2rem;font:600 12px ui-monospace,monospace;letter-spacing:.04em;
16
16
  color:var(--acc)}.codes{font:12px ui-monospace,monospace;color:var(--mut)}
17
- .s{margin-right:.5rem}.s4,.s5{color:#b5482c}a{color:var(--acc)}</style></head><body><main><h1>SpatialDDS web binding (spatialdds-py)</h1><p class=mut>Version 0.7.1 · OpenAPI 3.1.0 · generated, never hand-written · <a href='openapi'>openapi.yaml</a></p><p>Generated by <code>tools/gen_openapi.py</code> from the gateway&#x27;s own tables and the published JSON Schemas; never edited by hand. Reads are open; writes take a bearer token scoped to scenes. The WebSocket streams (N.5) are described on each collection path, not modelled.</p><h2>Operations</h2><section id="search"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/search</code></h3><p class="sum">Services near a geohash (§8.2.3 manifests) <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="searchPost"><h3><span class="v post">POST</span> <code>/.well-known/spatialdds/search</code></h3><p class="sum">The same search, as a POST body <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span></p></section><section id="listSchemas"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/schemas</code></h3><p class="sum">The published JSON Schemas, by type <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="getSchema"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/schemas/{type}</code></h3><p class="sum"> <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="bootstrap"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/bootstrap</code></h3><p class="sum">DDS-join material (N.2); optional <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="resolverMetadata"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/resolver</code></h3><p class="sum">§7.5.2 resolver metadata <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="openapi"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/openapi</code></h3><p class="sum">This document <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="openapiPage"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/openapi.html</code></h3><p class="sum">This document as a static reference page <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="resolve"><h3><span class="v get">GET</span> <code>/spatialdds/resolve</code></h3><p class="sum">Resolve a URI to its manifest (§7.5.2) <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">400</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="putManifest"><h3><span class="v put">PUT</span> <code>/spatialdds/resolve</code></h3><p class="sum">Publish a manifest, keyed by its own <code>id</code> <span class="auth">token</span></p><p>The <code>uri</code> parameter is not used; the body&#x27;s <code>id</code> is the key. Its scene segment is the lane. **Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>).</p><p class="codes"><span class="s s2">200</span> <span class="s s2">201</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span> <span class="s s5">503</span></p></section><section id="withdrawManifest"><h3><span class="v delete">DELETE</span> <code>/spatialdds/resolve</code></h3><p class="sum">Withdraw a manifest; <code>resolve</code> then answers 404 <span class="auth">token</span></p><p>Owner-checked by the URI&#x27;s scene segment. **Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>).</p><p class="codes"><span class="s s2">204</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">404</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="getAsset"><h3><span class="v get">GET</span> <code>/assets/{name}</code></h3><p class="sum">Asset bytes this endpoint hosts (implementation-defined) <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="listAnnounce"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/announce/v1</code></h3><p class="sum">Every spatial.disco.Announce instance in the latched set <span class="auth">open</span></p><p>**The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="commandAnnounce"><h3><span class="v post">POST</span> <code>/{scene}/{stream}/announce/v1</code></h3><p class="sum">An N.6 command addressed through the announce lane <span class="auth">token</span></p><p>Accepted only on a lane whose topic advertises <code>accepts_commands</code>; otherwise <code>405</code>. **Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch.</p><p class="codes"><span class="s s2">202</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">409</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span></p></section><section id="getAnnounce"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/announce/v1/{key}</code></h3><p class="sum">One spatial.disco.Announce instance <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="putAnnounce"><h3><span class="v put">PUT</span> <code>/{scene}/{stream}/announce/v1/{key}</code></h3><p class="sum">Publish or replace a spatial.disco.Announce <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch. The body&#x27;s key must equal the URL&#x27;s. <code>If-Match</code> is honoured when present.</p><p class="codes"><span class="s s2">200</span> <span class="s s2">201</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">412</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span> <span class="s s5">503</span></p></section><section id="withdrawAnnounce"><h3><span class="v delete">DELETE</span> <code>/{scene}/{stream}/announce/v1/{key}</code></h3><p class="sum">Withdraw (dispose) a spatial.disco.Announce <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). The dispose streams on the collection&#x27;s WebSocket with its <code>reason</code>.</p><p class="codes"><span class="s s2">204</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">404</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="listContentAnnounce"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/content_announce/v1</code></h3><p class="sum">Every spatial.disco.ContentAnnounce instance in the latched set <span class="auth">open</span></p><p>**The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="commandContentAnnounce"><h3><span class="v post">POST</span> <code>/{scene}/{stream}/content_announce/v1</code></h3><p class="sum">An N.6 command addressed through the content_announce lane <span class="auth">token</span></p><p>Accepted only on a lane whose topic advertises <code>accepts_commands</code>; otherwise <code>405</code>. **Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch.</p><p class="codes"><span class="s s2">202</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">409</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span></p></section><section id="getContentAnnounce"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/content_announce/v1/{key}</code></h3><p class="sum">One spatial.disco.ContentAnnounce instance <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="putContentAnnounce"><h3><span class="v put">PUT</span> <code>/{scene}/{stream}/content_announce/v1/{key}</code></h3><p class="sum">Publish or replace a spatial.disco.ContentAnnounce <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch. The body&#x27;s key must equal the URL&#x27;s. <code>If-Match</code> is honoured when present.</p><p class="codes"><span class="s s2">200</span> <span class="s s2">201</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">412</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span> <span class="s s5">503</span></p></section><section id="withdrawContentAnnounce"><h3><span class="v delete">DELETE</span> <code>/{scene}/{stream}/content_announce/v1/{key}</code></h3><p class="sum">Withdraw (dispose) a spatial.disco.ContentAnnounce <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). The dispose streams on the collection&#x27;s WebSocket with its <code>reason</code>.</p><p class="codes"><span class="s s2">204</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">404</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="listGeoAnchor"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/geo_anchor/v1</code></h3><p class="sum">Every spatial.core.GeoAnchor instance in the latched set <span class="auth">open</span></p><p>**The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="commandGeoAnchor"><h3><span class="v post">POST</span> <code>/{scene}/{stream}/geo_anchor/v1</code></h3><p class="sum">An N.6 command addressed through the geo_anchor lane <span class="auth">token</span></p><p>Accepted only on a lane whose topic advertises <code>accepts_commands</code>; otherwise <code>405</code>. **Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch.</p><p class="codes"><span class="s s2">202</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">409</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span></p></section><section id="getGeoAnchor"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/geo_anchor/v1/{key}</code></h3><p class="sum">One spatial.core.GeoAnchor instance <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="putGeoAnchor"><h3><span class="v put">PUT</span> <code>/{scene}/{stream}/geo_anchor/v1/{key}</code></h3><p class="sum">Publish or replace a spatial.core.GeoAnchor <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch. The body&#x27;s key must equal the URL&#x27;s. <code>If-Match</code> is honoured when present.</p><p class="codes"><span class="s s2">200</span> <span class="s s2">201</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">412</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span> <span class="s s5">503</span></p></section><section id="withdrawGeoAnchor"><h3><span class="v delete">DELETE</span> <code>/{scene}/{stream}/geo_anchor/v1/{key}</code></h3><p class="sum">Withdraw (dispose) a spatial.core.GeoAnchor <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). The dispose streams on the collection&#x27;s WebSocket with its <code>reason</code>.</p><p class="codes"><span class="s s2">204</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">404</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="listInstances"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/{type}/{version}</code></h3><p class="sum">Any other served topic, read-only <span class="auth">token for operator-scoped</span></p><p>Latched types answer with the latched set; streamed types with the replayed window. Public or operator-scoped per the type: <code>spatial.core.FrameTransform</code> latched public, <code>spatial.events.CrossingLine</code> latched public, <code>spatial.events.SpatialEvent</code> stream bearer, <code>spatial.events.SpatialZone</code> latched public, <code>spatial.owm.Entity</code> latched bearer, <code>spatial.owm.ModelPose</code> stream bearer, <code>spatial.semantics.Detection2DSet</code> stream bearer, <code>spatial.semantics.Detection3DSet</code> stream bearer, <code>spatial.semantics.FusedTrackSet</code> stream bearer. **The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">401</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="listWellKnownInstances"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/{stream}/{type}/{version}</code></h3><p class="sum">A four-segment topic&#x27;s collection <span class="auth">token for operator-scoped</span></p><p>A four-segment topic (<code>spatialdds/&lt;stream&gt;/&lt;type&gt;/&lt;version&gt;</code>, no scene), such as the discovery announce lane, served exactly as a scene-scoped collection is: latched set, <code>ETag</code>, <code>304</code>, the same access classes, and the N.5 stream by upgrading the same path. Read-only: a topic with no scene is in no lane. **The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">401</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="getWellKnownInstance"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/{stream}/{type}/{version}/{key}</code></h3><p class="sum">One instance of a four-segment topic <span class="auth">token for operator-scoped</span></p><p>A four-segment topic (<code>spatialdds/&lt;stream&gt;/&lt;type&gt;/&lt;version&gt;</code>, no scene), such as the discovery announce lane, served exactly as a scene-scoped collection is: latched set, <code>ETag</code>, <code>304</code>, the same access classes, and the N.5 stream by upgrading the same path. Read-only: a topic with no scene is in no lane. </p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">401</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><h2>Schemas</h2><p class=mut>115 components, from the published JSON Schemas at <code>/.well-known/spatialdds/schemas</code>.</p></main></body></html>
17
+ .s{margin-right:.5rem}.s4,.s5{color:#b5482c}a{color:var(--acc)}</style></head><body><main><h1>SpatialDDS web binding (spatialdds-py)</h1><p class=mut>Version 0.7.2 · OpenAPI 3.1.0 · generated, never hand-written · <a href='openapi'>openapi.yaml</a></p><p>Generated by <code>tools/gen_openapi.py</code> from the gateway&#x27;s own tables and the published JSON Schemas; never edited by hand. Reads are open; writes take a bearer token scoped to scenes. The WebSocket streams (N.5) are described on each collection path, not modelled.</p><h2>Operations</h2><section id="search"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/search</code></h3><p class="sum">Services near a geohash (§8.2.3 manifests) <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="searchPost"><h3><span class="v post">POST</span> <code>/.well-known/spatialdds/search</code></h3><p class="sum">The same search, as a POST body <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span></p></section><section id="listSchemas"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/schemas</code></h3><p class="sum">The published JSON Schemas, by type <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="getSchema"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/schemas/{type}</code></h3><p class="sum"> <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="bootstrap"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/bootstrap</code></h3><p class="sum">DDS-join material (N.2); optional <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="resolverMetadata"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/resolver</code></h3><p class="sum">§7.5.2 resolver metadata <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="openapi"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/openapi</code></h3><p class="sum">This document <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="openapiPage"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/openapi.html</code></h3><p class="sum">This document as a static reference page <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="resolve"><h3><span class="v get">GET</span> <code>/spatialdds/resolve</code></h3><p class="sum">Resolve a URI to its manifest (§7.5.2) <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">400</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="putManifest"><h3><span class="v put">PUT</span> <code>/spatialdds/resolve</code></h3><p class="sum">Publish a manifest, keyed by its own <code>id</code> <span class="auth">token</span></p><p>The <code>uri</code> parameter is not used; the body&#x27;s <code>id</code> is the key. Its scene segment is the lane. **Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>).</p><p class="codes"><span class="s s2">200</span> <span class="s s2">201</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span> <span class="s s5">503</span></p></section><section id="withdrawManifest"><h3><span class="v delete">DELETE</span> <code>/spatialdds/resolve</code></h3><p class="sum">Withdraw a manifest; <code>resolve</code> then answers 404 <span class="auth">token</span></p><p>Owner-checked by the URI&#x27;s scene segment. **Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>).</p><p class="codes"><span class="s s2">204</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">404</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="getAsset"><h3><span class="v get">GET</span> <code>/assets/{name}</code></h3><p class="sum">Asset bytes this endpoint hosts (implementation-defined) <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="listAnnounce"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/announce/v1</code></h3><p class="sum">Every spatial.disco.Announce instance in the latched set <span class="auth">open</span></p><p>**The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="commandAnnounce"><h3><span class="v post">POST</span> <code>/{scene}/{stream}/announce/v1</code></h3><p class="sum">An N.6 command addressed through the announce lane <span class="auth">token</span></p><p>Accepted only on a lane whose topic advertises <code>accepts_commands</code>; otherwise <code>405</code>. **Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch.</p><p class="codes"><span class="s s2">202</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">409</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span></p></section><section id="getAnnounce"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/announce/v1/{key}</code></h3><p class="sum">One spatial.disco.Announce instance <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="putAnnounce"><h3><span class="v put">PUT</span> <code>/{scene}/{stream}/announce/v1/{key}</code></h3><p class="sum">Publish or replace a spatial.disco.Announce <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch. The body&#x27;s key must equal the URL&#x27;s. <code>If-Match</code> is honoured when present.</p><p class="codes"><span class="s s2">200</span> <span class="s s2">201</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">412</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span> <span class="s s5">503</span></p></section><section id="withdrawAnnounce"><h3><span class="v delete">DELETE</span> <code>/{scene}/{stream}/announce/v1/{key}</code></h3><p class="sum">Withdraw (dispose) a spatial.disco.Announce <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). The dispose streams on the collection&#x27;s WebSocket with its <code>reason</code>.</p><p class="codes"><span class="s s2">204</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">404</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="listContentAnnounce"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/content_announce/v1</code></h3><p class="sum">Every spatial.disco.ContentAnnounce instance in the latched set <span class="auth">open</span></p><p>**The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="commandContentAnnounce"><h3><span class="v post">POST</span> <code>/{scene}/{stream}/content_announce/v1</code></h3><p class="sum">An N.6 command addressed through the content_announce lane <span class="auth">token</span></p><p>Accepted only on a lane whose topic advertises <code>accepts_commands</code>; otherwise <code>405</code>. **Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch.</p><p class="codes"><span class="s s2">202</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">409</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span></p></section><section id="getContentAnnounce"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/content_announce/v1/{key}</code></h3><p class="sum">One spatial.disco.ContentAnnounce instance <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="putContentAnnounce"><h3><span class="v put">PUT</span> <code>/{scene}/{stream}/content_announce/v1/{key}</code></h3><p class="sum">Publish or replace a spatial.disco.ContentAnnounce <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch. The body&#x27;s key must equal the URL&#x27;s. <code>If-Match</code> is honoured when present.</p><p class="codes"><span class="s s2">200</span> <span class="s s2">201</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">412</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span> <span class="s s5">503</span></p></section><section id="withdrawContentAnnounce"><h3><span class="v delete">DELETE</span> <code>/{scene}/{stream}/content_announce/v1/{key}</code></h3><p class="sum">Withdraw (dispose) a spatial.disco.ContentAnnounce <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). The dispose streams on the collection&#x27;s WebSocket with its <code>reason</code>.</p><p class="codes"><span class="s s2">204</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">404</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="listGeoAnchor"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/geo_anchor/v1</code></h3><p class="sum">Every spatial.core.GeoAnchor instance in the latched set <span class="auth">open</span></p><p>**The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="commandGeoAnchor"><h3><span class="v post">POST</span> <code>/{scene}/{stream}/geo_anchor/v1</code></h3><p class="sum">An N.6 command addressed through the geo_anchor lane <span class="auth">token</span></p><p>Accepted only on a lane whose topic advertises <code>accepts_commands</code>; otherwise <code>405</code>. **Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch.</p><p class="codes"><span class="s s2">202</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">409</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span></p></section><section id="getGeoAnchor"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/geo_anchor/v1/{key}</code></h3><p class="sum">One spatial.core.GeoAnchor instance <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="putGeoAnchor"><h3><span class="v put">PUT</span> <code>/{scene}/{stream}/geo_anchor/v1/{key}</code></h3><p class="sum">Publish or replace a spatial.core.GeoAnchor <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). Every member of the record is required: a body is a whole record, never a patch. The body&#x27;s key must equal the URL&#x27;s. <code>If-Match</code> is honoured when present.</p><p class="codes"><span class="s s2">200</span> <span class="s s2">201</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">405</span> <span class="s s4">412</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span> <span class="s s5">503</span></p></section><section id="withdrawGeoAnchor"><h3><span class="v delete">DELETE</span> <code>/{scene}/{stream}/geo_anchor/v1/{key}</code></h3><p class="sum">Withdraw (dispose) a spatial.core.GeoAnchor <span class="auth">token</span></p><p>**Writes are per lane.** The path&#x27;s first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). The dispose streams on the collection&#x27;s WebSocket with its <code>reason</code>.</p><p class="codes"><span class="s s2">204</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">404</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="listInstances"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/{type}/{version}</code></h3><p class="sum">Any other served topic, read-only <span class="auth">token for operator-scoped</span></p><p>Latched types answer with the latched set; streamed types with the replayed window. Public or operator-scoped per the type: <code>spatial.core.FrameTransform</code> latched public, <code>spatial.events.CrossingLine</code> latched public, <code>spatial.events.SpatialEvent</code> stream bearer, <code>spatial.events.SpatialZone</code> latched public, <code>spatial.owm.Entity</code> latched bearer, <code>spatial.owm.ModelPose</code> stream bearer, <code>spatial.semantics.Detection2DSet</code> stream bearer, <code>spatial.semantics.Detection3DSet</code> stream bearer, <code>spatial.semantics.FusedTrackSet</code> stream bearer. **The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">401</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="listWellKnownInstances"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/{stream}/{type}/{version}</code></h3><p class="sum">A four-segment topic&#x27;s collection <span class="auth">token for operator-scoped</span></p><p>A four-segment topic (<code>spatialdds/&lt;stream&gt;/&lt;type&gt;/&lt;version&gt;</code>, no scene), such as the discovery announce lane, served exactly as a scene-scoped collection is: latched set, <code>ETag</code>, <code>304</code>, the same access classes, and the N.5 stream by upgrading the same path. Read-only: a topic with no scene is in no lane. **The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">401</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="getWellKnownInstance"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/{stream}/{type}/{version}/{key}</code></h3><p class="sum">One instance of a four-segment topic <span class="auth">token for operator-scoped</span></p><p>A four-segment topic (<code>spatialdds/&lt;stream&gt;/&lt;type&gt;/&lt;version&gt;</code>, no scene), such as the discovery announce lane, served exactly as a scene-scoped collection is: latched set, <code>ETag</code>, <code>304</code>, the same access classes, and the N.5 stream by upgrading the same path. Read-only: a topic with no scene is in no lane. </p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">401</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><h2>Schemas</h2><p class=mut>115 components, from the published JSON Schemas at <code>/.well-known/spatialdds/schemas</code>.</p></main></body></html>
@@ -2,7 +2,7 @@
2
2
  openapi: 3.1.0
3
3
  info:
4
4
  title: SpatialDDS web binding (spatialdds-py)
5
- version: 0.7.1
5
+ version: 0.7.2
6
6
  summary: SpatialDDS 1.8 Appendix N over HTTPS, plus this endpoint's write surface.
7
7
  description: Generated by `tools/gen_openapi.py` from the gateway's own tables and the published JSON Schemas; never edited by hand. Reads are open; writes take a bearer token scoped to scenes. The WebSocket streams (N.5) are described on each collection path, not modelled.
8
8
  servers:
@@ -29,7 +29,7 @@ __all__ = [
29
29
  "AnnounceRelay", "RELAYED_BY",
30
30
  "ON_EXIT", "DOMAIN_ENV",
31
31
  "to_json", "from_json", "validate", "SchemaInvalid", "fqn_of", "key_of",
32
- "class_for",
32
+ "class_for", "extend", "Extension",
33
33
  "registry", "Profile", "RegistryError", "topic_name",
34
34
  "ANNOUNCE", "DEPART", "CONTENT", "QUERY", "COVERAGE_HINT",
35
35
  "Recorder", "chunk", "Reassembler", "CorruptChunk", "blob_ref",
@@ -51,7 +51,7 @@ _FROM = {
51
51
  "DOMAIN_ENV": "_participant",
52
52
  "to_json": "codec", "from_json": "codec", "validate": "codec",
53
53
  "SchemaInvalid": "codec", "fqn_of": "codec", "key_of": "codec",
54
- "class_for": "codec",
54
+ "class_for": "codec", "extend": "codec", "Extension": "codec",
55
55
  "Profile": "registry", "RegistryError": "registry",
56
56
  "topic_name": "registry",
57
57
  "Recorder": "record",
@@ -131,10 +131,29 @@ class _Lane:
131
131
  f"stream= would name a second one")
132
132
  return
133
133
  try:
134
+ if isinstance(type_, str) and type_ in codec.extensions():
135
+ # A deployment extension registered with `extend()`, by its
136
+ # name: the class is known, and the profile is still the
137
+ # caller's to give.
138
+ ext = codec.extensions()[type_]
139
+ if type_name not in (None, type_):
140
+ problems.append(f"{type_} is registered as {type_}; "
141
+ f"type_name={type_name!r} would rename it")
142
+ return
143
+ type_, type_name = ext.cls, type_
134
144
  if isinstance(type_, type):
135
145
  # A deployment extension: its own generated class, a name per
136
146
  # §3.3.2's pattern, and an explicit Profile.
137
147
  self.cls, self.fqn = type_, codec.fqn_of(type_)
148
+ ext = codec.extension_of(self.fqn)
149
+ if ext is not None and ext.cls is not type_:
150
+ ext = None
151
+ if ext is not None and type_name is None:
152
+ type_name = ext.type_name
153
+ elif ext is not None and type_name != ext.type_name:
154
+ problems.append(f"{type_.__name__} is registered as "
155
+ f"{ext.type_name}, not {type_name!r}")
156
+ return
138
157
  if not type_name:
139
158
  problems.append(f"{type_.__name__} is an extension type: "
140
159
  f"pass type_name= (e.g. 'myorg.depth_frame')")
@@ -23,12 +23,14 @@ from __future__ import annotations
23
23
 
24
24
  import re
25
25
  from functools import lru_cache
26
+ from dataclasses import dataclass
26
27
  from typing import Any, Dict, Optional, Type, TypeVar
27
28
 
28
29
  from ..server import idlmodel, pin, webjson, xcdr2
29
30
 
30
31
  __all__ = ["to_json", "from_json", "fqn_of", "key_member", "key_of",
31
- "validate", "SchemaInvalid", "model", "idl_order"]
32
+ "validate", "SchemaInvalid", "model", "idl_order", "class_for",
33
+ "extend", "Extension", "extensions", "extension_of"]
32
34
 
33
35
  T = TypeVar("T")
34
36
 
@@ -61,9 +63,146 @@ def model() -> idlmodel.Model:
61
63
  """The whole vendored IDL, through the gateway's parser."""
62
64
  m = idlmodel.parse(pin.flatten(pin.IDL_DIR, idl_order()))
63
65
  m._leaves = None
66
+ #: The pin's own types, before any `extend()` adds to this model. One
67
+ #: extension's IDL can define several types, so "in the model" is not
68
+ #: "pinned" once the first is registered.
69
+ m.pinned = frozenset(m.aggregates)
64
70
  return m
65
71
 
66
72
 
73
+ @dataclass(frozen=True)
74
+ class Extension:
75
+ """A deployment's own type, registered with `extend()`."""
76
+ type_name: str # its §3.3.2-style name, namespaced: "oarc.fusion_coverage"
77
+ cls: type # the generated class
78
+ fqn: str # its dotted identity, "oarc_demo.FusionCoverage"
79
+ record: bytes # the flattened IDL a recording embeds for it
80
+
81
+
82
+ _EXT: Dict[str, Extension] = {}
83
+ _EXT_FQN: Dict[str, Extension] = {}
84
+ _EXT_NAME = re.compile(r"^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$")
85
+
86
+
87
+ def extensions() -> Dict[str, Extension]:
88
+ """Every type registered with `extend()`, by name."""
89
+ return dict(_EXT)
90
+
91
+
92
+ def extension_of(fqn: str) -> Optional[Extension]:
93
+ """The registered extension with this dotted identity, if there is one."""
94
+ return _EXT_FQN.get(fqn)
95
+
96
+
97
+ def extend(type_name: str, cls: type, idl: Any) -> Extension:
98
+ """Teach this layer a deployment's own type, beside the pinned IDL.
99
+
100
+ A deployment's extension (§3.3.2 allows one, documented) is a type the
101
+ pinned IDL does not define. Until it is registered here, the native
102
+ layer can write it but cannot convert it to N.1 or back, find its key,
103
+ name its class, or record its schema. Registering it gives it all four:
104
+
105
+ * `to_json` / `from_json`, through the same gateway codec as every
106
+ pinned type;
107
+ * `key_of` from its own `@key`, so instances are tracked and `on_exit`
108
+ applies;
109
+ * `class_for(type_name)`, for a bridge that learns the type from an
110
+ announce;
111
+ * the recording tap embeds its IDL.
112
+
113
+ `idl` is the IDL text, or a path to it. It may `#include` only pinned
114
+ files, and its schema record is their closure, then its own body. It must
115
+ define the class's own type.
116
+
117
+ `validate()` cannot check an extension against a published schema,
118
+ because none exists. It checks that the sample is representable in N.1,
119
+ and says so.
120
+
121
+ Refused:
122
+
123
+ * a name without a namespace, which could collide with a future
124
+ registration;
125
+ * a registered name, or a well-known message;
126
+ * a pinned type;
127
+ * IDL that includes an unpinned file, or does not define the class;
128
+ * the same name again with different IDL or class.
129
+
130
+ Registering again with identical arguments is a no-op.
131
+ """
132
+ from pathlib import Path
133
+ from . import registry
134
+ problems = []
135
+ if type_name in registry.registrations() \
136
+ or type_name in registry.well_known():
137
+ problems.append(f"{type_name!r} is the spec's (§3.3.2 or a well-known "
138
+ f"message): it needs no extension")
139
+ elif not isinstance(type_name, str) or not _EXT_NAME.match(type_name):
140
+ problems.append(f"extension name {type_name!r} must be namespaced, "
141
+ f"lower-case segments joined by '.' (e.g. "
142
+ f"'oarc.fusion_coverage'), so it cannot collide with a "
143
+ f"name §3.3.2 registers later")
144
+ try:
145
+ fqn = fqn_of(cls)
146
+ except TypeError as e:
147
+ problems.append(str(e))
148
+ fqn = ""
149
+ if fqn and fqn in model().pinned:
150
+ problems.append(f"{fqn} is in the pinned IDL: use its registered name")
151
+ text = idl
152
+ if isinstance(idl, Path) or (isinstance(idl, str) and "\n" not in idl
153
+ and Path(idl).is_file()):
154
+ text = Path(idl).read_text()
155
+ if not isinstance(text, str) or not text.strip():
156
+ problems.append("idl= must be IDL text or a path to it")
157
+ text = ""
158
+ files: list = []
159
+ for inc in re.findall(r'^\s*#include\s+"([^"]+)"', text, re.M):
160
+ if not (pin.IDL_DIR / inc).is_file():
161
+ problems.append(f"the extension's IDL includes {inc!r}, which the "
162
+ f"pinned IDL does not have")
163
+ continue
164
+ for f in pin.file_closure(inc):
165
+ if f not in files:
166
+ files.append(f)
167
+ if problems:
168
+ raise registry.RegistryError("; ".join(problems))
169
+ body = "\n".join(l for l in text.splitlines()
170
+ if not l.lstrip().startswith("#"))
171
+ record = (pin.flatten(pin.IDL_DIR, files)
172
+ + f"\n// ---- extension {type_name} ----\n{body}").encode()
173
+ parsed = idlmodel.parse(record.decode())
174
+ if fqn not in parsed.aggregates:
175
+ raise registry.RegistryError(
176
+ f"the extension's IDL does not define {fqn}, the type "
177
+ f"{cls.__name__} says it is")
178
+ prior = _EXT.get(type_name) or _EXT_FQN.get(fqn)
179
+ if prior is not None:
180
+ if (prior.type_name, prior.cls, prior.record) == (type_name, cls, record):
181
+ return prior
182
+ raise registry.RegistryError(
183
+ f"{prior.type_name} ({prior.fqn}) is already registered, "
184
+ f"differently: one name, one type, one IDL")
185
+ m = model()
186
+ for k, v in parsed.aggregates.items():
187
+ m.aggregates.setdefault(k, v)
188
+ for k, v in parsed.typedefs.items():
189
+ m.typedefs.setdefault(k, v)
190
+ m._leaves = None
191
+ _codec.cache_clear()
192
+ key_member.cache_clear()
193
+ ext = Extension(type_name, cls, fqn, record)
194
+ _EXT[type_name] = _EXT_FQN[fqn] = ext
195
+ return ext
196
+
197
+
198
+ def _known(fqn: str) -> None:
199
+ if fqn not in model().aggregates:
200
+ from . import registry
201
+ raise registry.RegistryError(
202
+ f"{fqn} is not in the pinned IDL: register a deployment's own type "
203
+ f"with sd.dds.extend(name, cls, idl) first")
204
+
205
+
67
206
  @lru_cache(maxsize=1)
68
207
  def _codec():
69
208
  m, tables = model(), webjson.tables()
@@ -94,6 +233,9 @@ def class_for(name: str) -> type:
94
233
  """
95
234
  import importlib
96
235
  from . import registry
236
+ ext = _EXT.get(name) or _EXT_FQN.get(name)
237
+ if ext is not None:
238
+ return ext.cls
97
239
  reg = registry.registrations().get(name)
98
240
  wk = registry.well_known() if name in registry.well_known() else None
99
241
  fqn = reg.fqn if reg else wk[name].fqn if wk else name
@@ -105,8 +247,9 @@ def class_for(name: str) -> type:
105
247
  except (ImportError, AttributeError):
106
248
  pass
107
249
  raise registry.RegistryError(
108
- f"{name!r} is not a registered type name, a well-known message, or a "
109
- f"dotted type identity in the pinned IDL")
250
+ f"{name!r} is not a registered type name, a well-known message, a "
251
+ f"dotted type identity in the pinned IDL, or an extension registered "
252
+ f"with extend()")
110
253
 
111
254
 
112
255
  def to_json(sample: Any) -> Dict[str, Any]:
@@ -118,8 +261,9 @@ def to_json(sample: Any) -> Dict[str, Any]:
118
261
  gateway's own canonical form, the one its ETags are computed from, so
119
262
  the refusal and a served document's digest are the same rule.
120
263
  """
121
- dec, _w, proj, _l = _codec()
122
264
  fqn = fqn_of(sample)
265
+ _known(fqn)
266
+ dec, _w, proj, _l = _codec()
123
267
  doc = proj.project(fqn, dec.decode(fqn, sample.serialize()))
124
268
  try:
125
269
  webjson.canon(doc)
@@ -130,8 +274,9 @@ def to_json(sample: Any) -> Dict[str, Any]:
130
274
 
131
275
  def from_json(cls: Type[T], doc: Dict[str, Any]) -> T:
132
276
  """A typed sample from its N.1 document: the gateway's lift, encoded, decoded."""
133
- _d, writer, _p, lifter = _codec()
134
277
  fqn = fqn_of(cls)
278
+ _known(fqn)
279
+ _d, writer, _p, lifter = _codec()
135
280
  return cls.deserialize(writer.encode(fqn, lifter.lift(fqn, doc)))
136
281
 
137
282
 
@@ -162,6 +307,9 @@ def validate(sample: Any) -> Dict[str, Any]:
162
307
  to serialize. One whose wire form N.1 cannot carry (a non-finite double)
163
308
  is `SchemaInvalid` from `to_json`. One whose N.1 form breaks its published
164
309
  schema is `SchemaInvalid` here.
310
+
311
+ An extension registered with `extend()` has no published schema, so its
312
+ check stops at the second: representable in N.1.
165
313
  """
166
314
  try:
167
315
  import jsonschema
@@ -170,6 +318,8 @@ def validate(sample: Any) -> Dict[str, Any]:
170
318
  raise MissingExtra(f"validation needs jsonschema: {EXTRA}") from e
171
319
  doc = to_json(sample)
172
320
  fqn = fqn_of(sample)
321
+ if fqn in _EXT_FQN:
322
+ return doc
173
323
  schema = webjson.schemas().get(fqn)
174
324
  if schema is None:
175
325
  raise SchemaInvalid(f"no published schema for {fqn}, so a sample "
@@ -39,6 +39,7 @@ except ImportError as e: # pragma: no cover
39
39
  raise MissingExtra(f"the recording tap needs mcap: {EXTRA}") from e
40
40
 
41
41
  from ..server import mcapmeta, pin # noqa: E402
42
+ from . import codec # noqa: E402
42
43
 
43
44
  __all__ = ["Recorder"]
44
45
 
@@ -73,7 +74,9 @@ class Recorder:
73
74
  if self._closed:
74
75
  return
75
76
  if fqn not in self._schemas:
76
- name, data = pin.schema_record(fqn.replace(".", "::"))
77
+ ext = codec.extension_of(fqn)
78
+ name, data = ((fqn.replace(".", "::"), ext.record) if ext
79
+ else pin.schema_record(fqn.replace(".", "::")))
77
80
  self._schemas[fqn] = self._w.register_schema(
78
81
  name=name, encoding="omgidl", data=data)
79
82
  if topic not in self._channels:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spatialdds
3
- Version: 0.7.1
3
+ Version: 0.7.2
4
4
  Summary: SpatialDDS for programs: a client for the web binding (Appendix N), a native DDS participant, and the reference registry behind one command.
5
5
  Author: Open AR Cloud
6
6
  License: Apache-2.0
@@ -152,6 +152,10 @@ scene:
152
152
  never speaks as the asserter.
153
153
  - **`sd.dds.class_for(name)`** is the generated class for a registered type
154
154
  name, a well-known message or a dotted identity.
155
+ - **`sd.dds.extend(name, cls, idl)`** registers a deployment's own type, with
156
+ the IDL it was generated from. After that it converts, keys, records and
157
+ opens by name like a pinned type, and validation checks N.1
158
+ representability, since it has no published schema.
155
159
 
156
160
  `Sample.data` is the typed sample (`sd.dds.types` carries every type in the
157
161
  pinned IDL). `sd.dds.to_json(sample)` is its N.1 form, produced by the gateway's
@@ -594,6 +598,12 @@ explicitly was tried first and is what missed two paths.
594
598
 
595
599
  If your clients are not browsers, nothing here changes anything for you.
596
600
 
601
+ ## New in 0.7.2: a deployment's own types
602
+
603
+ `sd.dds.extend(name, cls, idl)` brings a deployment's own documented type
604
+ into the native layer: N.1 conversion, its key, `class_for`, the recording
605
+ tap, and opening it by name. Additive, as 0.7.1 was.
606
+
597
607
  ## New in 0.7.1: for programs that own their loop
598
608
 
599
609
  Everything SpatialDDS-demo's adoption found missing, and nothing removed:
@@ -649,7 +659,7 @@ Two changes may need a line of yours:
649
659
  The security fixes, the limits table and the details are in the
650
660
  [changelog](https://github.com/OpenArCloud/spatialdds-py/blob/main/lib/spatialdds/CHANGELOG.md).
651
661
 
652
- ## Not in 0.7.1
662
+ ## Not in 0.7.2
653
663
 
654
664
  Stated so nobody waits for them:
655
665
 
File without changes