spatialdds 0.8.0__tar.gz → 0.8.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 (246) hide show
  1. {spatialdds-0.8.0 → spatialdds-0.8.2}/PKG-INFO +8 -1
  2. {spatialdds-0.8.0 → spatialdds-0.8.2}/README.md +7 -0
  3. {spatialdds-0.8.0 → spatialdds-0.8.2}/pyproject.toml +1 -1
  4. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/__init__.py +1 -1
  5. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/openapi.html +1 -1
  6. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/openapi.yaml +1 -1
  7. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/_participant.py +24 -4
  8. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/gw_http.py +19 -7
  9. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/publish.py +44 -9
  10. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds.egg-info/PKG-INFO +8 -1
  11. {spatialdds-0.8.0 → spatialdds-0.8.2}/setup.cfg +0 -0
  12. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/anchors.idl +0 -0
  13. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/argeo.idl +0 -0
  14. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/common.idl +0 -0
  15. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/core.idl +0 -0
  16. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/discovery.idl +0 -0
  17. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/events.idl +0 -0
  18. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/lidar.idl +0 -0
  19. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/mapping.idl +0 -0
  20. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/provisional/owm.idl +0 -0
  21. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/provisional/radio.idl +0 -0
  22. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/provisional/rf_beam.idl +0 -0
  23. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/rad.idl +0 -0
  24. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/semantics.idl +0 -0
  25. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/slam_frontend.idl +0 -0
  26. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/types.idl +0 -0
  27. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/vio.idl +0 -0
  28. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/idl/vision.idl +0 -0
  29. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/registry.json +0 -0
  30. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/builtin_Time.json +0 -0
  31. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_anchors_AnchorDelta.json +0 -0
  32. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_anchors_AnchorEntry.json +0 -0
  33. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSet.json +0 -0
  34. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSetRequest.json +0 -0
  35. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSetResponse.json +0 -0
  36. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_argeo_NodeGeo.json +0 -0
  37. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_argeo_QualityRequirements.json +0 -0
  38. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_argeo_VpsRequest.json +0 -0
  39. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_argeo_VpsResponse.json +0 -0
  40. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_common_AssetRef.json +0 -0
  41. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_common_FrameRef.json +0 -0
  42. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_common_KV.json +0 -0
  43. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_common_MetaKV.json +0 -0
  44. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_common_Vec2.json +0 -0
  45. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_Aabb3.json +0 -0
  46. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_BlobChunk.json +0 -0
  47. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_BlobRef.json +0 -0
  48. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_ComponentRef.json +0 -0
  49. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_Edge.json +0 -0
  50. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_EntityBinding.json +0 -0
  51. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_FrameTransform.json +0 -0
  52. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_FramedPose.json +0 -0
  53. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_GeoAnchor.json +0 -0
  54. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_GeoPose.json +0 -0
  55. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_NavSatStatus.json +0 -0
  56. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_Node.json +0 -0
  57. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_PlannedTrajectory.json +0 -0
  58. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_PlannedWaypoint.json +0 -0
  59. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_PoseSE3.json +0 -0
  60. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_SnapshotRequest.json +0 -0
  61. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_SnapshotResponse.json +0 -0
  62. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_TileKey.json +0 -0
  63. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_TileMeta.json +0 -0
  64. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_core_TilePatch.json +0 -0
  65. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_Announce.json +0 -0
  66. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_Capabilities.json +0 -0
  67. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_ContentAnnounce.json +0 -0
  68. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_CoverageElement.json +0 -0
  69. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_CoverageFilter.json +0 -0
  70. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_CoverageHint.json +0 -0
  71. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_CoverageQuery.json +0 -0
  72. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_CoverageResponse.json +0 -0
  73. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_Depart.json +0 -0
  74. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_KV.json +0 -0
  75. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_ProfileSupport.json +0 -0
  76. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_ServiceSummary.json +0 -0
  77. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_TopicMeta.json +0 -0
  78. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_Transform.json +0 -0
  79. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_disco_ValidityWindow.json +0 -0
  80. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_events_CrossingLine.json +0 -0
  81. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_events_SpatialEvent.json +0 -0
  82. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_events_SpatialZone.json +0 -0
  83. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_events_ZoneState.json +0 -0
  84. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_mapping_Edge.json +0 -0
  85. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_mapping_MapAlignment.json +0 -0
  86. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_mapping_MapEvent.json +0 -0
  87. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_mapping_MapMeta.json +0 -0
  88. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_mapping_MapQuality.json +0 -0
  89. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_owm_Entity.json +0 -0
  90. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_owm_ModelCommand.json +0 -0
  91. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_owm_ModelPose.json +0 -0
  92. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_semantics_Detection2D.json +0 -0
  93. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_semantics_Detection2DSet.json +0 -0
  94. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_semantics_Detection3D.json +0 -0
  95. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_semantics_Detection3DSet.json +0 -0
  96. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_semantics_FusedTrack.json +0 -0
  97. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_semantics_FusedTrackSet.json +0 -0
  98. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_semantics_Keypoint3D.json +0 -0
  99. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_semantics_KeypointLink.json +0 -0
  100. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_common_Axis.json +0 -0
  101. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_common_FrameHeader.json +0 -0
  102. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_common_FrameQuality.json +0 -0
  103. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_common_Linspace.json +0 -0
  104. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_common_ROI.json +0 -0
  105. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_common_ROIReply.json +0 -0
  106. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_common_ROIRequest.json +0 -0
  107. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_common_StreamMeta.json +0 -0
  108. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarDetection.json +0 -0
  109. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarDetectionSet.json +0 -0
  110. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarFrame.json +0 -0
  111. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarMeta.json +0 -0
  112. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadDetection.json +0 -0
  113. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadDetectionSet.json +0 -0
  114. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadSensorMeta.json +0 -0
  115. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadTensorFrame.json +0 -0
  116. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadTensorMeta.json +0 -0
  117. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioObservation.json +0 -0
  118. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioScan.json +0 -0
  119. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioSensorMeta.json +0 -0
  120. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamArraySet.json +0 -0
  121. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamFrame.json +0 -0
  122. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamMeta.json +0 -0
  123. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_CamIntrinsics.json +0 -0
  124. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_Keypoint2D.json +0 -0
  125. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_Track2D.json +0 -0
  126. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionDetections.json +0 -0
  127. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionFrame.json +0 -0
  128. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionMeta.json +0 -0
  129. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_CameraInfo.json +0 -0
  130. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_Feature2D.json +0 -0
  131. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_FeatureMatch.json +0 -0
  132. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_KeyframeFeatures.json +0 -0
  133. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_Landmark.json +0 -0
  134. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_MatchSet.json +0 -0
  135. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_TrackObs.json +0 -0
  136. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_slam_frontend_Tracklet.json +0 -0
  137. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_vio_FusedState.json +0 -0
  138. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_vio_ImuInfo.json +0 -0
  139. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_vio_ImuSample.json +0 -0
  140. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_vio_MagnetometerSample.json +0 -0
  141. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/schemas/spatial_vio_SensorFusionSample.json +0 -0
  142. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/artifacts/serializer_tables.json +0 -0
  143. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/canonical.py +0 -0
  144. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/canonjson.py +0 -0
  145. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/client.py +0 -0
  146. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/__init__.py +0 -0
  147. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/_extra.py +0 -0
  148. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/blob.py +0 -0
  149. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/codec.py +0 -0
  150. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/qos.py +0 -0
  151. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/record.py +0 -0
  152. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/registry.py +0 -0
  153. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/__init__.py +0 -0
  154. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/_field_aliases.py +0 -0
  155. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/builtin/__init__.py +0 -0
  156. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/builtin/_types.py +0 -0
  157. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/__init__.py +0 -0
  158. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/anchors/__init__.py +0 -0
  159. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/anchors/_anchors.py +0 -0
  160. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/argeo/__init__.py +0 -0
  161. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/argeo/_argeo.py +0 -0
  162. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/common/__init__.py +0 -0
  163. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/common/_types.py +0 -0
  164. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/core/GnssService/__init__.py +0 -0
  165. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/core/GnssService/_core.py +0 -0
  166. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/core/__init__.py +0 -0
  167. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/core/_core.py +0 -0
  168. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/disco/__init__.py +0 -0
  169. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/disco/_discovery.py +0 -0
  170. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/__init__.py +0 -0
  171. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/_events.py +0 -0
  172. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/enums/__init__.py +0 -0
  173. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/enums/crossing_direction_enum/__init__.py +0 -0
  174. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/enums/crossing_direction_enum/_events.py +0 -0
  175. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/enums/event_state_enum/__init__.py +0 -0
  176. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/enums/event_state_enum/_events.py +0 -0
  177. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/enums/event_type_enum/__init__.py +0 -0
  178. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/enums/event_type_enum/_events.py +0 -0
  179. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/enums/severity_enum/__init__.py +0 -0
  180. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/enums/severity_enum/_events.py +0 -0
  181. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/enums/zone_kind_enum/__init__.py +0 -0
  182. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/events/enums/zone_kind_enum/_events.py +0 -0
  183. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/__init__.py +0 -0
  184. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/_mapping.py +0 -0
  185. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/enums/__init__.py +0 -0
  186. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/enums/alignment_method/__init__.py +0 -0
  187. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/enums/alignment_method/_mapping.py +0 -0
  188. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/enums/edge_type/__init__.py +0 -0
  189. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/enums/edge_type/_mapping.py +0 -0
  190. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/enums/map_event_kind/__init__.py +0 -0
  191. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/enums/map_event_kind/_mapping.py +0 -0
  192. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/enums/map_kind/__init__.py +0 -0
  193. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/enums/map_kind/_mapping.py +0 -0
  194. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/enums/map_status/__init__.py +0 -0
  195. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/mapping/enums/map_status/_mapping.py +0 -0
  196. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/owm/__init__.py +0 -0
  197. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/owm/_owm.py +0 -0
  198. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/semantics/__init__.py +0 -0
  199. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/semantics/_semantics.py +0 -0
  200. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/__init__.py +0 -0
  201. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/common/__init__.py +0 -0
  202. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/common/_common.py +0 -0
  203. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/lidar/__init__.py +0 -0
  204. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/lidar/_lidar.py +0 -0
  205. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/rad/__init__.py +0 -0
  206. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/rad/_rad.py +0 -0
  207. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/radio/__init__.py +0 -0
  208. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/radio/_radio.py +0 -0
  209. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/rf_beam/__init__.py +0 -0
  210. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/rf_beam/_rf_beam.py +0 -0
  211. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/vision/__init__.py +0 -0
  212. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/sensing/vision/_vision.py +0 -0
  213. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/slam_frontend/__init__.py +0 -0
  214. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/slam_frontend/_slam_frontend.py +0 -0
  215. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/vio/__init__.py +0 -0
  216. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/dds/types/spatial/vio/_vio.py +0 -0
  217. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/demo/assets/duck.gltf +0 -0
  218. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/demo/assets/fountain-label.txt +0 -0
  219. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/demo/assets/fountain-marker.gltf +0 -0
  220. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/demo/fountain-anchors.mcap +0 -0
  221. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/demo/manifests/content-fountain-label.json +0 -0
  222. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/demo/manifests/content-fountain-marker.json +0 -0
  223. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/errors.py +0 -0
  224. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/events.py +0 -0
  225. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/frames.py +0 -0
  226. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/journal.py +0 -0
  227. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/recency.py +0 -0
  228. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/records.py +0 -0
  229. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/serve.py +0 -0
  230. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/__init__.py +0 -0
  231. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/bus.py +0 -0
  232. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/commands.py +0 -0
  233. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/gateway.py +0 -0
  234. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/idlmodel.py +0 -0
  235. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/limits.py +0 -0
  236. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/mcapmeta.py +0 -0
  237. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/pin.py +0 -0
  238. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/tenancy.py +0 -0
  239. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/webjson.py +0 -0
  240. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/server/xcdr2.py +0 -0
  241. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds/tokens.py +0 -0
  242. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds.egg-info/SOURCES.txt +0 -0
  243. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds.egg-info/dependency_links.txt +0 -0
  244. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds.egg-info/entry_points.txt +0 -0
  245. {spatialdds-0.8.0 → spatialdds-0.8.2}/spatialdds.egg-info/requires.txt +0 -0
  246. {spatialdds-0.8.0 → spatialdds-0.8.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.8.0
3
+ Version: 0.8.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
@@ -31,6 +31,13 @@ Requires-Dist: jsonschema>=4.0; extra == "dds"
31
31
  SpatialDDS for programs: a client over plain HTTPS and a WebSocket, a native
32
32
  DDS participant, and the reference registry behind one command.
33
33
 
34
+ **Integrating with a registry, or with the public sandbox at
35
+ demo.spatialdds.org?** Start with the
36
+ [integrator guide](https://github.com/OpenArCloud/spatialdds-py/blob/main/docs/integrator-guide.md):
37
+ read, watch, and publish content, live entities and claims, and every
38
+ refusal you can meet. Every command in it is run by a gate, in order,
39
+ against the code in the repository.
40
+
34
41
  ```sh
35
42
  pip install spatialdds # the client: two dependencies
36
43
  pip install "spatialdds[server]" # and the registry
@@ -3,6 +3,13 @@
3
3
  SpatialDDS for programs: a client over plain HTTPS and a WebSocket, a native
4
4
  DDS participant, and the reference registry behind one command.
5
5
 
6
+ **Integrating with a registry, or with the public sandbox at
7
+ demo.spatialdds.org?** Start with the
8
+ [integrator guide](https://github.com/OpenArCloud/spatialdds-py/blob/main/docs/integrator-guide.md):
9
+ read, watch, and publish content, live entities and claims, and every
10
+ refusal you can meet. Every command in it is run by a gate, in order,
11
+ against the code in the repository.
12
+
6
13
  ```sh
7
14
  pip install spatialdds # the client: two dependencies
8
15
  pip install "spatialdds[server]" # and the registry
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "spatialdds"
7
- version = "0.8.0"
7
+ version = "0.8.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.8.0"
44
+ __version__ = "0.8.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.8.0 · 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. A deployment&#x27;s own keyed types (<code>serve --extension</code>) are publishable on their own collection paths, under the same rules as the entity lane when they carry <code>basis</code>, <code>state</code>, <code>state_reason</code> and <code>stamp</code>; a type that names an <code>asserter</code> has it stamped or verified as the bearer token&#x27;s principal (<code>asserter-not-principal</code>, <code>asserter-ungrounded</code>). Their paths are not listed here, because the deployment chooses them.</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="listEntity"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/entity/v1</code></h3><p class="sum">Every spatial.owm.Entity instance in the latched set <span class="auth">token</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="commandEntity"><h3><span class="v post">POST</span> <code>/{scene}/{stream}/entity/v1</code></h3><p class="sum">An N.6 command addressed through the entity 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="getEntity"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/entity/v1/{key}</code></h3><p class="sum">One spatial.owm.Entity instance <span class="auth">token</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="putEntity"><h3><span class="v put">PUT</span> <code>/{scene}/{stream}/entity/v1/{key}</code></h3><p class="sum">Publish or replace a spatial.owm.Entity <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. **Basis gates liveliness.** A DECLARED or AUTHORED body is a declaration and holds until withdrawn; it takes no <code>refresh</code>. An DERIVED or OBSERVED body must declare <code>refresh</code>, and be PUT again within it; when it lapses the gateway withdraws the instance itself, a terminal sample (RETIRED) then the dispose, both with the reason <code>refresh lapsed</code>. On a gateway with a DDS domain the instance is written there too, from the gateway&#x27;s own participant.</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 s5">503</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span></p></section><section id="withdrawEntity"><h3><span class="v delete">DELETE</span> <code>/{scene}/{stream}/entity/v1/{key}</code></h3><p class="sum">Withdraw (dispose) a spatial.owm.Entity <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>). A terminal sample (RETIRED, with the reason) streams first, then the dispose with its <code>reason</code>, on the collection&#x27;s WebSocket and, on a gateway with a DDS domain, on the bus.</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.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.8.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. A deployment&#x27;s own keyed types (<code>serve --extension</code>) are publishable on their own collection paths, under the same rules as the entity lane when they carry <code>basis</code>, <code>state</code>, <code>state_reason</code> and <code>stamp</code>; a type that names an <code>asserter</code> has it stamped or verified as the bearer token&#x27;s principal (<code>asserter-not-principal</code>, <code>asserter-ungrounded</code>). Their paths are not listed here, because the deployment chooses them.</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="listEntity"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/entity/v1</code></h3><p class="sum">Every spatial.owm.Entity instance in the latched set <span class="auth">token</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="commandEntity"><h3><span class="v post">POST</span> <code>/{scene}/{stream}/entity/v1</code></h3><p class="sum">An N.6 command addressed through the entity 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="getEntity"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/entity/v1/{key}</code></h3><p class="sum">One spatial.owm.Entity instance <span class="auth">token</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="putEntity"><h3><span class="v put">PUT</span> <code>/{scene}/{stream}/entity/v1/{key}</code></h3><p class="sum">Publish or replace a spatial.owm.Entity <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. **Basis gates liveliness.** A DECLARED or AUTHORED body is a declaration and holds until withdrawn; it takes no <code>refresh</code>. An DERIVED or OBSERVED body must declare <code>refresh</code>, and be PUT again within it; when it lapses the gateway withdraws the instance itself, a terminal sample (RETIRED) then the dispose, both with the reason <code>refresh lapsed</code>. On a gateway with a DDS domain the instance is written there too, from the gateway&#x27;s own participant.</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 s5">503</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span></p></section><section id="withdrawEntity"><h3><span class="v delete">DELETE</span> <code>/{scene}/{stream}/entity/v1/{key}</code></h3><p class="sum">Withdraw (dispose) a spatial.owm.Entity <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>). A terminal sample (RETIRED, with the reason) streams first, then the dispose with its <code>reason</code>, on the collection&#x27;s WebSocket and, on a gateway with a DDS domain, on the bus.</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.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.8.0
5
+ version: 0.8.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. A deployment's own keyed types (`serve --extension`) are publishable on their own collection paths, under the same rules as the entity lane when they carry `basis`, `state`, `state_reason` and `stamp`; a type that names an `asserter` has it stamped or verified as the bearer token's principal (`asserter-not-principal`, `asserter-ungrounded`). Their paths are not listed here, because the deployment chooses them.
8
8
  servers:
@@ -75,6 +75,9 @@ DOMAIN_ENV = "SPATIALDDS_DDS_DOMAIN"
75
75
  #: program can make: a robot still exists after its bridge stops; a
76
76
  #: withdrawn catalogue item does not.
77
77
  ON_EXIT = ("keep", "withdraw")
78
+ #: The most samples one `Reader.take()` takes from its DataReader; the rest
79
+ #: wait for the next call (finding 76).
80
+ TAKE_LIMIT = 256
78
81
  #: Message types whose well-known writers the participant owns: it announces
79
82
  #: and departs on a program's behalf, so a second writer would be a second
80
83
  #: claim about the same presence.
@@ -336,6 +339,12 @@ class Writer:
336
339
  its terminal state itself, and this wrote it again (S18). The members
337
340
  this method sets (`state`, `state_reason`, `stamp`) and the key are
338
341
  not changes a caller can make.
342
+
343
+ The terminal sample's `stamp` is this host's wall clock at the moment
344
+ of withdrawal, whatever clock the instance's other samples carried;
345
+ `on_exit="withdraw"` stamps the same way. A writer on another clock (a
346
+ simulator, a replay, a device with its own time base) cannot set it,
347
+ so its withdrawals read as happening at host time (finding 74).
339
348
  """
340
349
  if not isinstance(reason, str) or not reason.strip():
341
350
  raise ValueError("withdraw() needs a non-empty reason=: a removal "
@@ -343,8 +352,12 @@ class Writer:
343
352
  fixed = {"state", "state_reason", "stamp", codec.key_member(self._lane.fqn)}
344
353
  refused = sorted(set(changes) & fixed)
345
354
  if refused:
346
- raise ValueError(f"withdraw() sets {', '.join(refused)} itself; "
347
- f"pass reason=, and the other members to change")
355
+ clock = (" (the terminal stamp is this host's wall clock at "
356
+ "withdrawal, and a caller cannot set it)"
357
+ if "stamp" in refused else "")
358
+ raise ValueError(f"withdraw() sets {', '.join(refused)} itself"
359
+ f"{clock}; pass reason=, and the other members "
360
+ f"to change")
348
361
  with self._lock:
349
362
  if key not in self._last:
350
363
  raise KeyError(f"{self.topic} holds no instance keyed {key!r} "
@@ -514,7 +527,7 @@ class Reader:
514
527
 
515
528
  def _events(self) -> List[Any]:
516
529
  out: List[Any] = []
517
- for s in self._dr.take(N=256) or []:
530
+ for s in self._dr.take(N=TAKE_LIMIT) or []:
518
531
  info = getattr(s, "sample_info", None)
519
532
  if info is None:
520
533
  continue
@@ -534,7 +547,14 @@ class Reader:
534
547
  return out
535
548
 
536
549
  def take(self) -> List[Any]:
537
- """Every event that has arrived, now, without blocking.
550
+ """What has arrived, now, without blocking: up to 256 samples' events.
551
+
552
+ A call takes at most `TAKE_LIMIT` samples from the reader, and any
553
+ beyond that wait for the next call. Nothing in what it returns says
554
+ more are waiting, so a program whose lanes can deliver more than 256
555
+ samples between two calls should call `take()` again until it
556
+ returns no events (finding 76). `events()` keeps calling it and has
557
+ no such bound.
538
558
 
539
559
  For a program that already owns its loop: a tick, a framework's
540
560
  timer, a request handler. The events are the ones `events()` yields,
@@ -261,11 +261,15 @@ def _unwritable(request: web.Request,
261
261
 
262
262
  Reads keep serving the state as it was. The write may be retried as it
263
263
  stands once space returns; no operator action is needed, because the
264
- journal on disk is the last one that was completely written.
264
+ journal on disk is the last one that was completely written. The full
265
+ error, which names the journal's path, goes to the server's log and not
266
+ to the client (finding 78).
265
267
  """
268
+ print(f"spatialdds: journal unwritable, write refused: {e}",
269
+ file=sys.stderr)
266
270
  r = _problem(503, "journal-unwritable", "The registry cannot record writes",
267
- f"This write was not accepted: the journal could not be "
268
- f"written ({e}). Reads are unaffected. Retry later.",
271
+ f"This write was not accepted: {e.reason}. Reads are "
272
+ f"unaffected. Retry later.",
269
273
  instance=str(request.rel_url))
270
274
  r.headers["Retry-After"] = "60"
271
275
  return r
@@ -504,10 +508,14 @@ def _schemas(request: web.Request) -> dict[str, dict]:
504
508
 
505
509
  N.2: an endpoint MUST publish a schema for every type it serves. A
506
510
  deployment's own type is described by the model it is decoded with.
511
+ Every type the write surface accepts is listed whether or not a lane of
512
+ it exists yet, since a body is held to this schema before its first lane
513
+ does (finding 79).
507
514
  """
508
515
  st: gateway.State = request.app["state"]
509
516
  return webjson.served_schemas(st.model,
510
- {r.fqn for r in st.resources.values()})
517
+ {r.fqn for r in st.resources.values()}
518
+ | set(st.publishable.values()))
511
519
 
512
520
 
513
521
  async def schemas_index(request: web.Request) -> web.Response:
@@ -1153,10 +1161,12 @@ async def put_instance(request: web.Request) -> web.Response:
1153
1161
  try:
1154
1162
  topic, res = publish.resource_for_put(
1155
1163
  st, m["scene"], m["stream"], m["type"], m["version"])
1156
- # Before validation: an empty asserter is stamped, and the stamped
1157
- # body is the one checked, encoded and stored.
1158
- body = publish.ground_asserter(st, res.fqn, body, who.name)
1164
+ # The body as sent meets the published schema first: a missing
1165
+ # asserter is a missing required member, not an empty one (fuzz,
1166
+ # 0.8.0). Then an empty asserter is stamped, and the stamped body is
1167
+ # the one encoded and stored.
1159
1168
  publish.validate_schema(res.fqn, body, st)
1169
+ body = publish.ground_asserter(st, res.fqn, body, who.name)
1160
1170
  publish.check_authority(request.app["base"], body)
1161
1171
  data, raw = publish.canonicalize(st, res.fqn, body)
1162
1172
  # The basis rule: an observed or derived claim declares how often it
@@ -1219,6 +1229,8 @@ async def put_instance(request: web.Request) -> web.Response:
1219
1229
  scene=res.scene, refresh=lease)
1220
1230
  except publish.JournalUnwritable as e:
1221
1231
  return _unwritable(request, e)
1232
+ # Accepted and journalled: only now does a new lane exist (finding 73).
1233
+ publish.register_lane(st, res)
1222
1234
  created = publish.apply_sample(st, topic, res, key, data)
1223
1235
  # A re-PUT inside the interval is the refresh: it starts the interval
1224
1236
  # again. A body whose basis became a declaration drops the lease.
@@ -29,6 +29,7 @@ carries it as a design rule.
29
29
  """
30
30
  from __future__ import annotations
31
31
 
32
+ import errno
32
33
  import json
33
34
  import os
34
35
  import tempfile
@@ -96,7 +97,23 @@ WRITTEN_BY_RECORD = mcapmeta.WRITTEN_BY_RECORD
96
97
 
97
98
 
98
99
  class JournalUnwritable(Exception):
99
- """The journal could not be written; nothing was accepted."""
100
+ """The journal could not be written; nothing was accepted.
101
+
102
+ `str()` is the full error, paths included, for the server's log. A client
103
+ is told `reason`, which is worded from the errno alone: the exception's
104
+ text names the journal's directory, and a refusal names only what the
105
+ client sent (finding 78).
106
+ """
107
+
108
+ def __init__(self, full: str, err: int | None = None) -> None:
109
+ super().__init__(full)
110
+ self.errno = err
111
+
112
+ @property
113
+ def reason(self) -> str:
114
+ if self.errno in (errno.ENOSPC, getattr(errno, "EDQUOT", None)):
115
+ return "the registry's disk is full"
116
+ return "the journal cannot be written"
100
117
 
101
118
 
102
119
  class Rejected(Exception):
@@ -206,7 +223,13 @@ def canonicalize(st: gateway.State, fqn: str,
206
223
 
207
224
  def resource_for_put(st: gateway.State, scene: str, stream: str,
208
225
  type_seg: str, version: str) -> tuple[str, gateway.Resource]:
209
- """The resource a PUT addresses, created if this topic is new."""
226
+ """The resource a PUT or DELETE addresses, provisional if the topic is new.
227
+
228
+ A new topic's `Resource` is built and returned, and not registered:
229
+ `register_lane()` does that, once a write to it is accepted. Registering
230
+ it here, as a side effect of the lookup, let a refused `PUT` or a 404'd
231
+ `DELETE` create a lane that search advertised (finding 73).
232
+ """
210
233
  fqn = PUBLISHABLE.get(type_seg) or st.publishable.get(type_seg)
211
234
  every = sorted(set(PUBLISHABLE) | set(st.publishable))
212
235
  if fqn is None:
@@ -244,14 +267,25 @@ def resource_for_put(st: gateway.State, scene: str, stream: str,
244
267
  access = gateway.PUBLIC
245
268
  res = gateway.Resource(scene, stream, type_seg, version, topic, fqn,
246
269
  keys[0] if keys else "", access, latched)
247
- st.resources[res.path] = res
248
- st.latched.setdefault(topic, {})
249
- st.latched_initial.setdefault(topic, {})
250
- st.live.setdefault(topic, [])
251
- st.scenes = sorted(set(st.scenes) | {scene})
252
270
  return topic, res
253
271
 
254
272
 
273
+ def register_lane(st: gateway.State, res: gateway.Resource) -> None:
274
+ """Make a lane served: in search, its collection, its streams.
275
+
276
+ Called when a write to it is accepted (and journalled, where there is a
277
+ journal), and on replay; never on a refusal. A no-op for a lane that is
278
+ already registered.
279
+ """
280
+ if res.path in st.resources:
281
+ return
282
+ st.resources[res.path] = res
283
+ st.latched.setdefault(res.topic, {})
284
+ st.latched_initial.setdefault(res.topic, {})
285
+ st.live.setdefault(res.topic, [])
286
+ st.scenes = sorted(set(st.scenes) | {res.scene})
287
+
288
+
255
289
  def apply_sample(st: gateway.State, topic: str, res: gateway.Resource,
256
290
  key: str, data: dict) -> bool:
257
291
  """Put an instance into the latched set. True if it is new.
@@ -402,7 +436,7 @@ def ground_asserter(st: gateway.State, fqn: str, doc: Any,
402
436
  """
403
437
  if ASSERTER not in members_of(st, fqn) or not isinstance(doc, dict):
404
438
  return doc
405
- claimed = doc.get(ASSERTER, "")
439
+ claimed = doc.get(ASSERTER)
406
440
  if not principal:
407
441
  raise Rejected(
408
442
  403, "asserter-ungrounded", "No principal to assert this claim",
@@ -487,6 +521,7 @@ class Journal:
487
521
  continue
488
522
  if e["kind"] == "sample":
489
523
  topic, res = resource_for_put(self.state, *seg)
524
+ register_lane(self.state, res)
490
525
  data = proj.project(e["fqn"], dec.decode(e["fqn"], e["raw"]))
491
526
  key = str(data.get(res.key, "")) if res.key else ""
492
527
  apply_sample(self.state, topic, res, key, data)
@@ -567,7 +602,7 @@ class Journal:
567
602
  except OSError as e:
568
603
  self.entries.pop()
569
604
  self.seq -= 1
570
- raise JournalUnwritable(f"{type(e).__name__}: {e}") from e
605
+ raise JournalUnwritable(f"{type(e).__name__}: {e}", e.errno) from e
571
606
 
572
607
 
573
608
  def _topic_scene(topic: str) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spatialdds
3
- Version: 0.8.0
3
+ Version: 0.8.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
@@ -31,6 +31,13 @@ Requires-Dist: jsonschema>=4.0; extra == "dds"
31
31
  SpatialDDS for programs: a client over plain HTTPS and a WebSocket, a native
32
32
  DDS participant, and the reference registry behind one command.
33
33
 
34
+ **Integrating with a registry, or with the public sandbox at
35
+ demo.spatialdds.org?** Start with the
36
+ [integrator guide](https://github.com/OpenArCloud/spatialdds-py/blob/main/docs/integrator-guide.md):
37
+ read, watch, and publish content, live entities and claims, and every
38
+ refusal you can meet. Every command in it is run by a gate, in order,
39
+ against the code in the repository.
40
+
34
41
  ```sh
35
42
  pip install spatialdds # the client: two dependencies
36
43
  pip install "spatialdds[server]" # and the registry
File without changes