hydroserverpy 0.4.0__py3-none-any.whl → 0.5.0b2__py3-none-any.whl
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.
Potentially problematic release.
This version of hydroserverpy might be problematic. Click here for more details.
- hydroserverpy/__init__.py +2 -3
- hydroserverpy/api/http.py +22 -0
- hydroserverpy/api/main.py +173 -0
- hydroserverpy/api/models/__init__.py +21 -0
- hydroserverpy/api/models/base.py +74 -0
- hydroserverpy/api/models/etl/__init__.py +0 -0
- hydroserverpy/api/models/etl/data_archive.py +105 -0
- hydroserverpy/api/models/etl/data_source.py +150 -0
- hydroserverpy/api/models/etl/orchestration_configuration.py +35 -0
- hydroserverpy/api/models/etl/orchestration_system.py +78 -0
- hydroserverpy/api/models/iam/__init__.py +0 -0
- hydroserverpy/api/models/iam/account.py +12 -0
- hydroserverpy/api/models/iam/collaborator.py +34 -0
- hydroserverpy/api/models/iam/role.py +10 -0
- hydroserverpy/api/models/iam/workspace.py +238 -0
- hydroserverpy/api/models/sta/__init__.py +0 -0
- hydroserverpy/api/models/sta/datastream.py +338 -0
- hydroserverpy/api/models/sta/observed_property.py +72 -0
- hydroserverpy/api/models/sta/processing_level.py +50 -0
- hydroserverpy/api/models/sta/result_qualifier.py +49 -0
- hydroserverpy/api/models/sta/sensor.py +105 -0
- hydroserverpy/api/models/sta/thing.py +217 -0
- hydroserverpy/api/models/sta/unit.py +49 -0
- hydroserverpy/api/services/__init__.py +11 -0
- hydroserverpy/api/services/base.py +102 -0
- hydroserverpy/api/services/etl/__init__.py +0 -0
- hydroserverpy/api/services/etl/data_archive.py +196 -0
- hydroserverpy/api/services/etl/data_source.py +196 -0
- hydroserverpy/api/services/etl/orchestration_system.py +74 -0
- hydroserverpy/api/services/iam/__init__.py +0 -0
- hydroserverpy/api/services/iam/workspace.py +126 -0
- hydroserverpy/api/services/sta/__init__.py +0 -0
- hydroserverpy/api/services/sta/datastream.py +354 -0
- hydroserverpy/api/services/sta/observed_property.py +100 -0
- hydroserverpy/api/services/sta/processing_level.py +78 -0
- hydroserverpy/api/services/sta/result_qualifier.py +74 -0
- hydroserverpy/api/services/sta/sensor.py +116 -0
- hydroserverpy/api/services/sta/thing.py +188 -0
- hydroserverpy/api/services/sta/unit.py +82 -0
- hydroserverpy/etl/loaders/hydroserver_loader.py +1 -1
- hydroserverpy/etl_csv/hydroserver_etl_csv.py +49 -34
- {hydroserverpy-0.4.0.dist-info → hydroserverpy-0.5.0b2.dist-info}/METADATA +4 -3
- hydroserverpy-0.5.0b2.dist-info/RECORD +66 -0
- {hydroserverpy-0.4.0.dist-info → hydroserverpy-0.5.0b2.dist-info}/WHEEL +1 -1
- hydroserverpy/core/endpoints/__init__.py +0 -9
- hydroserverpy/core/endpoints/base.py +0 -146
- hydroserverpy/core/endpoints/data_loaders.py +0 -93
- hydroserverpy/core/endpoints/data_sources.py +0 -93
- hydroserverpy/core/endpoints/datastreams.py +0 -225
- hydroserverpy/core/endpoints/observed_properties.py +0 -111
- hydroserverpy/core/endpoints/processing_levels.py +0 -111
- hydroserverpy/core/endpoints/result_qualifiers.py +0 -111
- hydroserverpy/core/endpoints/sensors.py +0 -111
- hydroserverpy/core/endpoints/things.py +0 -261
- hydroserverpy/core/endpoints/units.py +0 -111
- hydroserverpy/core/schemas/__init__.py +0 -9
- hydroserverpy/core/schemas/base.py +0 -124
- hydroserverpy/core/schemas/data_loaders.py +0 -73
- hydroserverpy/core/schemas/data_sources.py +0 -223
- hydroserverpy/core/schemas/datastreams.py +0 -330
- hydroserverpy/core/schemas/observed_properties.py +0 -43
- hydroserverpy/core/schemas/processing_levels.py +0 -31
- hydroserverpy/core/schemas/result_qualifiers.py +0 -26
- hydroserverpy/core/schemas/sensors.py +0 -68
- hydroserverpy/core/schemas/things.py +0 -346
- hydroserverpy/core/schemas/units.py +0 -29
- hydroserverpy/core/service.py +0 -200
- hydroserverpy-0.4.0.dist-info/RECORD +0 -51
- /hydroserverpy/{core → api}/__init__.py +0 -0
- {hydroserverpy-0.4.0.dist-info → hydroserverpy-0.5.0b2.dist-info/licenses}/LICENSE +0 -0
- {hydroserverpy-0.4.0.dist-info → hydroserverpy-0.5.0b2.dist-info}/top_level.txt +0 -0
- {hydroserverpy-0.4.0.dist-info → hydroserverpy-0.5.0b2.dist-info}/zip-safe +0 -0
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
from .data_loaders import DataLoaderEndpoint
|
|
2
|
-
from .data_sources import DataSourceEndpoint
|
|
3
|
-
from .datastreams import DatastreamEndpoint
|
|
4
|
-
from .observed_properties import ObservedPropertyEndpoint
|
|
5
|
-
from .processing_levels import ProcessingLevelEndpoint
|
|
6
|
-
from .result_qualifiers import ResultQualifierEndpoint
|
|
7
|
-
from .sensors import SensorEndpoint
|
|
8
|
-
from .things import ThingEndpoint
|
|
9
|
-
from .units import UnitEndpoint
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from uuid import UUID
|
|
3
|
-
from typing import TYPE_CHECKING, Type, Union, List, TypeVar, Optional
|
|
4
|
-
|
|
5
|
-
if TYPE_CHECKING:
|
|
6
|
-
from hydroserverpy import HydroServer
|
|
7
|
-
from hydroserverpy.core.schemas.base import HydroServerCoreModel
|
|
8
|
-
|
|
9
|
-
HydroServerModelType = TypeVar("HydroServerModelType", bound=HydroServerCoreModel)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def expand_docstring(
|
|
13
|
-
model: Optional[Type["HydroServerCoreModel"]] = None, include_uid: bool = False
|
|
14
|
-
):
|
|
15
|
-
def decorator(func):
|
|
16
|
-
docstring = func.__doc__
|
|
17
|
-
if model is not None or include_uid is True:
|
|
18
|
-
docstring += "\n"
|
|
19
|
-
if include_uid is True:
|
|
20
|
-
docstring += f":param uid: The entity ID.\n"
|
|
21
|
-
docstring += f":type uid: Union[UUID, str]\n"
|
|
22
|
-
if model is not None:
|
|
23
|
-
for field_name, field in model.model_fields.items():
|
|
24
|
-
docstring += f":param {field_name}: {field.description}\n"
|
|
25
|
-
docstring += f':type {field_name}: {getattr(field.annotation, "__name__", field.annotation)}\n'
|
|
26
|
-
func.__doc__ = docstring
|
|
27
|
-
return func
|
|
28
|
-
|
|
29
|
-
return decorator
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class HydroServerEndpoint:
|
|
33
|
-
"""
|
|
34
|
-
A base class for interacting with specific API endpoints within a HydroServer service.
|
|
35
|
-
|
|
36
|
-
:ivar _model: The model class associated with this endpoint.
|
|
37
|
-
:ivar _api_route: The base route of the API.
|
|
38
|
-
:ivar _endpoint_route: The specific route of the endpoint.
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
_model: Type["HydroServerCoreModel"]
|
|
42
|
-
_api_route: str
|
|
43
|
-
_endpoint_route: str
|
|
44
|
-
|
|
45
|
-
def __init__(self, service: "HydroServer") -> None:
|
|
46
|
-
"""
|
|
47
|
-
Initialize the HydroServerEndpoint.
|
|
48
|
-
|
|
49
|
-
:param service: The HydroServer service instance to use for requests.
|
|
50
|
-
:type service: HydroServer
|
|
51
|
-
"""
|
|
52
|
-
|
|
53
|
-
self._service = service
|
|
54
|
-
|
|
55
|
-
def _get(
|
|
56
|
-
self, uid: Optional[Union[UUID, str]] = None, params: dict = None
|
|
57
|
-
) -> Union[List["HydroServerModelType"], "HydroServerModelType"]:
|
|
58
|
-
"""
|
|
59
|
-
Fetch an entity collection or single entity from a HydroServer endpoint.
|
|
60
|
-
|
|
61
|
-
:param uid: The unique identifier of the entity to retrieve.
|
|
62
|
-
:type uid: Optional[Union[UUID, str]]
|
|
63
|
-
:returns: A model instance representing the entity.
|
|
64
|
-
:rtype: HydroServerCoreModel
|
|
65
|
-
"""
|
|
66
|
-
|
|
67
|
-
if params is None:
|
|
68
|
-
params = {}
|
|
69
|
-
|
|
70
|
-
path = f'{self._api_route}/data/{self._endpoint_route}{"/" + str(uid) if uid else ""}'
|
|
71
|
-
response = getattr(self._service, "_request")("get", path, params=params)
|
|
72
|
-
|
|
73
|
-
if uid:
|
|
74
|
-
entity = json.loads(response.content)
|
|
75
|
-
result = self._model(
|
|
76
|
-
_endpoint=self, _uid=UUID(str(entity.pop("id"))), **entity
|
|
77
|
-
)
|
|
78
|
-
else:
|
|
79
|
-
result = [
|
|
80
|
-
self._model(_endpoint=self, _uid=UUID(str(entity.pop("id"))), **entity)
|
|
81
|
-
for entity in json.loads(response.content)
|
|
82
|
-
]
|
|
83
|
-
|
|
84
|
-
return result
|
|
85
|
-
|
|
86
|
-
def _post(self, **kwargs) -> "HydroServerModelType":
|
|
87
|
-
"""
|
|
88
|
-
Create a new entity using the endpoint.
|
|
89
|
-
|
|
90
|
-
:param kwargs: The attributes to set on the new entity.
|
|
91
|
-
:returns: A model instance representing the newly created entity.
|
|
92
|
-
:rtype: HydroServerModelType
|
|
93
|
-
"""
|
|
94
|
-
|
|
95
|
-
response = getattr(self._service, "_request")(
|
|
96
|
-
"post",
|
|
97
|
-
f"{self._api_route}/data/{self._endpoint_route}",
|
|
98
|
-
headers={"Content-type": "application/json"},
|
|
99
|
-
data=self._model(_endpoint=self, **kwargs).json(
|
|
100
|
-
exclude_unset=True, by_alias=True
|
|
101
|
-
),
|
|
102
|
-
)
|
|
103
|
-
entity = json.loads(response.content)
|
|
104
|
-
|
|
105
|
-
return self._model(_endpoint=self, _uid=UUID(str(entity.pop("id"))), **entity)
|
|
106
|
-
|
|
107
|
-
def _patch(self, uid: Union[UUID, str], **kwargs) -> "HydroServerModelType":
|
|
108
|
-
"""
|
|
109
|
-
Update an existing entity in the endpoint.
|
|
110
|
-
|
|
111
|
-
:param uid: The unique identifier of the entity to update.
|
|
112
|
-
:type uid: Union[UUID, str]
|
|
113
|
-
:param kwargs: The attributes to update on the entity.
|
|
114
|
-
:returns: A model instance representing the updated entity.
|
|
115
|
-
:rtype: HydroServerModelType
|
|
116
|
-
"""
|
|
117
|
-
|
|
118
|
-
response = getattr(self._service, "_request")(
|
|
119
|
-
"patch",
|
|
120
|
-
f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}",
|
|
121
|
-
headers={"Content-type": "application/json"},
|
|
122
|
-
data=json.dumps(
|
|
123
|
-
{
|
|
124
|
-
self._model.model_fields[key].serialization_alias: value
|
|
125
|
-
for key, value in kwargs.items()
|
|
126
|
-
},
|
|
127
|
-
default=str,
|
|
128
|
-
),
|
|
129
|
-
)
|
|
130
|
-
entity = json.loads(response.content)
|
|
131
|
-
|
|
132
|
-
return self._model(_endpoint=self, _uid=UUID(str(entity.pop("id"))), **entity)
|
|
133
|
-
|
|
134
|
-
def _delete(self, uid: Union[UUID, str]) -> None:
|
|
135
|
-
"""
|
|
136
|
-
Delete an entity from the endpoint by its unique identifier.
|
|
137
|
-
|
|
138
|
-
:param uid: The unique identifier of the entity to delete.
|
|
139
|
-
:type uid: Union[UUID, str]
|
|
140
|
-
:returns: None
|
|
141
|
-
"""
|
|
142
|
-
|
|
143
|
-
getattr(self._service, "_request")(
|
|
144
|
-
"delete",
|
|
145
|
-
f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}",
|
|
146
|
-
)
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from typing import Union, List, TYPE_CHECKING
|
|
3
|
-
from uuid import UUID
|
|
4
|
-
from hydroserverpy.core.endpoints.base import HydroServerEndpoint, expand_docstring
|
|
5
|
-
from hydroserverpy.core.endpoints.data_sources import DataSourceEndpoint
|
|
6
|
-
from hydroserverpy.core.schemas import DataLoader, DataSource
|
|
7
|
-
|
|
8
|
-
if TYPE_CHECKING:
|
|
9
|
-
from hydroserverpy.core.service import HydroServer
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class DataLoaderEndpoint(HydroServerEndpoint):
|
|
13
|
-
"""
|
|
14
|
-
An endpoint for interacting with DataLoader entities in the HydroServer service.
|
|
15
|
-
|
|
16
|
-
:ivar _model: The model class associated with this endpoint, set to `DataLoader`.
|
|
17
|
-
:ivar _api_route: The base route of the API, derived from the service.
|
|
18
|
-
:ivar _endpoint_route: The specific route of the endpoint, set to `'data-loaders'`.
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
def __init__(self, service: "HydroServer") -> None:
|
|
22
|
-
"""
|
|
23
|
-
Initialize the DataLoaderEndpoint.
|
|
24
|
-
|
|
25
|
-
:param service: The HydroServer service instance to use for requests.
|
|
26
|
-
:type service: HydroServer
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
super().__init__(service)
|
|
30
|
-
self._model = DataLoader
|
|
31
|
-
self._api_route = self._service.api_route
|
|
32
|
-
self._endpoint_route = "data-loaders"
|
|
33
|
-
|
|
34
|
-
def list(self) -> List[DataLoader]:
|
|
35
|
-
"""
|
|
36
|
-
Retrieve a collection of data loaders owned by the logged-in user.
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
|
-
return super()._get()
|
|
40
|
-
|
|
41
|
-
@expand_docstring(include_uid=True)
|
|
42
|
-
def get(self, uid: Union[UUID, str]) -> DataLoader:
|
|
43
|
-
"""
|
|
44
|
-
Retrieve a data loader owned by the logged-in user.
|
|
45
|
-
"""
|
|
46
|
-
|
|
47
|
-
return super()._get(uid)
|
|
48
|
-
|
|
49
|
-
@expand_docstring(model=DataLoader)
|
|
50
|
-
def create(self, **kwargs) -> DataLoader:
|
|
51
|
-
"""
|
|
52
|
-
Create a new data loader in HydroServer.
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
return super()._post(**kwargs)
|
|
56
|
-
|
|
57
|
-
@expand_docstring(model=DataLoader, include_uid=True)
|
|
58
|
-
def update(self, uid: Union[UUID, str], **kwargs) -> DataLoader:
|
|
59
|
-
"""
|
|
60
|
-
Update an existing data loader in HydroServer.
|
|
61
|
-
"""
|
|
62
|
-
|
|
63
|
-
return super()._patch(uid=uid, **kwargs)
|
|
64
|
-
|
|
65
|
-
@expand_docstring(include_uid=True)
|
|
66
|
-
def delete(self, uid: Union[UUID, str]) -> None:
|
|
67
|
-
"""
|
|
68
|
-
Delete an existing data loader in HydroServer.
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
super()._delete(uid=uid)
|
|
72
|
-
|
|
73
|
-
def list_data_sources(self, uid: Union[UUID, str]) -> List[DataSource]:
|
|
74
|
-
"""
|
|
75
|
-
Retrieve a list of data source entities associated with a specific data loader.
|
|
76
|
-
|
|
77
|
-
:param uid: The unique identifier of the data loader.
|
|
78
|
-
:type uid: Union[UUID, str]
|
|
79
|
-
:returns: A list of data sour instances associated with the data loader.
|
|
80
|
-
:rtype: List[DataSource]
|
|
81
|
-
"""
|
|
82
|
-
|
|
83
|
-
response = getattr(self._service, "_request")(
|
|
84
|
-
"get",
|
|
85
|
-
f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}/data-sources",
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
endpoint = DataSourceEndpoint(self._service)
|
|
89
|
-
|
|
90
|
-
return [
|
|
91
|
-
DataSource(_endpoint=endpoint, _uid=UUID(str(entity.pop("id"))), **entity)
|
|
92
|
-
for entity in json.loads(response.content)
|
|
93
|
-
]
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from typing import Union, List, TYPE_CHECKING
|
|
3
|
-
from uuid import UUID
|
|
4
|
-
from hydroserverpy.core.endpoints.base import HydroServerEndpoint, expand_docstring
|
|
5
|
-
from hydroserverpy.core.endpoints.datastreams import DatastreamEndpoint
|
|
6
|
-
from hydroserverpy.core.schemas import DataSource, Datastream
|
|
7
|
-
|
|
8
|
-
if TYPE_CHECKING:
|
|
9
|
-
from hydroserverpy.core.service import HydroServer
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class DataSourceEndpoint(HydroServerEndpoint):
|
|
13
|
-
"""
|
|
14
|
-
An endpoint for interacting with data source entities in the HydroServer service.
|
|
15
|
-
|
|
16
|
-
:ivar _model: The model class associated with this endpoint, set to `DataSource`.
|
|
17
|
-
:ivar _api_route: The base route of the API, derived from the service.
|
|
18
|
-
:ivar _endpoint_route: The specific route of the endpoint, set to `'data-sources'`.
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
def __init__(self, service: "HydroServer") -> None:
|
|
22
|
-
"""
|
|
23
|
-
Initialize the DataSourceEndpoint.
|
|
24
|
-
|
|
25
|
-
:param service: The HydroServer service instance to use for requests.
|
|
26
|
-
:type service: HydroServer
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
super().__init__(service)
|
|
30
|
-
self._model = DataSource
|
|
31
|
-
self._api_route = self._service.api_route
|
|
32
|
-
self._endpoint_route = "data-sources"
|
|
33
|
-
|
|
34
|
-
def list(self) -> List[DataSource]:
|
|
35
|
-
"""
|
|
36
|
-
Retrieve a collection of data sources owned by the logged-in user.
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
|
-
return super()._get()
|
|
40
|
-
|
|
41
|
-
@expand_docstring(include_uid=True)
|
|
42
|
-
def get(self, uid: Union[UUID, str]) -> DataSource:
|
|
43
|
-
"""
|
|
44
|
-
Retrieve a data source owned by the logged-in user.
|
|
45
|
-
"""
|
|
46
|
-
|
|
47
|
-
return super()._get(uid)
|
|
48
|
-
|
|
49
|
-
@expand_docstring(model=DataSource)
|
|
50
|
-
def create(self, **kwargs) -> DataSource:
|
|
51
|
-
"""
|
|
52
|
-
Create a new data source in HydroServer.
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
return super()._post(**kwargs)
|
|
56
|
-
|
|
57
|
-
@expand_docstring(model=DataSource, include_uid=True)
|
|
58
|
-
def update(self, uid: Union[UUID, str], **kwargs) -> DataSource:
|
|
59
|
-
"""
|
|
60
|
-
Update an existing data source in HydroServer.
|
|
61
|
-
"""
|
|
62
|
-
|
|
63
|
-
return super()._patch(uid=uid, **kwargs)
|
|
64
|
-
|
|
65
|
-
@expand_docstring(include_uid=True)
|
|
66
|
-
def delete(self, uid: Union[UUID, str]) -> None:
|
|
67
|
-
"""
|
|
68
|
-
Delete an existing data source in HydroServer.
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
super()._delete(uid=uid)
|
|
72
|
-
|
|
73
|
-
def list_datastreams(self, uid: Union[UUID, str]) -> List[Datastream]:
|
|
74
|
-
"""
|
|
75
|
-
Retrieve a list of datastream entities associated with a specific data source.
|
|
76
|
-
|
|
77
|
-
:param uid: The unique identifier of the data source.
|
|
78
|
-
:type uid: Union[UUID, str]
|
|
79
|
-
:returns: A list of datastream instances associated with the data source.
|
|
80
|
-
:rtype: List[Datastream]
|
|
81
|
-
"""
|
|
82
|
-
|
|
83
|
-
response = getattr(self._service, "_request")(
|
|
84
|
-
"get",
|
|
85
|
-
f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}/datastreams",
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
endpoint = DatastreamEndpoint(self._service)
|
|
89
|
-
|
|
90
|
-
return [
|
|
91
|
-
Datastream(_endpoint=endpoint, _uid=UUID(str(entity.pop("id"))), **entity)
|
|
92
|
-
for entity in json.loads(response.content)
|
|
93
|
-
]
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import pandas as pd
|
|
3
|
-
from typing import List, Union, TYPE_CHECKING
|
|
4
|
-
from uuid import UUID
|
|
5
|
-
from datetime import datetime
|
|
6
|
-
from hydroserverpy.core.endpoints.base import HydroServerEndpoint, expand_docstring
|
|
7
|
-
from hydroserverpy.core.schemas import Datastream
|
|
8
|
-
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from hydroserverpy.core.service import HydroServer
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class DatastreamEndpoint(HydroServerEndpoint):
|
|
14
|
-
"""
|
|
15
|
-
An endpoint for interacting with datastream entities in the HydroServer service.
|
|
16
|
-
|
|
17
|
-
:ivar _model: The model class associated with this endpoint, set to `Datastream`.
|
|
18
|
-
:ivar _api_route: The base route of the API, derived from the service.
|
|
19
|
-
:ivar _endpoint_route: The specific route of the endpoint, set to `'datastreams'`.
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
def __init__(self, service) -> None:
|
|
23
|
-
"""
|
|
24
|
-
Initialize the DatastreamEndpoint.
|
|
25
|
-
|
|
26
|
-
:param service: The HydroServer service instance to use for requests.
|
|
27
|
-
:type service: HydroServer
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
super().__init__(service)
|
|
31
|
-
self._model = Datastream
|
|
32
|
-
self._api_route = self._service.api_route
|
|
33
|
-
self._endpoint_route = "datastreams"
|
|
34
|
-
|
|
35
|
-
def list(
|
|
36
|
-
self, owned_only: bool = False, primary_owned_only: bool = False
|
|
37
|
-
) -> List[Datastream]:
|
|
38
|
-
"""
|
|
39
|
-
Retrieve a collection of datastreams owned by the logged-in user.
|
|
40
|
-
|
|
41
|
-
:param owned_only: Only list datastreams owned by the logged-in user.
|
|
42
|
-
:param primary_owned_only: Only list datastreams primary owned by the logged-in user.
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
return super()._get(
|
|
46
|
-
params={
|
|
47
|
-
"owned_only": owned_only,
|
|
48
|
-
"primary_owned_only": primary_owned_only,
|
|
49
|
-
}
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
@expand_docstring(include_uid=True)
|
|
53
|
-
def get(self, uid: Union[UUID, str]) -> Datastream:
|
|
54
|
-
"""
|
|
55
|
-
Retrieve a datastream owned by the logged-in user.
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
return super()._get(uid)
|
|
59
|
-
|
|
60
|
-
@expand_docstring(model=Datastream)
|
|
61
|
-
def create(self, **kwargs) -> Datastream:
|
|
62
|
-
"""
|
|
63
|
-
Create a new datastream in HydroServer.
|
|
64
|
-
"""
|
|
65
|
-
|
|
66
|
-
return super()._post(**kwargs)
|
|
67
|
-
|
|
68
|
-
@expand_docstring(model=Datastream, include_uid=True)
|
|
69
|
-
def update(self, uid: Union[UUID, str], **kwargs) -> Datastream:
|
|
70
|
-
"""
|
|
71
|
-
Update an existing datastream in HydroServer.
|
|
72
|
-
"""
|
|
73
|
-
|
|
74
|
-
return super()._patch(uid=uid, **kwargs)
|
|
75
|
-
|
|
76
|
-
@expand_docstring(include_uid=True)
|
|
77
|
-
def delete(self, uid: Union[UUID, str]) -> None:
|
|
78
|
-
"""
|
|
79
|
-
Delete an existing datastream in HydroServer.
|
|
80
|
-
"""
|
|
81
|
-
|
|
82
|
-
super()._delete(uid=uid)
|
|
83
|
-
|
|
84
|
-
def get_observations(
|
|
85
|
-
self,
|
|
86
|
-
uid: Union[UUID, str],
|
|
87
|
-
start_time: datetime = None,
|
|
88
|
-
end_time: datetime = None,
|
|
89
|
-
page: int = 1,
|
|
90
|
-
page_size: int = 100000,
|
|
91
|
-
include_quality: bool = False,
|
|
92
|
-
fetch_all: bool = False,
|
|
93
|
-
) -> pd.DataFrame:
|
|
94
|
-
"""
|
|
95
|
-
Retrieve observations from a specific datastream.
|
|
96
|
-
|
|
97
|
-
:param uid: The unique identifier of the datastream.
|
|
98
|
-
:type uid: Union[UUID, str]
|
|
99
|
-
:param start_time: The start time for filtering observations.
|
|
100
|
-
:type start_time: datetime, optional
|
|
101
|
-
:param end_time: The end time for filtering observations.
|
|
102
|
-
:type end_time: datetime, optional
|
|
103
|
-
:param page: The page number to retrieve (used for pagination).
|
|
104
|
-
:type page: int, optional
|
|
105
|
-
:param page_size: The number of observations per page.
|
|
106
|
-
:type page_size: int, optional
|
|
107
|
-
:param include_quality: Whether to include quality information with each observation.
|
|
108
|
-
:type include_quality: bool, optional
|
|
109
|
-
:param fetch_all: Whether to fetch all observations (ignoring pagination).
|
|
110
|
-
:type fetch_all: bool, optional
|
|
111
|
-
:returns: A DataFrame containing the retrieved observations.
|
|
112
|
-
:rtype: pd.DataFrame
|
|
113
|
-
"""
|
|
114
|
-
|
|
115
|
-
filters = []
|
|
116
|
-
if start_time:
|
|
117
|
-
filters.append(
|
|
118
|
-
f'phenomenonTime ge {start_time.strftime("%Y-%m-%dT%H:%M:%S%z")}'
|
|
119
|
-
)
|
|
120
|
-
if end_time:
|
|
121
|
-
filters.append(
|
|
122
|
-
f'phenomenonTime le {end_time.strftime("%Y-%m-%dT%H:%M:%S%z")}'
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
if fetch_all:
|
|
126
|
-
page = 1
|
|
127
|
-
|
|
128
|
-
observations = []
|
|
129
|
-
|
|
130
|
-
while True:
|
|
131
|
-
response = getattr(self._service, "_request")(
|
|
132
|
-
"get",
|
|
133
|
-
f"{self._api_route}/sensorthings/v1.1/Datastreams('{str(uid)}')/Observations",
|
|
134
|
-
params={
|
|
135
|
-
"$resultFormat": "dataArray",
|
|
136
|
-
"$select": f'phenomenonTime,result{",resultQuality" if include_quality else ""}',
|
|
137
|
-
"$count": True,
|
|
138
|
-
"$top": page_size,
|
|
139
|
-
"$skip": (page - 1) * page_size,
|
|
140
|
-
"$filter": " and ".join(filters) if filters else None,
|
|
141
|
-
},
|
|
142
|
-
)
|
|
143
|
-
response_content = json.loads(response.content)
|
|
144
|
-
data_array = (
|
|
145
|
-
response_content["value"][0]["dataArray"]
|
|
146
|
-
if response_content["value"]
|
|
147
|
-
else []
|
|
148
|
-
)
|
|
149
|
-
observations.extend(
|
|
150
|
-
[
|
|
151
|
-
(
|
|
152
|
-
[
|
|
153
|
-
obs[0],
|
|
154
|
-
obs[1],
|
|
155
|
-
obs[2]["qualityCode"] if obs[2]["qualityCode"] else None,
|
|
156
|
-
(
|
|
157
|
-
obs[2]["resultQualifiers"]
|
|
158
|
-
if obs[2]["resultQualifiers"]
|
|
159
|
-
else None
|
|
160
|
-
),
|
|
161
|
-
]
|
|
162
|
-
if include_quality
|
|
163
|
-
else [obs[0], obs[1]]
|
|
164
|
-
)
|
|
165
|
-
for obs in data_array
|
|
166
|
-
]
|
|
167
|
-
)
|
|
168
|
-
if not fetch_all or len(data_array) < page_size:
|
|
169
|
-
break
|
|
170
|
-
page += 1
|
|
171
|
-
|
|
172
|
-
columns = ["timestamp", "value"]
|
|
173
|
-
if include_quality:
|
|
174
|
-
columns.extend(["quality_code", "result_quality"])
|
|
175
|
-
|
|
176
|
-
data_frame = pd.DataFrame(observations, columns=columns)
|
|
177
|
-
data_frame["timestamp"] = pd.to_datetime(data_frame["timestamp"])
|
|
178
|
-
|
|
179
|
-
return data_frame
|
|
180
|
-
|
|
181
|
-
def load_observations(
|
|
182
|
-
self,
|
|
183
|
-
uid: Union[UUID, str],
|
|
184
|
-
observations: pd.DataFrame,
|
|
185
|
-
) -> None:
|
|
186
|
-
"""
|
|
187
|
-
Load observations to a specific datastream.
|
|
188
|
-
|
|
189
|
-
:param uid: The unique identifier of the datastream.
|
|
190
|
-
:type uid: Union[UUID, str]
|
|
191
|
-
:param observations: A DataFrame containing the observations to upload.
|
|
192
|
-
:type observations: pd.DataFrame
|
|
193
|
-
:returns: None
|
|
194
|
-
"""
|
|
195
|
-
|
|
196
|
-
data_array = [
|
|
197
|
-
[
|
|
198
|
-
row["timestamp"].strftime("%Y-%m-%dT%H:%M:%S%z"),
|
|
199
|
-
row["value"],
|
|
200
|
-
(
|
|
201
|
-
{
|
|
202
|
-
"qualityCode": row.get("quality_code", None),
|
|
203
|
-
"resultQualifiers": row.get("result_qualifiers", []),
|
|
204
|
-
}
|
|
205
|
-
if "quality_code" in row or "result_qualifiers" in row
|
|
206
|
-
else {}
|
|
207
|
-
),
|
|
208
|
-
]
|
|
209
|
-
for _, row in observations.iterrows()
|
|
210
|
-
]
|
|
211
|
-
|
|
212
|
-
getattr(self._service, "_request")(
|
|
213
|
-
"post",
|
|
214
|
-
f"{self._api_route}/sensorthings/v1.1/CreateObservations",
|
|
215
|
-
headers={"Content-type": "application/json"},
|
|
216
|
-
data=json.dumps(
|
|
217
|
-
[
|
|
218
|
-
{
|
|
219
|
-
"Datastream": {"@iot.id": str(uid)},
|
|
220
|
-
"components": ["phenomenonTime", "result", "resultQuality"],
|
|
221
|
-
"dataArray": data_array,
|
|
222
|
-
}
|
|
223
|
-
]
|
|
224
|
-
),
|
|
225
|
-
)
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
from typing import Union, List, TYPE_CHECKING
|
|
2
|
-
from uuid import UUID
|
|
3
|
-
from hydroserverpy.core.endpoints.base import HydroServerEndpoint, expand_docstring
|
|
4
|
-
from hydroserverpy.core.schemas import ObservedProperty
|
|
5
|
-
|
|
6
|
-
if TYPE_CHECKING:
|
|
7
|
-
from hydroserverpy.core.service import HydroServer
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class ObservedPropertyEndpoint(HydroServerEndpoint):
|
|
11
|
-
"""
|
|
12
|
-
An endpoint for interacting with observed property entities in the HydroServer service.
|
|
13
|
-
|
|
14
|
-
:ivar _model: The model class associated with this endpoint, set to `ObservedProperty`.
|
|
15
|
-
:ivar _api_route: The base route of the API, derived from the service.
|
|
16
|
-
:ivar _endpoint_route: The specific route of the endpoint, set to `'observed-properties'`.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
def __init__(self, service):
|
|
20
|
-
"""
|
|
21
|
-
Initialize the ObservedPropertyEndpoint.
|
|
22
|
-
|
|
23
|
-
:param service: The HydroServer service instance to use for requests.
|
|
24
|
-
:type service: HydroServer
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
super().__init__(service)
|
|
28
|
-
self._model = ObservedProperty
|
|
29
|
-
self._api_route = self._service.api_route
|
|
30
|
-
self._endpoint_route = "observed-properties"
|
|
31
|
-
|
|
32
|
-
def list(
|
|
33
|
-
self,
|
|
34
|
-
include_owned: bool = True,
|
|
35
|
-
include_unowned: bool = True,
|
|
36
|
-
include_templates: bool = True,
|
|
37
|
-
) -> List[ObservedProperty]:
|
|
38
|
-
"""
|
|
39
|
-
Retrieve a collection of observed properties.
|
|
40
|
-
|
|
41
|
-
:param include_owned: Whether to include owned observed properties.
|
|
42
|
-
:param include_unowned: Whether to include unowned observed properties.
|
|
43
|
-
:param include_templates: Whether to include template observed properties.
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
include_owned is True
|
|
48
|
-
and include_unowned is True
|
|
49
|
-
and include_templates is True
|
|
50
|
-
):
|
|
51
|
-
owner = "anyUserOrNoUser"
|
|
52
|
-
elif (
|
|
53
|
-
include_owned is True
|
|
54
|
-
and include_unowned is True
|
|
55
|
-
and include_templates is False
|
|
56
|
-
):
|
|
57
|
-
owner = "anyUser"
|
|
58
|
-
elif (
|
|
59
|
-
include_owned is True
|
|
60
|
-
and include_unowned is False
|
|
61
|
-
and include_templates is True
|
|
62
|
-
):
|
|
63
|
-
owner = "currentUserOrNoUser"
|
|
64
|
-
elif (
|
|
65
|
-
include_owned is True
|
|
66
|
-
and include_unowned is False
|
|
67
|
-
and include_templates is False
|
|
68
|
-
):
|
|
69
|
-
owner = "currentUser"
|
|
70
|
-
elif (
|
|
71
|
-
include_owned is False
|
|
72
|
-
and include_unowned is False
|
|
73
|
-
and include_templates is True
|
|
74
|
-
):
|
|
75
|
-
owner = "noUser"
|
|
76
|
-
else:
|
|
77
|
-
return []
|
|
78
|
-
|
|
79
|
-
return super()._get(params={"owner": owner})
|
|
80
|
-
|
|
81
|
-
@expand_docstring(include_uid=True)
|
|
82
|
-
def get(self, uid: Union[UUID, str]) -> ObservedProperty:
|
|
83
|
-
"""
|
|
84
|
-
Retrieve an observed property owned by the logged-in user.
|
|
85
|
-
"""
|
|
86
|
-
|
|
87
|
-
return super()._get(uid)
|
|
88
|
-
|
|
89
|
-
@expand_docstring(model=ObservedProperty)
|
|
90
|
-
def create(self, **kwargs) -> ObservedProperty:
|
|
91
|
-
"""
|
|
92
|
-
Create a new observed property in HydroServer.
|
|
93
|
-
"""
|
|
94
|
-
|
|
95
|
-
return super()._post(**kwargs)
|
|
96
|
-
|
|
97
|
-
@expand_docstring(model=ObservedProperty, include_uid=True)
|
|
98
|
-
def update(self, uid: Union[UUID, str], **kwargs) -> ObservedProperty:
|
|
99
|
-
"""
|
|
100
|
-
Update an existing observed property in HydroServer.
|
|
101
|
-
"""
|
|
102
|
-
|
|
103
|
-
return super()._patch(uid=uid, **kwargs)
|
|
104
|
-
|
|
105
|
-
@expand_docstring(include_uid=True)
|
|
106
|
-
def delete(self, uid: Union[UUID, str]) -> None:
|
|
107
|
-
"""
|
|
108
|
-
Delete an existing observed property in HydroServer.
|
|
109
|
-
"""
|
|
110
|
-
|
|
111
|
-
super()._delete(uid=uid)
|