spatialdds 0.5.4__tar.gz → 0.7.0__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.5.4/spatialdds.egg-info → spatialdds-0.7.0}/PKG-INFO +178 -24
  2. spatialdds-0.5.4/PKG-INFO → spatialdds-0.7.0/README.md +170 -44
  3. {spatialdds-0.5.4 → spatialdds-0.7.0}/pyproject.toml +31 -9
  4. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/__init__.py +26 -9
  5. spatialdds-0.7.0/spatialdds/artifacts/idl/anchors.idl +68 -0
  6. spatialdds-0.7.0/spatialdds/artifacts/idl/argeo.idl +125 -0
  7. spatialdds-0.7.0/spatialdds/artifacts/idl/common.idl +174 -0
  8. spatialdds-0.7.0/spatialdds/artifacts/idl/events.idl +362 -0
  9. spatialdds-0.7.0/spatialdds/artifacts/idl/lidar.idl +126 -0
  10. spatialdds-0.7.0/spatialdds/artifacts/idl/mapping.idl +322 -0
  11. spatialdds-0.7.0/spatialdds/artifacts/idl/provisional/owm.idl +153 -0
  12. spatialdds-0.7.0/spatialdds/artifacts/idl/provisional/radio.idl +142 -0
  13. spatialdds-0.7.0/spatialdds/artifacts/idl/provisional/rf_beam.idl +148 -0
  14. spatialdds-0.7.0/spatialdds/artifacts/idl/rad.idl +241 -0
  15. spatialdds-0.7.0/spatialdds/artifacts/idl/semantics.idl +212 -0
  16. spatialdds-0.7.0/spatialdds/artifacts/idl/slam_frontend.idl +103 -0
  17. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/idl/types.idl +6 -0
  18. spatialdds-0.7.0/spatialdds/artifacts/idl/vio.idl +112 -0
  19. spatialdds-0.7.0/spatialdds/artifacts/idl/vision.idl +165 -0
  20. spatialdds-0.7.0/spatialdds/artifacts/openapi.html +17 -0
  21. spatialdds-0.7.0/spatialdds/artifacts/openapi.yaml +6511 -0
  22. spatialdds-0.7.0/spatialdds/artifacts/registry.json +561 -0
  23. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_CamIntrinsics.json +1 -0
  24. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionFrame.json +1 -0
  25. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionMeta.json +2 -0
  26. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/serializer_tables.json +1 -0
  27. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/client.py +53 -38
  28. spatialdds-0.7.0/spatialdds/dds/__init__.py +75 -0
  29. spatialdds-0.7.0/spatialdds/dds/_extra.py +22 -0
  30. spatialdds-0.7.0/spatialdds/dds/_participant.py +751 -0
  31. spatialdds-0.7.0/spatialdds/dds/blob.py +128 -0
  32. spatialdds-0.7.0/spatialdds/dds/codec.py +154 -0
  33. spatialdds-0.7.0/spatialdds/dds/qos.py +61 -0
  34. spatialdds-0.7.0/spatialdds/dds/record.py +107 -0
  35. spatialdds-0.7.0/spatialdds/dds/registry.py +271 -0
  36. spatialdds-0.7.0/spatialdds/dds/types/__init__.py +12 -0
  37. spatialdds-0.7.0/spatialdds/dds/types/_field_aliases.py +26 -0
  38. spatialdds-0.7.0/spatialdds/dds/types/builtin/__init__.py +11 -0
  39. spatialdds-0.7.0/spatialdds/dds/types/builtin/_types.py +28 -0
  40. spatialdds-0.7.0/spatialdds/dds/types/spatial/__init__.py +33 -0
  41. spatialdds-0.7.0/spatialdds/dds/types/spatial/anchors/__init__.py +20 -0
  42. spatialdds-0.7.0/spatialdds/dds/types/spatial/anchors/_anchors.py +102 -0
  43. spatialdds-0.7.0/spatialdds/dds/types/spatial/argeo/__init__.py +22 -0
  44. spatialdds-0.7.0/spatialdds/dds/types/spatial/argeo/_argeo.py +97 -0
  45. spatialdds-0.7.0/spatialdds/dds/types/spatial/common/__init__.py +27 -0
  46. spatialdds-0.7.0/spatialdds/dds/types/spatial/common/_types.py +104 -0
  47. spatialdds-0.7.0/spatialdds/dds/types/spatial/core/GnssService/__init__.py +17 -0
  48. spatialdds-0.7.0/spatialdds/dds/types/spatial/core/GnssService/_core.py +27 -0
  49. spatialdds-0.7.0/spatialdds/dds/types/spatial/core/__init__.py +40 -0
  50. spatialdds-0.7.0/spatialdds/dds/types/spatial/core/_core.py +338 -0
  51. spatialdds-0.7.0/spatialdds/dds/types/spatial/disco/__init__.py +34 -0
  52. spatialdds-0.7.0/spatialdds/dds/types/spatial/disco/_discovery.py +252 -0
  53. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/__init__.py +29 -0
  54. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/_events.py +164 -0
  55. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/enums/__init__.py +19 -0
  56. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/enums/crossing_direction_enum/__init__.py +11 -0
  57. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/enums/crossing_direction_enum/_events.py +25 -0
  58. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/enums/event_state_enum/__init__.py +11 -0
  59. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/enums/event_state_enum/_events.py +26 -0
  60. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/enums/event_type_enum/__init__.py +11 -0
  61. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/enums/event_type_enum/_events.py +36 -0
  62. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/enums/severity_enum/__init__.py +11 -0
  63. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/enums/severity_enum/_events.py +26 -0
  64. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/enums/zone_kind_enum/__init__.py +11 -0
  65. spatialdds-0.7.0/spatialdds/dds/types/spatial/events/enums/zone_kind_enum/_events.py +31 -0
  66. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/__init__.py +30 -0
  67. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/_mapping.py +168 -0
  68. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/enums/__init__.py +19 -0
  69. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/enums/alignment_method/__init__.py +11 -0
  70. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/enums/alignment_method/_mapping.py +31 -0
  71. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/enums/edge_type/__init__.py +11 -0
  72. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/enums/edge_type/_mapping.py +34 -0
  73. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/enums/map_event_kind/__init__.py +11 -0
  74. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/enums/map_event_kind/_mapping.py +29 -0
  75. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/enums/map_kind/__init__.py +11 -0
  76. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/enums/map_kind/_mapping.py +32 -0
  77. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/enums/map_status/__init__.py +11 -0
  78. spatialdds-0.7.0/spatialdds/dds/types/spatial/mapping/enums/map_status/_mapping.py +27 -0
  79. spatialdds-0.7.0/spatialdds/dds/types/spatial/owm/__init__.py +22 -0
  80. spatialdds-0.7.0/spatialdds/dds/types/spatial/owm/_owm.py +103 -0
  81. spatialdds-0.7.0/spatialdds/dds/types/spatial/semantics/__init__.py +22 -0
  82. spatialdds-0.7.0/spatialdds/dds/types/spatial/semantics/_semantics.py +174 -0
  83. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/__init__.py +21 -0
  84. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/common/__init__.py +34 -0
  85. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/common/_common.py +192 -0
  86. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/lidar/__init__.py +32 -0
  87. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/lidar/_lidar.py +135 -0
  88. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/rad/__init__.py +33 -0
  89. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/rad/_rad.py +191 -0
  90. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/radio/__init__.py +22 -0
  91. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/radio/_radio.py +141 -0
  92. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/rf_beam/__init__.py +25 -0
  93. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/rf_beam/_rf_beam.py +117 -0
  94. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/vision/__init__.py +36 -0
  95. spatialdds-0.7.0/spatialdds/dds/types/spatial/sensing/vision/_vision.py +171 -0
  96. spatialdds-0.7.0/spatialdds/dds/types/spatial/slam_frontend/__init__.py +22 -0
  97. spatialdds-0.7.0/spatialdds/dds/types/spatial/slam_frontend/_slam_frontend.py +144 -0
  98. spatialdds-0.7.0/spatialdds/dds/types/spatial/vio/__init__.py +20 -0
  99. spatialdds-0.7.0/spatialdds/dds/types/spatial/vio/_vio.py +134 -0
  100. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/demo/fountain-anchors.mcap +0 -0
  101. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/demo/manifests/content-fountain-label.json +1 -1
  102. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/demo/manifests/content-fountain-marker.json +1 -1
  103. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/errors.py +1 -1
  104. spatialdds-0.7.0/spatialdds/events.py +57 -0
  105. spatialdds-0.7.0/spatialdds/frames.py +222 -0
  106. spatialdds-0.7.0/spatialdds/journal.py +50 -0
  107. spatialdds-0.7.0/spatialdds/recency.py +119 -0
  108. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/records.py +118 -11
  109. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/serve.py +90 -17
  110. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/server/gateway.py +164 -21
  111. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/server/gw_http.py +373 -29
  112. spatialdds-0.7.0/spatialdds/server/limits.py +93 -0
  113. spatialdds-0.7.0/spatialdds/server/mcapmeta.py +19 -0
  114. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/server/pin.py +91 -17
  115. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/server/publish.py +191 -68
  116. spatialdds-0.7.0/spatialdds/server/tenancy.py +252 -0
  117. spatialdds-0.7.0/spatialdds/tokens.py +88 -0
  118. spatialdds-0.5.4/README.md → spatialdds-0.7.0/spatialdds.egg-info/PKG-INFO +198 -20
  119. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds.egg-info/SOURCES.txt +97 -0
  120. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds.egg-info/requires.txt +5 -0
  121. {spatialdds-0.5.4 → spatialdds-0.7.0}/setup.cfg +0 -0
  122. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/idl/core.idl +0 -0
  123. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/idl/discovery.idl +0 -0
  124. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/builtin_Time.json +0 -0
  125. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_anchors_AnchorDelta.json +0 -0
  126. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_anchors_AnchorEntry.json +0 -0
  127. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSet.json +0 -0
  128. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSetRequest.json +0 -0
  129. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSetResponse.json +0 -0
  130. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_argeo_NodeGeo.json +0 -0
  131. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_argeo_QualityRequirements.json +0 -0
  132. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_argeo_VpsRequest.json +0 -0
  133. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_argeo_VpsResponse.json +0 -0
  134. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_common_AssetRef.json +0 -0
  135. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_common_FrameRef.json +0 -0
  136. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_common_KV.json +0 -0
  137. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_common_MetaKV.json +0 -0
  138. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_common_Vec2.json +0 -0
  139. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_Aabb3.json +0 -0
  140. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_BlobChunk.json +0 -0
  141. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_BlobRef.json +0 -0
  142. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_ComponentRef.json +0 -0
  143. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_Edge.json +0 -0
  144. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_EntityBinding.json +0 -0
  145. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_FrameTransform.json +0 -0
  146. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_FramedPose.json +0 -0
  147. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_GeoAnchor.json +0 -0
  148. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_GeoPose.json +0 -0
  149. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_NavSatStatus.json +0 -0
  150. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_Node.json +0 -0
  151. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_PlannedTrajectory.json +0 -0
  152. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_PlannedWaypoint.json +0 -0
  153. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_PoseSE3.json +0 -0
  154. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_SnapshotRequest.json +0 -0
  155. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_SnapshotResponse.json +0 -0
  156. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_TileKey.json +0 -0
  157. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_TileMeta.json +0 -0
  158. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_core_TilePatch.json +0 -0
  159. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_Announce.json +0 -0
  160. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_Capabilities.json +0 -0
  161. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_ContentAnnounce.json +0 -0
  162. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_CoverageElement.json +0 -0
  163. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_CoverageFilter.json +0 -0
  164. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_CoverageHint.json +0 -0
  165. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_CoverageQuery.json +0 -0
  166. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_CoverageResponse.json +0 -0
  167. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_Depart.json +0 -0
  168. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_KV.json +0 -0
  169. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_ProfileSupport.json +0 -0
  170. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_ServiceSummary.json +0 -0
  171. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_TopicMeta.json +0 -0
  172. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_Transform.json +0 -0
  173. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_disco_ValidityWindow.json +0 -0
  174. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_events_CrossingLine.json +0 -0
  175. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_events_SpatialEvent.json +0 -0
  176. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_events_SpatialZone.json +0 -0
  177. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_events_ZoneState.json +0 -0
  178. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_mapping_Edge.json +0 -0
  179. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_mapping_MapAlignment.json +0 -0
  180. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_mapping_MapEvent.json +0 -0
  181. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_mapping_MapMeta.json +0 -0
  182. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_mapping_MapQuality.json +0 -0
  183. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_owm_Entity.json +0 -0
  184. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_owm_ModelCommand.json +0 -0
  185. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_owm_ModelPose.json +0 -0
  186. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_semantics_Detection2D.json +0 -0
  187. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_semantics_Detection2DSet.json +0 -0
  188. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_semantics_Detection3D.json +0 -0
  189. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_semantics_Detection3DSet.json +0 -0
  190. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_semantics_FusedTrack.json +0 -0
  191. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_semantics_FusedTrackSet.json +0 -0
  192. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_semantics_Keypoint3D.json +0 -0
  193. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_semantics_KeypointLink.json +0 -0
  194. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_common_Axis.json +0 -0
  195. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_common_FrameHeader.json +0 -0
  196. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_common_FrameQuality.json +0 -0
  197. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_common_Linspace.json +0 -0
  198. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_common_ROI.json +0 -0
  199. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_common_ROIReply.json +0 -0
  200. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_common_ROIRequest.json +0 -0
  201. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_common_StreamMeta.json +0 -0
  202. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarDetection.json +0 -0
  203. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarDetectionSet.json +0 -0
  204. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarFrame.json +0 -0
  205. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarMeta.json +0 -0
  206. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadDetection.json +0 -0
  207. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadDetectionSet.json +0 -0
  208. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadSensorMeta.json +0 -0
  209. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadTensorFrame.json +0 -0
  210. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadTensorMeta.json +0 -0
  211. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioObservation.json +0 -0
  212. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioScan.json +0 -0
  213. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioSensorMeta.json +0 -0
  214. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamArraySet.json +0 -0
  215. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamFrame.json +0 -0
  216. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamMeta.json +0 -0
  217. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_Keypoint2D.json +0 -0
  218. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_Track2D.json +0 -0
  219. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionDetections.json +0 -0
  220. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_CameraInfo.json +0 -0
  221. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_Feature2D.json +0 -0
  222. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_FeatureMatch.json +0 -0
  223. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_KeyframeFeatures.json +0 -0
  224. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_Landmark.json +0 -0
  225. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_MatchSet.json +0 -0
  226. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_TrackObs.json +0 -0
  227. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_Tracklet.json +0 -0
  228. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_vio_FusedState.json +0 -0
  229. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_vio_ImuInfo.json +0 -0
  230. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_vio_ImuSample.json +0 -0
  231. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_vio_MagnetometerSample.json +0 -0
  232. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/artifacts/schemas/spatial_vio_SensorFusionSample.json +0 -0
  233. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/canonical.py +0 -0
  234. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/canonjson.py +0 -0
  235. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/demo/assets/duck.gltf +0 -0
  236. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/demo/assets/fountain-label.txt +0 -0
  237. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/demo/assets/fountain-marker.gltf +0 -0
  238. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/server/__init__.py +0 -0
  239. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/server/commands.py +0 -0
  240. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/server/idlmodel.py +0 -0
  241. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/server/webjson.py +0 -0
  242. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds/server/xcdr2.py +0 -0
  243. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds.egg-info/dependency_links.txt +0 -0
  244. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds.egg-info/entry_points.txt +0 -0
  245. {spatialdds-0.5.4 → spatialdds-0.7.0}/spatialdds.egg-info/top_level.txt +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spatialdds
