Skip to content

Commit a223626

Browse files
Fix the relationship between datastreamschema and add_insert datastream.
update related docs
1 parent a27c8ca commit a223626

14 files changed

Lines changed: 533 additions & 143 deletions

docs/source/architecture/class_hierarchy.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ classDiagram
156156
+encoding: Encoding
157157
+record_schema: AnyComponent
158158
}
159-
class JSONDatastreamRecordSchema {
159+
class OMJSONDatastreamRecordSchema {
160160
+obs_format = "application/om+json"
161161
+result_schema: AnyComponent
162162
+parameters_schema: AnyComponent
@@ -179,7 +179,7 @@ classDiagram
179179
}
180180
181181
DatastreamRecordSchema <|-- SWEDatastreamRecordSchema
182-
DatastreamRecordSchema <|-- JSONDatastreamRecordSchema
182+
DatastreamRecordSchema <|-- OMJSONDatastreamRecordSchema
183183
CommandSchema <|-- SWEJSONCommandSchema
184184
CommandSchema <|-- JSONCommandSchema
185185
```

docs/source/architecture/construction.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ For raw CS API JSON, parse it through the resource model first:
6161
* - SWE+JSON schema document
6262
- `SWEDatastreamRecordSchema.from_swejson_dict(data)`
6363
* - OM+JSON schema document
64-
- `JSONDatastreamRecordSchema.from_omjson_dict(data)`
64+
- `OMJSONDatastreamRecordSchema.from_omjson_dict(data)`
6565
* - OSH logical schema (`obsFormat=logical`)
6666
- `LogicalDatastreamRecordSchema.from_logical_dict(data)`
6767
```
@@ -160,16 +160,29 @@ cs._underlying_resource.command_schema.to_json_dict()
160160

161161
### "I want the schema for an existing datastream from the server"
162162

163-
`Datastream` has three dedicated fetch methods, one per `obsFormat`
164-
the server supports. Each returns a typed schema model so there's no
165-
runtime auto-dispatch:
163+
For datastreams that came back from `System.discover_datastreams()`,
164+
the SWE+JSON schema is **already cached** on
165+
`_underlying_resource.record_schema`. The CS API listing endpoint
166+
omits the inner schema, so discovery makes a second HTTP call per
167+
datastream (`GET /datastreams/{id}/schema?obsFormat=application/swe+json`)
168+
and assigns the result onto the underlying resource. Reading
169+
`ds._underlying_resource.record_schema` post-discovery returns the
170+
populated `SWEDatastreamRecordSchema` without another network call.
171+
A schema fetch that fails for a single datastream is downgraded to a
172+
warning so it doesn't poison the rest of the discovery; that
173+
datastream's `record_schema` stays `None`.
174+
175+
For datastreams built locally (no discovery), or when you need the
176+
OM+JSON or logical variant, `Datastream` has three dedicated fetch
177+
methods — one per `obsFormat` the server supports. Each returns a
178+
typed schema model:
166179

167180
```python
168181
ds = Datastream(parent_node=node, datastream_resource=DatastreamResource.from_csapi_dict(server_response))
169182

170183
# Wire-format schemas (CS API spec)
171184
sw = ds.fetch_swejson_schema() # -> SWEDatastreamRecordSchema (application/swe+json)
172-
om = ds.fetch_omjson_schema() # -> JSONDatastreamRecordSchema (application/om+json)
185+
om = ds.fetch_omjson_schema() # -> OMJSONDatastreamRecordSchema (application/om+json)
173186

174187
# OSH-specific JSON Schema flavor
175188
lg = ds.fetch_logical_schema() # -> LogicalDatastreamRecordSchema (obsFormat=logical)
@@ -181,8 +194,9 @@ Each method:
181194
parent `Node`'s `APIHelper` for base URL + auth.
182195
2. Parses the response into the corresponding pydantic model.
183196
3. Returns the parsed model — does *not* mutate the datastream's
184-
`_underlying_resource.record_schema`. If you want to cache it, do
185-
it explicitly.
197+
`_underlying_resource.record_schema`. (Discovery is the one place
198+
that opts into caching the SWE+JSON variant; if you want to cache
199+
an OM+JSON or logical fetch, assign it yourself.)
186200

187201
The **logical schema** is OSH-specific (not in the OGC CS API spec):
188202
a JSON Schema document with OGC extension keywords

docs/source/architecture/serialization.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ wrapper, route through the resource model.
2424
- n/a
2525
* - **Datastream** (`DatastreamResource`)
2626
- `to_csapi_dict` / `from_csapi_dict`<br/>(application/json — single shape)
27-
- SWE+JSON: `SWEDatastreamRecordSchema.to_swejson_dict` / `from_swejson_dict`<br/>OM+JSON: `JSONDatastreamRecordSchema.to_omjson_dict` / `from_omjson_dict`<br/>OSH logical: `LogicalDatastreamRecordSchema.to_logical_dict` / `from_logical_dict`
27+
- SWE+JSON: `SWEDatastreamRecordSchema.to_swejson_dict` / `from_swejson_dict`<br/>OM+JSON: `OMJSONDatastreamRecordSchema.to_omjson_dict` / `from_omjson_dict`<br/>OSH logical: `LogicalDatastreamRecordSchema.to_logical_dict` / `from_logical_dict`
2828
- OM+JSON: `ObservationResource.to_omjson_dict` / `from_omjson_dict`<br/>SWE+JSON: `ObservationResource.to_swejson_dict` / `from_swejson_dict`
2929
* - **ControlStream** (`ControlStreamResource`)
3030
- `to_csapi_dict` / `from_csapi_dict`

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "oshconnect"
3-
version = "0.5.1a0"
3+
version = "0.5.1a1"
44
description = "Library for interfacing with OSH, helping guide visualization efforts, and providing a place to store configurations. Implements OGC CS API Part 3 (Pub/Sub) MQTT topic conventions including :data topics and resource event topics."
55
readme = "README.md"
66
authors = [

src/oshconnect/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
QuantityRangeSchema,
3434
TimeRangeSchema,
3535
)
36-
from .schema_datamodels import SWEDatastreamRecordSchema, JSONDatastreamRecordSchema, JSONCommandSchema
36+
from .schema_datamodels import SWEDatastreamRecordSchema, OMJSONDatastreamRecordSchema, JSONCommandSchema
3737

3838
# Event system
3939
from .events import EventHandler, IEventListener, CallbackListener, DefaultEventTypes, AtomicEventTypes, Event, EventBuilder
@@ -76,7 +76,7 @@
7676
"QuantityRangeSchema",
7777
"TimeRangeSchema",
7878
"SWEDatastreamRecordSchema",
79-
"JSONDatastreamRecordSchema",
79+
"OMJSONDatastreamRecordSchema",
8080
"JSONCommandSchema",
8181
# Event system
8282
"EventHandler",

src/oshconnect/resource_datamodels.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,13 @@ class DatastreamResource(BaseModel):
209209
feature_of_interest_link: Link = Field(None, alias="featureOfInterest@link")
210210
sampling_feature_link: Link = Field(None, alias="samplingFeature@link")
211211
parameters: dict = Field(None)
212-
phenomenon_time: TimePeriod = Field(None, alias="phenomenonTimeInterval")
212+
phenomenon_time: TimePeriod = Field(None, alias="phenomenonTime")
213213
result_time: TimePeriod = Field(None, alias="resultTimeInterval")
214214
ds_type: str = Field(None, alias="type")
215215
result_type: str = Field(None, alias="resultType")
216+
formats: List[str] = Field(default_factory=list)
217+
observed_properties: List[dict] = Field(default_factory=list, alias="observedProperties")
218+
system_id: str = Field(None, alias="system@id")
216219
links: List[Link] = Field(None)
217220
record_schema: SerializeAsAny[DatastreamRecordSchema] = Field(None, alias="schema")
218221

@@ -236,7 +239,7 @@ def to_csapi_dict(self) -> dict:
236239
"""Render this datastream as the CS API `application/json` resource
237240
body. The embedded ``schema`` field is dumped polymorphically per
238241
whichever variant (`SWEDatastreamRecordSchema` /
239-
`JSONDatastreamRecordSchema`) it holds.
242+
`OMJSONDatastreamRecordSchema`) it holds.
240243
"""
241244
return self.model_dump(by_alias=True, exclude_none=True, mode='json')
242245

src/oshconnect/schema_datamodels.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,10 @@ def from_swejson_dict(cls, data: dict) -> "SWEDatastreamRecordSchema":
155155
return cls.model_validate(data, by_alias=True)
156156

157157

158-
class JSONDatastreamRecordSchema(DatastreamRecordSchema):
159-
"""Datastream observation schema for the JSON media types
160-
(`application/json`, `application/om+json`).
158+
class OMJSONDatastreamRecordSchema(DatastreamRecordSchema):
159+
"""Datastream observation schema for the OM+JSON media type
160+
(`application/om+json`, also accepts `application/json` as a synonym
161+
on parse since OSH treats them equivalently for datastream schemas).
161162
162163
Per CS API Part 2 §16.1.4, this form does not carry a SWE `encoding`
163164
block; structure is fully described by `resultSchema` (inline result)
@@ -182,17 +183,17 @@ def _check_obs_format(cls, v):
182183
@model_validator(mode="after")
183184
def _root_schemas_require_name(self):
184185
if self.result_schema is not None:
185-
check_named(self.result_schema, "JSONDatastreamRecordSchema.resultSchema")
186+
check_named(self.result_schema, "OMJSONDatastreamRecordSchema.resultSchema")
186187
if self.parameters_schema is not None:
187-
check_named(self.parameters_schema, "JSONDatastreamRecordSchema.parametersSchema")
188+
check_named(self.parameters_schema, "OMJSONDatastreamRecordSchema.parametersSchema")
188189
return self
189190

190191
def to_omjson_dict(self) -> dict:
191192
"""Render as an `application/om+json` datastream-schema document."""
192193
return _dump_csapi(self)
193194

194195
@classmethod
195-
def from_omjson_dict(cls, data: dict) -> "JSONDatastreamRecordSchema":
196+
def from_omjson_dict(cls, data: dict) -> "OMJSONDatastreamRecordSchema":
196197
"""Build from an `application/om+json` (or `application/json`)
197198
datastream-schema dict (e.g., a CS API ``/datastreams/{id}/schema``
198199
response in OM+JSON form)."""
@@ -231,7 +232,7 @@ class LogicalDatastreamRecordSchema(BaseModel):
231232
"""Logical schema document — OSH's `obsFormat=logical` representation.
232233
233234
Returned by ``GET /datastreams/{id}/schema?obsFormat=logical``. Distinct
234-
from `SWEDatastreamRecordSchema` and `JSONDatastreamRecordSchema`:
235+
from `SWEDatastreamRecordSchema` and `OMJSONDatastreamRecordSchema`:
235236
236237
- No ``obsFormat`` envelope field
237238
- No ``recordSchema`` wrapper — the schema is the document

0 commit comments

Comments
 (0)