Skip to content

Commit 91a1723

Browse files
fix models and add logic supporting datastream retrieval
1 parent 80fb583 commit 91a1723

5 files changed

Lines changed: 68 additions & 18 deletions

File tree

external_models/__init__.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
# Author: Ian Patterson
55
# Contact Email: ian@botts-inc.com
66
# ==============================================================================
7+
from typing import Any
78

89
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
10+
from pydantic._internal import _repr
911
from shapely import Point
1012
from typing_extensions import Self
1113

@@ -45,6 +47,23 @@ def check_iso_date(cls, v) -> str:
4547
return v
4648

4749

50+
class TimePeriod(BaseModel):
51+
start: str = Field(...)
52+
end: str = Field(...)
53+
54+
@model_validator(mode='before')
55+
@classmethod
56+
def valid_time_period(cls, data) -> Any:
57+
if isinstance(data, list):
58+
if data[0] > data[1]:
59+
raise ValueError("Time period start must be before end.")
60+
return {"start": data[0], "end": data[1]}
61+
62+
def __repr__(self):
63+
return f'{[self.start, self.end]}'
64+
65+
66+
4867
class SecurityConstraints:
4968
constraints: list
5069

external_models/object_models.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from external_models import BoundingBox, Capabilities, Characteristics, ConfigurationSettings, Contact, DateTime, \
1616
Documentation, \
1717
FeatureOfInterest, HistoryEvent, Input, LegalConstraints, \
18-
Mode, Output, Parameter, ProcessMethod, SecurityConstraints
18+
Mode, Output, Parameter, ProcessMethod, SecurityConstraints, TimePeriod
1919

2020

2121
class System(BaseModel):
@@ -53,21 +53,23 @@ class System(BaseModel):
5353
method: ProcessMethod = Field(None)
5454

5555

56-
class Datastream(BaseModel):
57-
ds_id: str = Field(..., serialization_alias="id")
56+
class DatastreamResource(BaseModel):
57+
# model_config = ConfigDict(populate_by_name=True)
58+
59+
ds_id: str = Field(..., alias="id")
5860
name: str = Field(...)
59-
description: str
60-
valid_time: DateTime = Field(..., serialization_alias="validTime")
61-
output_name: str = Field(None, serialization_alias="outputName")
62-
procedure_link: Link = Field(None, serialization_alias="procedureLink@link")
63-
deployment_link: Link = Field(None, serialization_alias="deploymentLink@link")
64-
ultimate_feature_of_interest_link: Link = Field(None, serialization_alias="ultimateFeatureOfInterest@link")
65-
sampling_feature_link: Link = Field(None, serialization_alias="samplingFeature@link")
61+
description: str = Field(None)
62+
valid_time: TimePeriod = Field(..., alias="validTime")
63+
output_name: str = Field(None, alias="outputName")
64+
procedure_link: Link = Field(None, alias="procedureLink@link")
65+
deployment_link: Link = Field(None, alias="deploymentLink@link")
66+
ultimate_feature_of_interest_link: Link = Field(None, alias="ultimateFeatureOfInterest@link")
67+
sampling_feature_link: Link = Field(None, alias="samplingFeature@link")
6668
parameters: dict = Field(None)
67-
phenomenon_time: DateTime = Field(None, serialization_alias="phenomenonTimeInterval")
68-
result_time: DateTime = Field(None, serialization_alias="resultTimeInterval")
69-
ds_type: str = Field(None, serialization_alias="type")
70-
result_type: str = Field(None, serialization_alias="resultType")
69+
phenomenon_time: TimePeriod = Field(None, alias="phenomenonTimeInterval")
70+
result_time: TimePeriod = Field(None, alias="resultTimeInterval")
71+
ds_type: str = Field(None, alias="type")
72+
result_type: str = Field(None, alias="resultType")
7173
links: List[Link] = Field(None)
7274
schema: DatastreamSchema = Field(None)
7375

oshconnect/datamodels/datamodels.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
from __future__ import annotations
88

99
import base64
10+
import json
1011
import uuid
1112
from dataclasses import dataclass, field
1213

13-
from conSys4Py import APIResourceTypes
14+
from conSys4Py import APIResourceTypes, DatastreamBodyJSON
1415
from conSys4Py.core.default_api_helpers import APIHelper
1516

16-
from external_models.object_models import System as SystemResource
17+
from external_models.object_models import DatastreamResource, System as SystemResource
1718
from oshconnect import Endpoints
1819

1920

@@ -82,6 +83,9 @@ def discover_systems(self):
8283
def add_new_system(self, system: System):
8384
self._system_ids.append(system.uid)
8485

86+
def get_api_helper(self) -> APIHelper:
87+
return self._api_helper
88+
8589

8690
class System:
8791
uid: uuid.UUID
@@ -102,6 +106,18 @@ def __init__(self, name: str, label: str, **kwargs):
102106
def update_parent_node(self, node: Node):
103107
self._parent_node = node
104108

109+
def discover_datastreams(self):
110+
res = self._parent_node.get_api_helper().retrieve_resource(APIResourceTypes.DATASTREAM, req_headers={})
111+
datastream_json = res.json()['items']
112+
print(f'Result of datastream discovery: {datastream_json}')
113+
datastreams = []
114+
for ds in datastream_json:
115+
datastream_objs = DatastreamResource.model_validate(ds)
116+
datastreams.append(datastream_objs)
117+
118+
print(f'Found datastreams: {datastreams}')
119+
return datastreams
120+
105121
@staticmethod
106122
def from_system_resource(system_resource: SystemResource):
107123
other_props = system_resource.dict()

oshconnect/oshconnect.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,11 @@ def visualize_streams(self, streams: list):
8484
def get_visualization_recommendations(self, streams: list):
8585
pass
8686

87-
def discover_datastreams(self, streams: list):
88-
pass
87+
def discover_datastreams(self):
88+
for system in self._systems:
89+
res_datastreams = system.discover_datastreams()
90+
print(f'Datastreams found: {res_datastreams}')
91+
self._datafeeds.extend(res_datastreams)
8992

9093
def discover_systems(self, nodes: list[str] = None):
9194
search_nodes = self._nodes

tests/test_oshconnect.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,13 @@ def test_find_systems(self):
3535
print(f'Found systems: {app._systems}')
3636
# assert len(systems) == 1
3737
# assert systems[0] == node.get_api_endpoint()
38+
39+
def test_oshconnect_find_datastreams(self):
40+
app = OSHConnect(name="Test OSH Connect")
41+
node = Node(address="http://localhost", port=8585, username="admin", password="admin")
42+
app.add_node(node)
43+
app.discover_systems()
44+
45+
app.discover_datastreams()
46+
assert len(app._datafeeds) > 0
47+

0 commit comments

Comments
 (0)