3
- Version: 0.5.4
4
- Summary: SpatialDDS over plain HTTPS and a WebSocket: a client for the web binding (Appendix N), and the reference registry behind one command.
3
+ Version: 0.7.0
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
7
- Project-URL: Homepage, https://github.com/OpenArCloud/spatialdds-web
7
+ Project-URL: Homepage, https://github.com/OpenArCloud/spatialdds-py
8
8
  Project-URL: Specification, https://github.com/OpenArCloud/SpatialDDS-spec
9
- Keywords: spatialdds,spatial,geopose,anchors,registry,openarcloud
9
+ Keywords: spatialdds,spatial,geopose,anchors,registry,dds,cyclonedds,openarcloud
10
10
  Classifier: Development Status :: 3 - Alpha
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: Apache Software License
@@ -21,15 +21,20 @@ Provides-Extra: server
21
21
  Requires-Dist: aiohttp>=3.8; extra == "server"
22
22
  Requires-Dist: mcap>=1.1; extra == "server"
23
23
  Requires-Dist: jsonschema>=4.0; extra == "server"
24
+ Provides-Extra: dds
25
+ Requires-Dist: cyclonedds<12,>=11.0.1; extra == "dds"
26
+ Requires-Dist: mcap>=1.1; extra == "dds"
27
+ Requires-Dist: jsonschema>=4.0; extra == "dds"
24
28
 
