spatialdds 0.5.3__tar.gz → 0.6.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.
- {spatialdds-0.5.3 → spatialdds-0.6.0}/PKG-INFO +43 -5
- {spatialdds-0.5.3 → spatialdds-0.6.0}/README.md +42 -4
- {spatialdds-0.5.3 → spatialdds-0.6.0}/pyproject.toml +6 -1
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/__init__.py +1 -1
- spatialdds-0.6.0/spatialdds/artifacts/openapi.html +17 -0
- spatialdds-0.6.0/spatialdds/artifacts/openapi.yaml +6442 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/client.py +48 -10
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/demo/fountain-anchors.mcap +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/demo/manifests/content-fountain-label.json +1 -1
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/demo/manifests/content-fountain-marker.json +1 -1
- spatialdds-0.6.0/spatialdds/journal.py +50 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/serve.py +78 -8
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/server/gateway.py +13 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/server/gw_http.py +401 -28
- spatialdds-0.6.0/spatialdds/server/limits.py +93 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/server/publish.py +178 -63
- spatialdds-0.6.0/spatialdds/server/tenancy.py +252 -0
- spatialdds-0.6.0/spatialdds/tokens.py +88 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds.egg-info/PKG-INFO +43 -5
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds.egg-info/SOURCES.txt +6 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/setup.cfg +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/idl/core.idl +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/idl/discovery.idl +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/idl/types.idl +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/builtin_Time.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_anchors_AnchorDelta.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_anchors_AnchorEntry.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSet.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSetRequest.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSetResponse.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_argeo_NodeGeo.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_argeo_QualityRequirements.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_argeo_VpsRequest.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_argeo_VpsResponse.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_common_AssetRef.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_common_FrameRef.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_common_KV.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_common_MetaKV.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_common_Vec2.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_Aabb3.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_BlobChunk.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_BlobRef.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_ComponentRef.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_Edge.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_EntityBinding.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_FrameTransform.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_FramedPose.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_GeoAnchor.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_GeoPose.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_NavSatStatus.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_Node.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_PlannedTrajectory.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_PlannedWaypoint.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_PoseSE3.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_SnapshotRequest.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_SnapshotResponse.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_TileKey.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_TileMeta.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_core_TilePatch.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_Announce.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_Capabilities.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_ContentAnnounce.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_CoverageElement.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_CoverageFilter.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_CoverageHint.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_CoverageQuery.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_CoverageResponse.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_Depart.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_KV.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_ProfileSupport.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_ServiceSummary.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_TopicMeta.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_Transform.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_disco_ValidityWindow.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_events_CrossingLine.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_events_SpatialEvent.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_events_SpatialZone.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_events_ZoneState.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_mapping_Edge.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_mapping_MapAlignment.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_mapping_MapEvent.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_mapping_MapMeta.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_mapping_MapQuality.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_owm_Entity.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_owm_ModelCommand.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_owm_ModelPose.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_semantics_Detection2D.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_semantics_Detection2DSet.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_semantics_Detection3D.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_semantics_Detection3DSet.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_semantics_FusedTrack.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_semantics_FusedTrackSet.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_semantics_Keypoint3D.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_semantics_KeypointLink.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_common_Axis.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_common_FrameHeader.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_common_FrameQuality.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_common_Linspace.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_common_ROI.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_common_ROIReply.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_common_ROIRequest.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_common_StreamMeta.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarDetection.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarDetectionSet.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarFrame.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarMeta.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadDetection.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadDetectionSet.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadSensorMeta.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadTensorFrame.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadTensorMeta.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioObservation.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioScan.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioSensorMeta.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamArraySet.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamFrame.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamMeta.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_CamIntrinsics.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_Keypoint2D.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_Track2D.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionDetections.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionFrame.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionMeta.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_CameraInfo.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_Feature2D.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_FeatureMatch.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_KeyframeFeatures.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_Landmark.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_MatchSet.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_TrackObs.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_slam_frontend_Tracklet.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_vio_FusedState.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_vio_ImuInfo.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_vio_ImuSample.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_vio_MagnetometerSample.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/schemas/spatial_vio_SensorFusionSample.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/artifacts/serializer_tables.json +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/canonical.py +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/canonjson.py +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/demo/assets/duck.gltf +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/demo/assets/fountain-label.txt +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/demo/assets/fountain-marker.gltf +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/errors.py +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/records.py +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/server/__init__.py +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/server/commands.py +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/server/idlmodel.py +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/server/pin.py +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/server/webjson.py +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds/server/xcdr2.py +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds.egg-info/dependency_links.txt +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds.egg-info/entry_points.txt +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/spatialdds.egg-info/requires.txt +0 -0
- {spatialdds-0.5.3 → spatialdds-0.6.0}/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.
|
|
3
|
+
Version: 0.6.0
|
|
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
5
|
Author: Open AR Cloud
|
|
6
6
|
License: Apache-2.0
|
|
@@ -271,7 +271,7 @@ declared.
|
|
|
271
271
|
<!-- bar: resolve -->
|
|
272
272
|
```python
|
|
273
273
|
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")
|
|
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/ut-austin-south-mall/content/duck").fetch_asset()), "bytes verified")
|
|
275
275
|
```
|
|
276
276
|
|
|
277
277
|
```console
|
|
@@ -286,7 +286,7 @@ call goes away and the bar is one line.
|
|
|
286
286
|
|
|
287
287
|
| call | what it does |
|
|
288
288
|
| --- | --- |
|
|
289
|
-
| `sd.connect(base, token=None, verify_integrity=True, timeout=15.0, lifted=True, scene=
|
|
289
|
+
| `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
290
|
| `ep.search(geohash=None, kinds=None)` | §3.3.0 search → a list of `Hit` |
|
|
291
291
|
| `ep.near(lat, lon, radius_m)` | a helper over `search`, never a second protocol |
|
|
292
292
|
| `ep.resolve(uri)` | §7.5.2 resolution → `Resolved` |
|
|
@@ -428,7 +428,7 @@ pumping 202 samples into two registered subscriber queues delivered 0 live
|
|
|
428
428
|
events. If you call `notify` only from the serving loop, 0.5.0 and 0.5.1 were
|
|
429
429
|
correct for you.
|
|
430
430
|
|
|
431
|
-
0.5.3
|
|
431
|
+
0.5.3 let a browser reach this gateway at all. `Authorization` is not a
|
|
432
432
|
CORS-safelisted request header, so a cross-origin request carrying one is
|
|
433
433
|
preceded by an `OPTIONS` preflight — and no `OPTIONS` was routed, so aiohttp
|
|
434
434
|
answered `405 Allow: GET,HEAD,POST` and the browser stopped there without
|
|
@@ -453,7 +453,45 @@ required, and nothing is newly reachable without one.
|
|
|
453
453
|
If your clients are not browsers, 0.5.0 through 0.5.2 were correct for you:
|
|
454
454
|
nothing else changes, and no response loses a header it had.
|
|
455
455
|
|
|
456
|
-
|
|
456
|
+
0.5.4 finishes what 0.5.3 started, and the gap is instructive. 0.5.3 threaded
|
|
457
|
+
the asking origin through the three places that build a response from
|
|
458
|
+
`_cache_headers` and missed the two that build one by hand: the N.6 command
|
|
459
|
+
lane's own reply, and **every N.8 problem document**. So a command published
|
|
460
|
+
and the page could not read the outcome --- a cross-origin `fetch` rejects a
|
|
461
|
+
response with no allowed origin, so a client saw a failure for a command that
|
|
462
|
+
had in fact succeeded --- and a `401`, `409` or `400` was unreadable by the
|
|
463
|
+
client it was written for, which is N.8 failing at the one thing that
|
|
464
|
+
distinguishes it from a bare status.
|
|
465
|
+
|
|
466
|
+
The fix is a one-rule middleware rather than a fourth and fifth call site:
|
|
467
|
+
where a response names no origin and the request had one, echo it with
|
|
468
|
+
`Vary: Origin`. `_cache_headers` remains the place that decides cacheability
|
|
469
|
+
and reach together and is unchanged where it already acts. Threading it
|
|
470
|
+
explicitly was tried first and is what missed two paths.
|
|
471
|
+
|
|
472
|
+
If your clients are not browsers, nothing here changes anything for you.
|
|
473
|
+
|
|
474
|
+
## New in 0.6.0: lanes, hardening, OpenAPI
|
|
475
|
+
|
|
476
|
+
One registry can now take several publishers. Each one holds a token scoped to
|
|
477
|
+
the scenes it may write, issued with `python -m spatialdds.tokens` and served
|
|
478
|
+
with `--tokens`. A write outside its lane is a `403` naming the scene, and
|
|
479
|
+
reads stay open. Manifests can be withdrawn, and the journal records who wrote
|
|
480
|
+
each entry. The REST surface is published as OpenAPI 3.1 at
|
|
481
|
+
`/.well-known/spatialdds/openapi`. Every limit refuses with a problem document
|
|
482
|
+
naming its number.
|
|
483
|
+
|
|
484
|
+
Two changes may need a line of yours:
|
|
485
|
+
|
|
486
|
+
- **Publishing needs a scene.** The client's publish verbs refuse when no
|
|
487
|
+
scene is set, where they used to write into `default`. Pass `scene=`.
|
|
488
|
+
- **The demo's manifest URIs changed.** They name the scene now,
|
|
489
|
+
`…/ut-austin-south-mall/…`.
|
|
490
|
+
|
|
491
|
+
The security fixes, the limits table and the details are in the
|
|
492
|
+
[changelog](https://github.com/OpenArCloud/spatialdds-web/blob/main/lib/spatialdds/CHANGELOG.md).
|
|
493
|
+
|
|
494
|
+
## Not in 0.6.0
|
|
457
495
|
|
|
458
496
|
Stated so nobody waits for them: no async API, no caching beyond ETag
|
|
459
497
|
revalidation, no retry policy, no MCAP tooling beyond the journal the server
|
|
@@ -247,7 +247,7 @@ declared.
|
|
|
247
247
|
<!-- bar: resolve -->
|
|
248
248
|
```python
|
|
249
249
|
import json, spatialdds as sd
|
|
250
|
-
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")
|
|
250
|
+
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")
|
|
251
251
|
```
|
|
252
252
|
|
|
253
253
|
```console
|
|
@@ -262,7 +262,7 @@ call goes away and the bar is one line.
|
|
|
262
262
|
|
|
263
263
|
| call | what it does |
|
|
264
264
|
| --- | --- |
|
|
265
|
-
| `sd.connect(base, token=None, verify_integrity=True, timeout=15.0, lifted=True, scene=
|
|
265
|
+
| `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 |
|
|
266
266
|
| `ep.search(geohash=None, kinds=None)` | §3.3.0 search → a list of `Hit` |
|
|
267
267
|
| `ep.near(lat, lon, radius_m)` | a helper over `search`, never a second protocol |
|
|
268
268
|
| `ep.resolve(uri)` | §7.5.2 resolution → `Resolved` |
|
|
@@ -404,7 +404,7 @@ pumping 202 samples into two registered subscriber queues delivered 0 live
|
|
|
404
404
|
events. If you call `notify` only from the serving loop, 0.5.0 and 0.5.1 were
|
|
405
405
|
correct for you.
|
|
406
406
|
|
|
407
|
-
0.5.3
|
|
407
|
+
0.5.3 let a browser reach this gateway at all. `Authorization` is not a
|
|
408
408
|
CORS-safelisted request header, so a cross-origin request carrying one is
|
|
409
409
|
preceded by an `OPTIONS` preflight — and no `OPTIONS` was routed, so aiohttp
|
|
410
410
|
answered `405 Allow: GET,HEAD,POST` and the browser stopped there without
|
|
@@ -429,7 +429,45 @@ required, and nothing is newly reachable without one.
|
|
|
429
429
|
If your clients are not browsers, 0.5.0 through 0.5.2 were correct for you:
|
|
430
430
|
nothing else changes, and no response loses a header it had.
|
|
431
431
|
|
|
432
|
-
|
|
432
|
+
0.5.4 finishes what 0.5.3 started, and the gap is instructive. 0.5.3 threaded
|
|
433
|
+
the asking origin through the three places that build a response from
|
|
434
|
+
`_cache_headers` and missed the two that build one by hand: the N.6 command
|
|
435
|
+
lane's own reply, and **every N.8 problem document**. So a command published
|
|
436
|
+
and the page could not read the outcome --- a cross-origin `fetch` rejects a
|
|
437
|
+
response with no allowed origin, so a client saw a failure for a command that
|
|
438
|
+
had in fact succeeded --- and a `401`, `409` or `400` was unreadable by the
|
|
439
|
+
client it was written for, which is N.8 failing at the one thing that
|
|
440
|
+
distinguishes it from a bare status.
|
|
441
|
+
|
|
442
|
+
The fix is a one-rule middleware rather than a fourth and fifth call site:
|
|
443
|
+
where a response names no origin and the request had one, echo it with
|
|
444
|
+
`Vary: Origin`. `_cache_headers` remains the place that decides cacheability
|
|
445
|
+
and reach together and is unchanged where it already acts. Threading it
|
|
446
|
+
explicitly was tried first and is what missed two paths.
|
|
447
|
+
|
|
448
|
+
If your clients are not browsers, nothing here changes anything for you.
|
|
449
|
+
|
|
450
|
+
## New in 0.6.0: lanes, hardening, OpenAPI
|
|
451
|
+
|
|
452
|
+
One registry can now take several publishers. Each one holds a token scoped to
|
|
453
|
+
the scenes it may write, issued with `python -m spatialdds.tokens` and served
|
|
454
|
+
with `--tokens`. A write outside its lane is a `403` naming the scene, and
|
|
455
|
+
reads stay open. Manifests can be withdrawn, and the journal records who wrote
|
|
456
|
+
each entry. The REST surface is published as OpenAPI 3.1 at
|
|
457
|
+
`/.well-known/spatialdds/openapi`. Every limit refuses with a problem document
|
|
458
|
+
naming its number.
|
|
459
|
+
|
|
460
|
+
Two changes may need a line of yours:
|
|
461
|
+
|
|
462
|
+
- **Publishing needs a scene.** The client's publish verbs refuse when no
|
|
463
|
+
scene is set, where they used to write into `default`. Pass `scene=`.
|
|
464
|
+
- **The demo's manifest URIs changed.** They name the scene now,
|
|
465
|
+
`…/ut-austin-south-mall/…`.
|
|
466
|
+
|
|
467
|
+
The security fixes, the limits table and the details are in the
|
|
468
|
+
[changelog](https://github.com/OpenArCloud/spatialdds-web/blob/main/lib/spatialdds/CHANGELOG.md).
|
|
469
|
+
|
|
470
|
+
## Not in 0.6.0
|
|
433
471
|
|
|
434
472
|
Stated so nobody waits for them: no async API, no caching beyond ETag
|
|
435
473
|
revalidation, no retry policy, no MCAP tooling beyond the journal the server
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "spatialdds"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.6.0"
|
|
8
8
|
description = "SpatialDDS over plain HTTPS and a WebSocket: a client for the web binding (Appendix N), and the reference registry behind one command."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -58,8 +58,13 @@ packages = ["spatialdds", "spatialdds.server"]
|
|
|
58
58
|
# * `demo/**` -- the fountain set `--demo` serves. Byte-identical to the
|
|
59
59
|
# repository's `samples/` copy, which `tools/pack_demo.py` maintains and
|
|
60
60
|
# `gates/serve_demo.py` checks.
|
|
61
|
+
# * `artifacts/openapi.{yaml,html}` -- the REST surface's OpenAPI document and
|
|
62
|
+
# its static reference page, generated by `tools/gen_openapi.py` and served
|
|
63
|
+
# at /.well-known/spatialdds/openapi; `gates/openapi.py` guards the drift.
|
|
61
64
|
spatialdds = [
|
|
62
65
|
"artifacts/serializer_tables.json",
|
|
66
|
+
"artifacts/openapi.yaml",
|
|
67
|
+
"artifacts/openapi.html",
|
|
63
68
|
"artifacts/schemas/*.json",
|
|
64
69
|
"artifacts/idl/*.idl",
|
|
65
70
|
"demo/*.mcap",
|
|
@@ -37,7 +37,7 @@ __all__ = [
|
|
|
37
37
|
"content_manifest", "geo_anchor", "service_uri", "content_uri",
|
|
38
38
|
]
|
|
39
39
|
|
|
40
|
-
__version__ = "0.
|
|
40
|
+
__version__ = "0.6.0"
|
|
41
41
|
#: The SpatialDDS-spec commit whose Appendix N and generated artifacts this
|
|
42
42
|
#: package implements. Package versions and specification versions move
|
|
43
43
|
#: independently; this is the one that says what the wire looks like.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!doctype html><html lang=en><head><meta charset=utf-8><meta name=viewport content='width=device-width,initial-scale=1'><title>SpatialDDS web binding (spatialdds-web)</title><style>
|
|
2
|
+
:root{--bg:#fbfbfa;--fg:#1f2328;--mut:#5b636d;--line:#e3e5e8;--acc:#0b6e69;
|
|
3
|
+
--code:#f1f2f1;color-scheme:light}
|
|
4
|
+
@media (prefers-color-scheme:dark){:root{--bg:#121516;--fg:#e6e8ea;--mut:#9aa3ab;
|
|
5
|
+
--line:#2a2f33;--acc:#5fc2bb;--code:#1c2124;color-scheme:dark}}
|
|
6
|
+
body{margin:0;background:var(--bg);color:var(--fg);font:15px/1.55 system-ui,
|
|
7
|
+
-apple-system,Segoe UI,sans-serif}main{max-width:62rem;margin:0 auto;
|
|
8
|
+
padding:2rem 1rem 4rem}h1{font-size:1.6rem;margin:0 0 .3rem}h2{font-size:1.1rem;
|
|
9
|
+
margin:2.2rem 0 .6rem;border-bottom:1px solid var(--line);padding-bottom:.3rem}
|
|
10
|
+
h3{font-size:.98rem;margin:0;font-weight:600;overflow-wrap:anywhere}
|
|
11
|
+
code{font:13px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;background:
|
|
12
|
+
var(--code);padding:.05rem .3rem;border-radius:3px}section{padding:.9rem 0;
|
|
13
|
+
border-bottom:1px solid var(--line)}p{margin:.35rem 0}.mut,.sum .auth{color:
|
|
14
|
+
var(--mut)}.auth{font-size:.85rem;margin-left:.4rem}.v{display:inline-block;
|
|
15
|
+
min-width:4.2rem;font:600 12px ui-monospace,monospace;letter-spacing:.04em;
|
|
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-web)</h1><p class=mut>Version 0.6.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's own tables and the published JSON Schemas; never edited by hand. Reads are open; writes take a bearer token scoped to scenes. The WebSocket streams (N.5) are described on each collection path, not modelled.</p><h2>Operations</h2><section id="search"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/search</code></h3><p class="sum">Services near a geohash (§8.2.3 manifests) <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="searchPost"><h3><span class="v post">POST</span> <code>/.well-known/spatialdds/search</code></h3><p class="sum">The same search, as a POST body <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span> <span class="s s4">413</span> <span class="s s4">415</span></p></section><section id="listSchemas"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/schemas</code></h3><p class="sum">The published JSON Schemas, by type <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="getSchema"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/schemas/{type}</code></h3><p class="sum"> <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="bootstrap"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/bootstrap</code></h3><p class="sum">DDS-join material (N.2); optional <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="resolverMetadata"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/resolver</code></h3><p class="sum">§7.5.2 resolver metadata <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="openapi"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/openapi</code></h3><p class="sum">This document <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="openapiPage"><h3><span class="v get">GET</span> <code>/.well-known/spatialdds/openapi.html</code></h3><p class="sum">This document as a static reference page <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">429</span></p></section><section id="resolve"><h3><span class="v get">GET</span> <code>/spatialdds/resolve</code></h3><p class="sum">Resolve a URI to its manifest (§7.5.2) <span class="auth">open</span></p><p class="codes"><span class="s s2">200</span> <span class="s s4">400</span> <span class="s s4">404</span> <span class="s s4">429</span></p></section><section id="putManifest"><h3><span class="v put">PUT</span> <code>/spatialdds/resolve</code></h3><p class="sum">Publish a manifest, keyed by its own <code>id</code> <span class="auth">token</span></p><p>The <code>uri</code> parameter is not used; the body's <code>id</code> is the key. Its scene segment is the lane. **Writes are per lane.** The path'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's scene segment. **Writes are per lane.** The path'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'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'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's key must equal the URL'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's first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). The dispose streams on the collection'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'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'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's key must equal the URL'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's first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). The dispose streams on the collection's WebSocket with its <code>reason</code>.</p><p class="codes"><span class="s s2">204</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">404</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="listGeoAnchor"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/geo_anchor/v1</code></h3><p class="sum">Every spatial.core.GeoAnchor instance in the latched set <span class="auth">open</span></p><p>**The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="commandGeoAnchor"><h3><span class="v post">POST</span> <code>/{scene}/{stream}/geo_anchor/v1</code></h3><p class="sum">An N.6 command addressed through the geo_anchor lane <span class="auth">token</span></p><p>Accepted only on a lane whose topic advertises <code>accepts_commands</code>; otherwise <code>405</code>. **Writes are per lane.** The path'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'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's key must equal the URL'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's first segment is the scene; the bearer token must be granted it (<code>tenancy.WRITE_REFUSALS</code>). The dispose streams on the collection's WebSocket with its <code>reason</code>.</p><p class="codes"><span class="s s2">204</span> <span class="s s4">400</span> <span class="s s4">401</span> <span class="s s4">403</span> <span class="s s4">404</span> <span class="s s4">405</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><section id="listInstances"><h3><span class="v get">GET</span> <code>/{scene}/{stream}/{type}/{version}</code></h3><p class="sum">Any other served topic, read-only <span class="auth">token for operator-scoped</span></p><p>Latched types answer with the latched set; streamed types with the replayed window. Public or operator-scoped per the type: <code>spatial.core.FrameTransform</code> latched public, <code>spatial.events.CrossingLine</code> latched public, <code>spatial.events.SpatialEvent</code> stream bearer, <code>spatial.events.SpatialZone</code> latched public, <code>spatial.owm.Entity</code> latched bearer, <code>spatial.owm.ModelPose</code> stream bearer, <code>spatial.semantics.Detection2DSet</code> stream bearer, <code>spatial.semantics.Detection3DSet</code> stream bearer, <code>spatial.semantics.FusedTrackSet</code> stream bearer. **The same URL is also a WebSocket** (N.5): connect with <code>wss://</code> and receive the latched set as <code>sample</code> events, exactly one <code>end_of_replay</code> carrying the replay count, then live <code>sample</code> and <code>dispose</code> events (<code>{event, topic, key, data | reason}</code>). Not modelled here; see [Appendix N.5](https://spatialdds.org/v1.8/appendix-n/).</p><p class="codes"><span class="s s2">200</span> <span class="s s3">304</span> <span class="s s4">401</span> <span class="s s4">404</span> <span class="s s4">429</span> <span class="s s5">503</span></p></section><h2>Schemas</h2><p class=mut>115 components, from the published JSON Schemas at <code>/.well-known/spatialdds/schemas</code>.</p></main></body></html>
|