Skip to content

Commit 114ce00

Browse files
Bugfixes into main (#5)
* fix duplicated TimePeriod model * Fix bug around TimePeriod comparison and add some more utility methods to that effect * add quick way to access messages * remove unused portions of docs for the time being * satisfy flake8, remove unused imports
1 parent 13c0641 commit 114ce00

6 files changed

Lines changed: 258 additions & 107 deletions

File tree

docs/source/index.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ certain streaming features made possible by OpenSensorHub.
1313
:caption: Contents
1414

1515
api
16-
datasources
17-
external
18-
1916

2017

2118

oshconnect/core_datamodels.py

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44
# Author: Ian Patterson
55
# Contact Email: ian@botts-inc.com
66
# ==============================================================================
7+
from __future__ import annotations
8+
79
import uuid
8-
from typing import Any, List, Self
10+
from typing import List
911

1012
from conSys4Py import DatastreamSchema, Geometry
1113
from conSys4Py.datamodels.api_utils import Link
12-
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
14+
from pydantic import BaseModel, ConfigDict, Field
1315
from shapely import Point
1416

15-
from .timemanagement import TimePeriod
17+
from oshconnect.timemanagement import DateTimeSchema, TimePeriod
1618

1719

1820
class BoundingBox(BaseModel):
@@ -30,52 +32,6 @@ class BoundingBox(BaseModel):
3032
# return self
3133

3234

33-
class DateTime(BaseModel):
34-
is_instant: bool = Field(True, description="Whether the date time is an instant or a period.")
35-
iso_date: str = Field(None, description="The ISO formatted date time.")
36-
time_period: tuple = Field(None, description="The time period of the date time.")
37-
38-
@model_validator(mode='before')
39-
def valid_datetime_type(self) -> Self:
40-
if self.is_instant:
41-
if self.iso_date is None:
42-
raise ValueError("Instant date time must have a valid ISO8601 date.")
43-
return self
44-
45-
@field_validator('iso_date')
46-
@classmethod
47-
def check_iso_date(cls, v) -> str:
48-
if not v:
49-
raise ValueError("Instant date time must have a valid ISO8601 date.")
50-
return v
51-
52-
53-
class TimePeriod(BaseModel):
54-
start: str = Field(...)
55-
end: str = Field(...)
56-
57-
@model_validator(mode='before')
58-
@classmethod
59-
def valid_time_period(cls, data) -> Any:
60-
if isinstance(data, list):
61-
if data[0] > data[1]:
62-
raise ValueError("Time period start must be before end.")
63-
return {"start": data[0], "end": data[1]}
64-
elif isinstance(data, dict):
65-
if data['start'] > data['end']:
66-
raise ValueError("Time period start must be before end.")
67-
return data
68-
69-
def __repr__(self):
70-
return f'{[self.start, self.end]}'
71-
72-
def does_timeperiod_overlap(self, checked_timeperiod: TimePeriod) -> bool:
73-
if checked_timeperiod.start < self.end and checked_timeperiod.end > self.start:
74-
return True
75-
else:
76-
return False
77-
78-
7935
class SecurityConstraints:
8036
constraints: list
8137

@@ -148,7 +104,7 @@ class SystemResource(BaseModel):
148104
keywords: List[str] = Field(None)
149105
identifiers: List[str] = Field(None)
150106
classifiers: List[str] = Field(None)
151-
valid_time: DateTime = Field(None, serialization_alias="validTime")
107+
valid_time: DateTimeSchema = Field(None, serialization_alias="validTime")
152108
security_constraints: List[SecurityConstraints] = Field(None, serialization_alias="securityConstraints")
153109
legal_constraints: List[LegalConstraints] = Field(None, serialization_alias="legalConstraints")
154110
characteristics: List[Characteristics] = Field(None)
@@ -191,8 +147,8 @@ class DatastreamResource(BaseModel):
191147
class Observation(BaseModel):
192148
sampling_feature_id: str = Field(None, serialization_alias="samplingFeature@Id")
193149
procedure_link: Link = Field(None, serialization_alias="procedure@link")
194-
phenomenon_time: DateTime = Field(None, serialization_alias="phenomenonTime")
195-
result_time: DateTime = Field(..., serialization_alias="resultTime")
150+
phenomenon_time: DateTimeSchema = Field(None, serialization_alias="phenomenonTime")
151+
result_time: DateTimeSchema = Field(..., serialization_alias="resultTime")
196152
parameters: dict = Field(None)
197153
result: dict = Field(...)
198154
result_link: Link = Field(None, serialization_alias="result@link")

oshconnect/datasource.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@
1818
import websockets
1919
from conSys4Py import APIResourceTypes
2020
from conSys4Py.datamodels.observations import ObservationOMJSONInline
21+
from conSys4Py.datamodels.swe_components import DataRecordSchema
2122

2223
from .core_datamodels import DatastreamResource, SystemResource, TimePeriod
2324
from .osh_connect_datamodels import TemporalModes
2425

2526

27+
# from swecommondm.component_implementations import DataRecord
28+
29+
2630
class DataSource:
2731
"""
2832
DataSource: represents the active connection of a datastream object.
@@ -43,6 +47,7 @@ class DataSource:
4347
_auth: str = None
4448
_websocket: websockets.WebSocketClientProtocol = None
4549
_extra_headers: dict = None
50+
_result_schema: DataRecordSchema = None
4651

4752
def __init__(self, name: str, datastream: DatastreamResource,
4853
parent_system: SystemResource):
@@ -64,6 +69,15 @@ def __init__(self, name: str, datastream: DatastreamResource,
6469
if self._parent_system.get_parent_node().is_secure:
6570
self._auth = self._parent_system.get_parent_node().get_decoded_auth()
6671
self._extra_headers = {'Authorization': f'Basic {self._auth}'}
72+
# get result schema
73+
74+
# t_url = f'http://{self._parent_system.get_parent_node().get_address()}:{self._parent_system.get_parent_node().get_port()}'
75+
#
76+
# res = conSys4Py.part_2.datastreams.retrieve_datastream_schema(t_url,
77+
# datastream_id=self._datastream.ds_id,
78+
# api_root=self._parent_system.get_parent_node()._api_helper.api_root,
79+
# headers=self._extra_headers)
80+
# print(res.json())
6781

6882
def get_id(self) -> str:
6983
"""
@@ -421,6 +435,22 @@ async def handle_http_batching(self, datasource: DataSource,
421435
self._message_list.add_message(msg_wrapper)
422436
return resp.json()
423437

438+
def get_message_handler(self) -> MessageHandler:
439+
"""
440+
Get the MessageHandler object from the DataSourceHandler
441+
442+
:return: MessageHandler object
443+
"""
444+
return self._message_list
445+
446+
def get_messages(self) -> list[MessageWrapper]:
447+
"""
448+
Get the list of MessageWrapper objects from the MessageHandler
449+
450+
:return: List of MessageWrapper objects
451+
"""
452+
return self._message_list.get_messages()
453+
424454

425455
class MessageHandler:
426456
"""
@@ -441,7 +471,7 @@ def add_message(self, message: MessageWrapper):
441471
:return:
442472
"""
443473
self._message_list.append(message)
444-
print(self._message_list)
474+
# print(self._message_list)
445475

446476
def get_messages(self) -> list[MessageWrapper]:
447477
"""
@@ -493,7 +523,7 @@ def get_message_as_dict(self) -> dict:
493523
"""
494524
Get the observation data from the MessageWrapper as a dictionary
495525
496-
:return: disct of the observation result data
526+
:return: dict of the observation result data
497527
"""
498528
return self._message.model_dump()
499529

oshconnect/oshconnectapi.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from conSys4Py.core.default_api_helpers import APIHelper
99

1010
from .core_datamodels import TimePeriod
11-
from .datasource import DataSource, DataSourceHandler
11+
from .datasource import DataSource, DataSourceHandler, MessageWrapper
1212
from .datastore import DataStore
1313
from .osh_connect_datamodels import Node, System, TemporalModes
1414
from .styling import Styling
@@ -180,3 +180,10 @@ def set_timeperiod(self, start_time: str, end_time: str):
180180
"""
181181
tp = TimePeriod(start=start_time, end=end_time)
182182
self.timestream = TimeManagement(time_range=tp)
183+
184+
def get_message_list(self) -> list[MessageWrapper]:
185+
"""
186+
Get the list of messages that have been received by the OSHConnect instance.
187+
:return: list of MessageWrapper objects
188+
"""
189+
return self._datasource_handler.get_messages()

0 commit comments

Comments
 (0)