25
29
  # spatialdds
26
30
 
27
- SpatialDDS over plain HTTPS and a WebSocket: a client for programs, and the
28
- reference registry behind one command.
31
+ SpatialDDS for programs: a client over plain HTTPS and a WebSocket, a native
32
+ DDS participant, and the reference registry behind one command.
29
33
 
30
34
  ```sh
31
35
  pip install spatialdds # the client: two dependencies
32
36
  pip install "spatialdds[server]" # and the registry
37
+ pip install "spatialdds[dds]" # and a native DDS participant
33
38
  pip install "./lib/spatialdds[server]" # from a checkout of this repo
34
39
  ```
35
40
 
@@ -39,14 +44,110 @@ package is the step after that, when a program wants native values instead of
39
44
  canonical JSON, bytes it can trust, refusals it can act on, and records it did
40
45
  not have to assemble member by member.
41
46
 
42
- **Implements Appendix N as of SpatialDDS-spec `9c3e1f2`.** Package versions and
43
- specification versions move independently; `spatialdds.SPEC_COMMIT` is the one
44
- that says what the wire looks like.
47
+ **Implements Appendix N as of SpatialDDS-spec `v1.8` (`4b5652c`).** Package
48
+ versions and specification versions move independently; `spatialdds.SPEC_TAG`
49
+ and `spatialdds.SPEC_COMMIT` are the ones that say what the wire looks like.
45
50
 
46
51
  The source, the reference gateway, the recordings and every gate behind the
47
- claims on this page are at [https://github.com/OpenArCloud/spatialdds-web](https://github.com/OpenArCloud/spatialdds-web). Every code block below is executed
52
+ claims on this page are at [https://github.com/OpenArCloud/spatialdds-py](https://github.com/OpenArCloud/spatialdds-py). Every code block below is executed
48
53
  by one of those gates on every run, against an endpoint started for it.
49
54
 
55
+ ## A native participant, over DDS
56
+
57
+ The same package speaks SpatialDDS natively, beside `sd.connect`. Install the
58
+ `[dds]` extra (it brings cyclonedds), and a participant is a plain program:
59
+ an entity with an announce, pose updates, and a clean withdrawal on exit.
60
+
61
+ <!-- native: participant -->
62
+ ```python
63
+ import spatialdds as sd
64
+
65
+ with sd.participant("bare-scene", domain=42, service_id="svc:duck",
66
+ authority="registry.example") as p:
67
+ frame = sd.frame("map/bare-scene", convention="ENU", meters_per_unit=1.0)
68
+ duck = p.writer("model_entity", qos_profile="MAP_META", on_exit="withdraw")
69
+ pose = p.writer("model_pose", qos_profile=sd.dds.Profile(
70
+ "DUCK_POSE", reliability="BEST_EFFORT", durability="VOLATILE"))
71
+ p.announce("OTHER", coverage=sd.circle(30.2849, -97.7341, 50))
72
+ duck.write(sd.entity("ent:duck", frame_ref=frame, source_id="svc:duck"))
73
+ for i in p.loop(hz=5):
74
+ pose.write(sd.model_pose("ent:duck", position=(i * 0.1, 0, 0),
75
+ source_id="svc:duck"))
76
+ if i == 9:
77
+ break
78
+ print("stopped; the duck was withdrawn on the way out")
79
+ ```
80
+
81
+ ```console
82
+ stopped; the duck was withdrawn on the way out
83
+ ```
84
+
85
+ Anyone on the domain sees it, through the same four events the web client's
86
+ `subscribe()` yields:
87
+
88
+ <!-- native: reader -->
89
+ ```python
90
+ import spatialdds as sd
91
+
92
+ with sd.participant("bare-scene", domain=42) as p:
93
+ for ev in p.reader("model_entity", qos_profile="MAP_META").events(timeout=5):
94
+ if isinstance(ev, sd.Sample):
95
+ print("Sample", ev.key, ev.data.state.name)
96
+ elif isinstance(ev, sd.Dispose):
97
+ print("Dispose", ev.key, repr(ev.reason))
98
+ else:
99
+ print(type(ev).__name__)
100
+ ```
101
+
102
+ ```console
103
+ EndOfReplay
104
+ Sample ent:duck ACTIVE
105
+ Sample ent:duck RETIRED
106
+ Dispose ent:duck 'the participant stopped'
107
+ ```
108
+
109
+ What it asks of you, and what it will not guess:
110
+
111
+ | you say | or it refuses |
112
+ | --- | --- |
113
+ | `scene`, and `domain` (or `SPATIALDDS_DDS_DOMAIN`) | always: there is no default scene, and DDS's domain 0 is not a choice anyone made |
114
+ | `service_id` and `authority` | to write or announce |
115
+ | `qos_profile` | where the §3.3.2 row names none, as `model_entity`'s and `model_pose`'s do; the refusal lists the §3.3.3 profiles that fit, or pass a `sd.dds.Profile(...)` extension |
116
+ | `on_exit="keep"` or `"withdraw"` | on every latched, keyed writer: whether a record outlives its writer is a claim only you can make |
117
+ | `withdraw(key, reason=...)` | with an empty reason |
118
+
119
+ And what it does without being asked:
120
+
121
+ - **Writers never autodispose.** A participant that crashes reaches every
122
+ reader as `Liveliness(alive=False)` once its lease runs out. It is never a
123
+ `Dispose`, which is only ever somebody's `withdraw()`: a terminal sample,
124
+ then the dispose, with the reason.
125
+ - **A clean stop departs.** Each writer does what its `on_exit` said. Then the
126
+ announce sends its terminal sample, its dispose and a `Depart`, and every
127
+ writer waits for its acknowledgements.
128
+ - **The announce is kept fresh.** `tick()`, which `loop()` calls, refreshes it
129
+ every `ttl_sec / 3`, and its `topics` are the writers you opened. `floor_hz=`
130
+ keeps a stationary publisher's records fresh too.
131
+ - **Every sample is validated** against the published JSON Schema before it is
132
+ written.
133
+
134
+ `Sample.data` is the typed sample (`sd.dds.types` carries every type in the
135
+ pinned IDL). `sd.dds.to_json(sample)` is its N.1 form, produced by the gateway's
136
+ own codec, so a native sample and a served one cannot disagree.
137
+
138
+ Without the extra, `import spatialdds` is unchanged, and `sd.participant`
139
+ raises `sd.MissingExtra` naming it. Two modules are pure Python and need
140
+ nothing:
141
+
142
+ - `sd.frames`: one copy of the ENU↔ECEF arithmetic, with composition that
143
+ never guesses a position;
144
+ - `sd.Recency`: learned per-key idle thresholds for fast lanes.
145
+
146
+ `sd.events` holds the four event classes both transports share; `sd.dds` is the
147
+ layer itself. Request and reply (VPS, coverage queries) is documented as a
148
+ convention, not built, until 1.9 settles it:
149
+ [REQUEST-REPLY.md](https://github.com/OpenArCloud/spatialdds-py/blob/main/docs/REQUEST-REPLY.md).
150
+
50
151
  ## Your own registry, in one command
51
152
 
52
153
  ```sh
@@ -133,9 +234,9 @@ limits {'max_fps': 10}
133
234
  ```
134
235
 
135
236
  Every one of those is something a service operator knows and a library cannot
136
- guess. [The mytown walkthrough](https://github.com/OpenArCloud/spatialdds-web/blob/main/docs/MYTOWN.md) publishes that
237
+ guess. [The mytown walkthrough](https://github.com/OpenArCloud/spatialdds-py/blob/main/docs/MYTOWN.md) publishes that
137
238
  and prints the whole served document;
138
- [`gates/builders.py`](https://github.com/OpenArCloud/spatialdds-web/blob/main/gates/builders.py) rebuilds that
239
+ [`gates/builders.py`](https://github.com/OpenArCloud/spatialdds-py/blob/main/gates/builders.py) rebuilds that
139
240
  repository's hand-authored `austin-vps` and duck records through these calls
140
241
  and compares them member by member, which is what makes "every member is
141
242
  reachable from an argument" a check rather than a claim.
@@ -147,7 +248,7 @@ and the byte count itself: a hash nobody typed is a hash a reader can trust.
147
248
  else hosts, and the hash comes from whoever has the bytes. Pass no hash and
148
249
  the reference carries no integrity claim, which costs a reader one thing:
149
250
  `fetch_asset()` raises rather than reporting a check it could not perform
150
- ([finding 31](https://github.com/OpenArCloud/spatialdds-web/blob/main/WEB-BINDING-FINDINGS.md)).
251
+ ([finding 31](https://github.com/OpenArCloud/spatialdds-py/blob/main/WEB-BINDING-FINDINGS.md)).
151
252
  `publish_content` takes either, or a path, or bytes, or a URL.
152
253
 
153
254
  The builders are also usable on their own: `sd.service_announce`,
@@ -179,7 +280,7 @@ they never fill is **identity**: `provider_id` and `org` are yours to state,
179
280
  because a library that invented a provider id would be inventing provenance.
180
281
 
181
282
  `GeoAnchor.checksum` is required by 1.8 and specified by nobody
182
- (spatialdds-web finding 31). The builder fills it with the SHA-256 of the
283
+ (spatialdds-py finding 31). The builder fills it with the SHA-256 of the
183
284
  record's own canonical JSON with `checksum` emptied -- a convention, chosen
184
285
  because a reader can recompute it from what was served. If the specification
185
286
  settles the semantics, this changes.
@@ -271,7 +372,7 @@ declared.
271
372
  <!-- bar: resolve -->
272
373
  ```python
273
374
  import json, spatialdds as sd
274
- ep = sd.connect("http://127.0.0.1:8787", token="not-a-secret"); ep.publish_manifest(json.load(open("samples/duck.input.json"))["manifest"]); print(len(ep.resolve("spatialdds://demo.spatialdds.org/south-mall/content/duck").fetch_asset()), "bytes verified")
375
+ ep = sd.connect("http://127.0.0.1:8787", token="not-a-secret"); ep.publish_manifest(json.load(open("samples/duck.input.json"))["manifest"]); print(len(ep.resolve("spatialdds://demo.spatialdds.org/ut-austin-south-mall/content/duck").fetch_asset()), "bytes verified")
275
376
  ```
276
377
 
277
378
  ```console
@@ -286,7 +387,7 @@ call goes away and the bar is one line.
286
387
 
287
388
  | call | what it does |
288
389
  | --- | --- |
289
- | `sd.connect(base, token=None, verify_integrity=True, timeout=15.0, lifted=True, scene="default", authority=None)` | an `Endpoint`; nothing is fetched until you ask |
390
+ | `sd.connect(base, token=None, verify_integrity=True, timeout=15.0, lifted=True, scene=None, authority=None)` | an `Endpoint`; nothing is fetched until you ask. `scene` is the lane the publish verbs write; unset, they refuse rather than guess |
290
391
  | `ep.search(geohash=None, kinds=None)` | §3.3.0 search → a list of `Hit` |
291
392
  | `ep.near(lat, lon, radius_m)` | a helper over `search`, never a second protocol |
292
393
  | `ep.resolve(uri)` | §7.5.2 resolution → `Resolved` |
@@ -313,7 +414,7 @@ call goes away and the bar is one line.
313
414
  | `sd.asset(path_or_bytes, media_type=)` / `sd.asset_ref(url, hash=, media_type=)` | an asset hashed from its bytes, or a reference to one hosted elsewhere |
314
415
  | `sd.records` | the builders, listed above |
315
416
  | `sd.lift(fqn, doc)` | the lift on its own, for JSON you already have |
316
- | `sd.SPEC_COMMIT`, `sd.APPENDIX_N`, `sd.__version__` | what this speaks |
417
+ | `sd.SPEC_TAG`, `sd.SPEC_COMMIT`, `sd.APPENDIX_N`, `sd.__version__` | what this speaks |
317
418
 
318
419
  `ep.near()` picks a geohash precision whose cell covers the radius, encodes the
319
420
  centre and eight points around the query circle so the covering cells are found
@@ -346,7 +447,7 @@ One family, built from the endpoint's own N.8 problem documents — `status`,
346
447
 
347
448
  That last one is the unusual one and it is deliberate. SpatialDDS counts "a
348
449
  checksum field in the body" as a §7.5.2 integrity signal, but nothing specifies
349
- what such a field digests or in what form (spatialdds-web finding 31). Where a
450
+ what such a field digests or in what form (spatialdds-py finding 31). Where a
350
451
  declared value does not parse as a SHA-256 of the asset's bytes, this library
351
452
  raises rather than reporting a check it did not perform.
352
453
 
@@ -471,12 +572,65 @@ explicitly was tried first and is what missed two paths.
471
572
 
472
573
  If your clients are not browsers, nothing here changes anything for you.
473
574
 
474
- ## Not in 0.5.4
475
-
476
- Stated so nobody waits for them: no async API, no caching beyond ETag
477
- revalidation, no retry policy, no MCAP tooling beyond the journal the server
478
- writes, no client-side command helper, and no DDS dependency of any kind. The
479
- wire is HTTP and a WebSocket.
575
+ ## New in 0.7.0: a native participant, and the v1.8 tag
576
+
577
+ - **The package speaks DDS natively.** `sd.participant(...)`, under the `[dds]`
578
+ extra, is described at the top of this page. It takes the conventions as
579
+ code and leaves the program a plain program.
580
+ - **One pin, the `v1.8` tag**, for everything vendored: the schemas, the IDL,
581
+ the native bindings and the registry its QoS comes from.
582
+ - **Four-segment topics.** The gateway now serves them at their well-known
583
+ paths, where it used to drop them.
584
+ - **Recordings carry their disposes.** A recording's withdrawals are served
585
+ with their reasons.
586
+
587
+ Two changes may need a line of yours:
588
+
589
+ - **`sd.topic()` derives durability from a registered `qos_profile`.** It used
590
+ to say `TRANSIENT_LOCAL` whatever the profile was. For a templated type
591
+ (`model_entity`) it uses the template's name.
592
+ - **`sd.Sample` and friends moved to `spatialdds.events`.** They are
593
+ re-exported where they were.
594
+
595
+ The repository is now
596
+ [spatialdds-py](https://github.com/OpenArCloud/spatialdds-py), and the package
597
+ name is unchanged. Details are in the
598
+ [changelog](https://github.com/OpenArCloud/spatialdds-py/blob/main/lib/spatialdds/CHANGELOG.md).
599
+
600
+ ## New in 0.6.0: lanes, hardening, OpenAPI
601
+
602
+ One registry can now take several publishers. Each one holds a token scoped to
603
+ the scenes it may write, issued with `python -m spatialdds.tokens` and served
604
+ with `--tokens`. A write outside its lane is a `403` naming the scene, and
605
+ reads stay open. Manifests can be withdrawn, and the journal records who wrote
606
+ each entry. The REST surface is published as OpenAPI 3.1 at
607
+ `/.well-known/spatialdds/openapi`. Every limit refuses with a problem document
608
+ naming its number.
609
+
610
+ Two changes may need a line of yours:
611
+
612
+ - **Publishing needs a scene.** The client's publish verbs refuse when no
613
+ scene is set, where they used to write into `default`. Pass `scene=`.
614
+ - **The demo's manifest URIs changed.** They name the scene now,
615
+ `…/ut-austin-south-mall/…`.
616
+
617
+ The security fixes, the limits table and the details are in the
618
+ [changelog](https://github.com/OpenArCloud/spatialdds-py/blob/main/lib/spatialdds/CHANGELOG.md).
619
+
620
+ ## Not in 0.7.0
621
+
622
+ Stated so nobody waits for them:
623
+
624
+ - no async API;
625
+ - no caching beyond ETag revalidation;
626
+ - no retry policy;
627
+ - no client-side command helper;
628
+ - no request/reply machinery in the native layer. VPS and coverage queries are
629
+ a documented convention until 1.9 settles their shape;
630
+ - no C++ or other-language port.
631
+
632
+ The web client still has no DDS dependency of any kind: cyclonedds arrives
633
+ only with `[dds]`.
480
634
 
481
635
  0.4.0 added the N.6 command surface described above; 0.5.0 made it usable
482
636
  from an embedder with a live source, which is two releases for one capability
@@ -1,35 +1,12 @@
1
- Metadata-Version: 2.4
2
- Name: spatialdds
3
- Version: 0.5.4
4
- Summary: SpatialDDS over plain HTTPS and a WebSocket: a client for the web binding (Appendix N), and the reference registry behind one command.
5
- Author: Open AR Cloud
6
- License: Apache-2.0
7
- Project-URL: Homepage, https://github.com/OpenArCloud/spatialdds-web
8
- Project-URL: Specification, https://github.com/OpenArCloud/SpatialDDS-spec
9
- Keywords: spatialdds,spatial,geopose,anchors,registry,openarcloud
10
- Classifier: Development Status :: 3 - Alpha
11
- Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: Apache Software License
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3 :: Only
15
- Classifier: Topic :: Scientific/Engineering :: GIS
16
- Requires-Python: >=3.9
17
- Description-Content-Type: text/markdown
18
- Requires-Dist: requests>=2.25
19
- Requires-Dist: websockets>=12
20
- Provides-Extra: server
21
- Requires-Dist: aiohttp>=3.8; extra == "server"
22
- Requires-Dist: mcap>=1.1; extra == "server"
23
- Requires-Dist: jsonschema>=4.0; extra == "server"
24
-
25
1
  # spatialdds
26
2
 
27
- SpatialDDS over plain HTTPS and a WebSocket: a client for programs, and the
28
- reference registry behind one command.
3
+ SpatialDDS for programs: a client over plain HTTPS and a WebSocket, a native
4
+ DDS participant, and the reference registry behind one command.
29
5
 
30
6
  ```sh
31
7
  pip install spatialdds # the client: two dependencies
32
8
  pip install "spatialdds[server]" # and the registry
9
+ pip install "spatialdds[dds]" # and a native DDS participant
33
10
  pip install "./lib/spatialdds[server]" # from a checkout of this repo
34
11
  ```
35
12
 
@@ -39,14 +16,110 @@ package is the step after that, when a program wants native values instead of
39
16
  canonical JSON, bytes it can trust, refusals it can act on, and records it did
40
17
  not have to assemble member by member.
41
18
 
42
- **Implements Appendix N as of SpatialDDS-spec `9c3e1f2`.** Package versions and
43
- specification versions move independently; `spatialdds.SPEC_COMMIT` is the one
44
- that says what the wire looks like.
19
+ **Implements Appendix N as of SpatialDDS-spec `v1.8` (`4b5652c`).** Package
20
+ versions and specification versions move independently; `spatialdds.SPEC_TAG`
21
+ and `spatialdds.SPEC_COMMIT` are the ones that say what the wire looks like.
45
22
 
46
23
  The source, the reference gateway, the recordings and every gate behind the
47
- claims on this page are at [https://github.com/OpenArCloud/spatialdds-web](https://github.com/OpenArCloud/spatialdds-web). Every code block below is executed
24
+ claims on this page are at [https://github.com/OpenArCloud/spatialdds-py](https://github.com/OpenArCloud/spatialdds-py). Every code block below is executed
48
25
  by one of those gates on every run, against an endpoint started for it.
49
26
 
27
+ ## A native participant, over DDS
28
+
29
+ The same package speaks SpatialDDS natively, beside `sd.connect`. Install the
30
+ `[dds]` extra (it brings cyclonedds), and a participant is a plain program:
31
+ an entity with an announce, pose updates, and a clean withdrawal on exit.
32
+
33
+ <!-- native: participant -->
34
+ ```python
35
+ import spatialdds as sd
36
+
37
+ with sd.participant("bare-scene", domain=42, service_id="svc:duck",
38
+ authority="registry.example") as p:
39
+ frame = sd.frame("map/bare-scene", convention="ENU", meters_per_unit=1.0)
40
+ duck = p.writer("model_entity", qos_profile="MAP_META", on_exit="withdraw")
41
+ pose = p.writer("model_pose", qos_profile=sd.dds.Profile(
42
+ "DUCK_POSE", reliability="BEST_EFFORT", durability="VOLATILE"))
43
+ p.announce("OTHER", coverage=sd.circle(30.2849, -97.7341, 50))
44
+ duck.write(sd.entity("ent:duck", frame_ref=frame, source_id="svc:duck"))
45
+ for i in p.loop(hz=5):
46
+ pose.write(sd.model_pose("ent:duck", position=(i * 0.1, 0, 0),
47
+ source_id="svc:duck"))
48
+ if i == 9:
49
+ break
50
+ print("stopped; the duck was withdrawn on the way out")
51
+ ```
52
+
53
+ ```console
54
+ stopped; the duck was withdrawn on the way out
55
+ ```
56
+
57
+ Anyone on the domain sees it, through the same four events the web client's
58
+ `subscribe()` yields:
59
+
60
+ <!-- native: reader -->
61
+ ```python
62
+ import spatialdds as sd
63
+
64
+ with sd.participant("bare-scene", domain=42) as p:
65
+ for ev in p.reader("model_entity", qos_profile="MAP_META").events(timeout=5):
66
+ if isinstance(ev, sd.Sample):
67
+ print("Sample", ev.key, ev.data.state.name)
68
+ elif isinstance(ev, sd.Dispose):
69
+ print("Dispose", ev.key, repr(ev.reason))
70
+ else:
71
+ print(type(ev).__name__)
72
+ ```
73
+
74
+ ```console
75
+ EndOfReplay
76
+ Sample ent:duck ACTIVE
77
+ Sample ent:duck RETIRED
78
+ Dispose ent:duck 'the participant stopped'
79
+ ```
80
+
81
+ What it asks of you, and what it will not guess:
82
+
83
+ | you say | or it refuses |
84
+ | --- | --- |
85
+ | `scene`, and `domain` (or `SPATIALDDS_DDS_DOMAIN`) | always: there is no default scene, and DDS's domain 0 is not a choice anyone made |
86
+ | `service_id` and `authority` | to write or announce |
87
+ | `qos_profile` | where the §3.3.2 row names none, as `model_entity`'s and `model_pose`'s do; the refusal lists the §3.3.3 profiles that fit, or pass a `sd.dds.Profile(...)` extension |
88
+ | `on_exit="keep"` or `"withdraw"` | on every latched, keyed writer: whether a record outlives its writer is a claim only you can make |
89
+ | `withdraw(key, reason=...)` | with an empty reason |
90
+
91
+ And what it does without being asked:
92
+
93
+ - **Writers never autodispose.** A participant that crashes reaches every
94
+ reader as `Liveliness(alive=False)` once its lease runs out. It is never a
95
+ `Dispose`, which is only ever somebody's `withdraw()`: a terminal sample,
96
+ then the dispose, with the reason.
97
+ - **A clean stop departs.** Each writer does what its `on_exit` said. Then the
98
+ announce sends its terminal sample, its dispose and a `Depart`, and every
99
+ writer waits for its acknowledgements.
100
+ - **The announce is kept fresh.** `tick()`, which `loop()` calls, refreshes it
101
+ every `ttl_sec / 3`, and its `topics` are the writers you opened. `floor_hz=`
102
+ keeps a stationary publisher's records fresh too.
103
+ - **Every sample is validated** against the published JSON Schema before it is
104
+ written.
105
+
106
+ `Sample.data` is the typed sample (`sd.dds.types` carries every type in the
107
+ pinned IDL). `sd.dds.to_json(sample)` is its N.1 form, produced by the gateway's
108
+ own codec, so a native sample and a served one cannot disagree.
109
+
110
+ Without the extra, `import spatialdds` is unchanged, and `sd.participant`
111
+ raises `sd.MissingExtra` naming it. Two modules are pure Python and need
112
+ nothing:
113
+
114
+ - `sd.frames`: one copy of the ENU↔ECEF arithmetic, with composition that
115
+ never guesses a position;
116
+ - `sd.Recency`: learned per-key idle thresholds for fast lanes.
117
+
118
+ `sd.events` holds the four event classes both transports share; `sd.dds` is the
119
+ layer itself. Request and reply (VPS, coverage queries) is documented as a
120
+ convention, not built, until 1.9 settles it:
121
+ [REQUEST-REPLY.md](https://github.com/OpenArCloud/spatialdds-py/blob/main/docs/REQUEST-REPLY.md).
122
+
50
123
  ## Your own registry, in one command
51
124
 
52
125
  ```sh
@@ -133,9 +206,9 @@ limits {'max_fps': 10}
133
206
  ```
134
207
 
135
208
  Every one of those is something a service operator knows and a library cannot
136
- guess. [The mytown walkthrough](https://github.com/OpenArCloud/spatialdds-web/blob/main/docs/MYTOWN.md) publishes that
209
+ guess. [The mytown walkthrough](https://github.com/OpenArCloud/spatialdds-py/blob/main/docs/MYTOWN.md) publishes that
137
210
  and prints the whole served document;
138
- [`gates/builders.py`](https://github.com/OpenArCloud/spatialdds-web/blob/main/gates/builders.py) rebuilds that
211
+ [`gates/builders.py`](https://github.com/OpenArCloud/spatialdds-py/blob/main/gates/builders.py) rebuilds that
139
212
  repository's hand-authored `austin-vps` and duck records through these calls
140
213
  and compares them member by member, which is what makes "every member is
141
214
  reachable from an argument" a check rather than a claim.
@@ -147,7 +220,7 @@ and the byte count itself: a hash nobody typed is a hash a reader can trust.
147
220
  else hosts, and the hash comes from whoever has the bytes. Pass no hash and
148
221
  the reference carries no integrity claim, which costs a reader one thing:
149
222
  `fetch_asset()` raises rather than reporting a check it could not perform
150
- ([finding 31](https://github.com/OpenArCloud/spatialdds-web/blob/main/WEB-BINDING-FINDINGS.md)).
223
+ ([finding 31](https://github.com/OpenArCloud/spatialdds-py/blob/main/WEB-BINDING-FINDINGS.md)).
151
224
  `publish_content` takes either, or a path, or bytes, or a URL.
152
225
 
153
226
  The builders are also usable on their own: `sd.service_announce`,
@@ -179,7 +252,7 @@ they never fill is **identity**: `provider_id` and `org` are yours to state,
179
252
  because a library that invented a provider id would be inventing provenance.
180
253
 
181
254
  `GeoAnchor.checksum` is required by 1.8 and specified by nobody
182
- (spatialdds-web finding 31). The builder fills it with the SHA-256 of the
255
+ (spatialdds-py finding 31). The builder fills it with the SHA-256 of the
183
256
  record's own canonical JSON with `checksum` emptied -- a convention, chosen
184
257
  because a reader can recompute it from what was served. If the specification
185
258
  settles the semantics, this changes.
@@ -271,7 +344,7 @@ declared.
271
344
  <!-- bar: resolve -->
272
345
  ```python
273
346
  import json, spatialdds as sd
274
- ep = sd.connect("http://127.0.0.1:8787", token="not-a-secret"); ep.publish_manifest(json.load(open("samples/duck.input.json"))["manifest"]); print(len(ep.resolve("spatialdds://demo.spatialdds.org/south-mall/content/duck").fetch_asset()), "bytes verified")
347
+ ep = sd.connect("http://127.0.0.1:8787", token="not-a-secret"); ep.publish_manifest(json.load(open("samples/duck.input.json"))["manifest"]); print(len(ep.resolve("spatialdds://demo.spatialdds.org/ut-austin-south-mall/content/duck").fetch_asset()), "bytes verified")
275
348
  ```
276
349
 
277
350
  ```console
@@ -286,7 +359,7 @@ call goes away and the bar is one line.
286
359
 
287
360
  | call | what it does |
288
361
  | --- | --- |
289
- | `sd.connect(base, token=None, verify_integrity=True, timeout=15.0, lifted=True, scene="default", authority=None)` | an `Endpoint`; nothing is fetched until you ask |
362
+ | `sd.connect(base, token=None, verify_integrity=True, timeout=15.0, lifted=True, scene=None, authority=None)` | an `Endpoint`; nothing is fetched until you ask. `scene` is the lane the publish verbs write; unset, they refuse rather than guess |
290
363
  | `ep.search(geohash=None, kinds=None)` | §3.3.0 search → a list of `Hit` |
291
364
  | `ep.near(lat, lon, radius_m)` | a helper over `search`, never a second protocol |
292
365
  | `ep.resolve(uri)` | §7.5.2 resolution → `Resolved` |
@@ -313,7 +386,7 @@ call goes away and the bar is one line.
313
386
  | `sd.asset(path_or_bytes, media_type=)` / `sd.asset_ref(url, hash=, media_type=)` | an asset hashed from its bytes, or a reference to one hosted elsewhere |
314
387
  | `sd.records` | the builders, listed above |
315
388
  | `sd.lift(fqn, doc)` | the lift on its own, for JSON you already have |
316
- | `sd.SPEC_COMMIT`, `sd.APPENDIX_N`, `sd.__version__` | what this speaks |
389
+ | `sd.SPEC_TAG`, `sd.SPEC_COMMIT`, `sd.APPENDIX_N`, `sd.__version__` | what this speaks |
317
390
 
318
391
  `ep.near()` picks a geohash precision whose cell covers the radius, encodes the
319
392
  centre and eight points around the query circle so the covering cells are found
@@ -346,7 +419,7 @@ One family, built from the endpoint's own N.8 problem documents — `status`,
346
419
 
347
420
  That last one is the unusual one and it is deliberate. SpatialDDS counts "a
348
421
  checksum field in the body" as a §7.5.2 integrity signal, but nothing specifies
349
- what such a field digests or in what form (spatialdds-web finding 31). Where a
422
+ what such a field digests or in what form (spatialdds-py finding 31). Where a
350
423
  declared value does not parse as a SHA-256 of the asset's bytes, this library
351
424
  raises rather than reporting a check it did not perform.
352
425
 
@@ -471,12 +544,65 @@ explicitly was tried first and is what missed two paths.
471
544
 
472
545
  If your clients are not browsers, nothing here changes anything for you.
473
546
 
474
- ## Not in 0.5.4
475
-
476
- Stated so nobody waits for them: no async API, no caching beyond ETag
477
- revalidation, no retry policy, no MCAP tooling beyond the journal the server
478
- writes, no client-side command helper, and no DDS dependency of any kind. The
479
- wire is HTTP and a WebSocket.
547
+ ## New in 0.7.0: a native participant, and the v1.8 tag
548
+
549
+ - **The package speaks DDS natively.** `sd.participant(...)`, under the `[dds]`
550
+ extra, is described at the top of this page. It takes the conventions as
551
+ code and leaves the program a plain program.
552
+ - **One pin, the `v1.8` tag**, for everything vendored: the schemas, the IDL,
553
+ the native bindings and the registry its QoS comes from.
554
+ - **Four-segment topics.** The gateway now serves them at their well-known
555
+ paths, where it used to drop them.
556
+ - **Recordings carry their disposes.** A recording's withdrawals are served
557
+ with their reasons.
558
+
559
+ Two changes may need a line of yours:
560
+
561
+ - **`sd.topic()` derives durability from a registered `qos_profile`.** It used
562
+ to say `TRANSIENT_LOCAL` whatever the profile was. For a templated type
563
+ (`model_entity`) it uses the template's name.
564
+ - **`sd.Sample` and friends moved to `spatialdds.events`.** They are
565
+ re-exported where they were.
566
+
567
+ The repository is now
568
+ [spatialdds-py](https://github.com/OpenArCloud/spatialdds-py), and the package
569
+ name is unchanged. Details are in the
570
+ [changelog](https://github.com/OpenArCloud/spatialdds-py/blob/main/lib/spatialdds/CHANGELOG.md).
571
+
572
+ ## New in 0.6.0: lanes, hardening, OpenAPI
573
+
574
+ One registry can now take several publishers. Each one holds a token scoped to
575
+ the scenes it may write, issued with `python -m spatialdds.tokens` and served
576
+ with `--tokens`. A write outside its lane is a `403` naming the scene, and
577
+ reads stay open. Manifests can be withdrawn, and the journal records who wrote
578
+ each entry. The REST surface is published as OpenAPI 3.1 at
579
+ `/.well-known/spatialdds/openapi`. Every limit refuses with a problem document
580
+ naming its number.
581
+
582
+ Two changes may need a line of yours:
583
+
584
+ - **Publishing needs a scene.** The client's publish verbs refuse when no
585
+ scene is set, where they used to write into `default`. Pass `scene=`.
586
+ - **The demo's manifest URIs changed.** They name the scene now,
587
+ `…/ut-austin-south-mall/…`.
588
+
589
+ The security fixes, the limits table and the details are in the
590
+ [changelog](https://github.com/OpenArCloud/spatialdds-py/blob/main/lib/spatialdds/CHANGELOG.md).
591
+
592
+ ## Not in 0.7.0
593
+
594
+ Stated so nobody waits for them:
595
+
596
+ - no async API;
597
+ - no caching beyond ETag revalidation;
598
+ - no retry policy;
599
+ - no client-side command helper;
600
+ - no request/reply machinery in the native layer. VPS and coverage queries are
601
+ a documented convention until 1.9 settles their shape;
602
+ - no C++ or other-language port.
603
+
604
+ The web client still has no DDS dependency of any kind: cyclonedds arrives
605
+ only with `[dds]`.
480
606
 
481
607
  0.4.0 added the N.6 command surface described above; 0.5.0 made it usable
482
608
  from an embedder with a live source, which is two releases for one capability
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "spatialdds"
7
- version = "0.5.4"
8
- description = "SpatialDDS over plain HTTPS and a WebSocket: a client for the web binding (Appendix N), and the reference registry behind one command."
7
+ version = "0.7.0"
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"
11
11
  license = { text = "Apache-2.0" }
12
12
  authors = [{ name = "Open AR Cloud" }]
13
- keywords = ["spatialdds", "spatial", "geopose", "anchors", "registry", "openarcloud"]
13
+ keywords = ["spatialdds", "spatial", "geopose", "anchors", "registry", "dds", "cyclonedds", "openarcloud"]
14
14
  classifiers = [
15
15
  "Development Status :: 3 - Alpha",
16
16
  "Intended Audience :: Developers",
@@ -32,16 +32,27 @@ dependencies = ["requests>=2.25", "websockets>=12"]
32
32
  # every publish with a 500 rather than accept something unvalidated, so
33
33
  # leaving it out of this group would ship a registry nobody can publish into.
34
34
  server = ["aiohttp>=3.8", "mcap>=1.1", "jsonschema>=4.0"]
35
+ # Being a native DDS participant: `sd.participant(...)` beside `sd.connect(...)`.
36
+ # cyclonedds is the binding the generated types and every endpoint use; 11.0.1
37
+ # is the only version any of the four repositories the native layer replaces
38
+ # had tested. mcap is the recording tap's format, and jsonschema validates
39
+ # every written sample against the published schema before it reaches the bus.
40
+ # Without this extra `import spatialdds` is unchanged, and `sd.participant`
41
+ # raises `sd.MissingExtra` naming it.
42
+ dds = ["cyclonedds>=11.0.1,<12", "mcap>=1.1", "jsonschema>=4.0"]
35
43
 
36
44
  [project.scripts]
37
45
  spatialdds-serve = "spatialdds.serve:main"
38
46
 
39
47
  [project.urls]
40
- Homepage = "https://github.com/OpenArCloud/spatialdds-web"
48
+ Homepage = "https://github.com/OpenArCloud/spatialdds-py"
41
49
  Specification = "https://github.com/OpenArCloud/SpatialDDS-spec"
42
50
 
43
- [tool.setuptools]
44
- packages = ["spatialdds", "spatialdds.server"]
51
+ # Found rather than listed: the native layer's generated bindings are a tree
52
+ # of subpackages (`spatialdds.dds.types.spatial.core`, ...), and a hand list
53
+ # is how one of them would go missing from a wheel.
54
+ [tool.setuptools.packages.find]
55
+ include = ["spatialdds", "spatialdds.*"]
45
56
 
46
57
  [tool.setuptools.package-data]
47
58
  # Everything vendored travels with the package, because the point of 0.2.0 is
@@ -49,19 +60,30 @@ packages = ["spatialdds", "spatialdds.server"]
49
60
  #
50
61
  # * `artifacts/serializer_tables.json` -- what the lift reads, in both
51
62
  # directions. A client has no recording to learn the types from.
63
+ # * `artifacts/registry.json` -- §3.3.2's types, §3.3.3's QoS profiles and the
64
+ # well-known topics, generated from the spec text at the pin by
65
+ # `tools/gen_registry.py`; `gates/native_registry.py` guards the drift.
52
66
  # * `artifacts/schemas/*.json` -- the 112 generated JSON Schemas. The endpoint
53
67
  # publishes them and validates against them, and §8.4's third-party reader
54
68
  # has nothing else to go on.
55
- # * `artifacts/idl/*.idl` -- the pinned IDL. A registry that starts empty
56
- # boots its types from this; the tables cannot stand in because they carry
57
- # no `@key`, so a keyed resource would have no instance names.
69
+ # * `artifacts/idl/**.idl` -- the pinned IDL, the whole v1.8 tree. A registry
70
+ # that starts empty boots its types from this (the tables cannot stand in:
71
+ # they carry no `@key`), and the native layer's bindings are generated from
72
+ # it and its codec models it.
58
73
  # * `demo/**` -- the fountain set `--demo` serves. Byte-identical to the
59
74
  # repository's `samples/` copy, which `tools/pack_demo.py` maintains and
60
75
  # `gates/serve_demo.py` checks.
76
+ # * `artifacts/openapi.{yaml,html}` -- the REST surface's OpenAPI document and
77
+ # its static reference page, generated by `tools/gen_openapi.py` and served
78
+ # at /.well-known/spatialdds/openapi; `gates/openapi.py` guards the drift.
61
79
  spatialdds = [
62
80
  "artifacts/serializer_tables.json",
81
+ "artifacts/registry.json",
82
+ "artifacts/openapi.yaml",
83
+ "artifacts/openapi.html",
63
84
  "artifacts/schemas/*.json",
64
85
  "artifacts/idl/*.idl",
86
+ "artifacts/idl/provisional/*.idl",
65
87
  "demo/*.mcap",
66
88
  "demo/manifests/*.json",
67
89
  "demo/assets/*",