hydroserverpy 1.2.1__py3-none-any.whl → 1.3.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.

Files changed (47) hide show
  1. hydroserverpy/__init__.py +1 -1
  2. hydroserverpy/api/{main.py → client.py} +52 -22
  3. hydroserverpy/api/models/__init__.py +1 -2
  4. hydroserverpy/api/models/base.py +180 -47
  5. hydroserverpy/api/models/etl/data_archive.py +31 -59
  6. hydroserverpy/api/models/etl/data_source.py +34 -76
  7. hydroserverpy/api/models/etl/orchestration_system.py +23 -38
  8. hydroserverpy/api/models/iam/apikey.py +57 -38
  9. hydroserverpy/api/models/iam/collaborator.py +55 -19
  10. hydroserverpy/api/models/iam/role.py +32 -4
  11. hydroserverpy/api/models/iam/workspace.py +58 -86
  12. hydroserverpy/api/models/sta/datastream.py +122 -214
  13. hydroserverpy/api/models/sta/observation.py +101 -0
  14. hydroserverpy/api/models/sta/observed_property.py +18 -53
  15. hydroserverpy/api/models/sta/processing_level.py +16 -31
  16. hydroserverpy/api/models/sta/result_qualifier.py +16 -31
  17. hydroserverpy/api/models/sta/sensor.py +27 -88
  18. hydroserverpy/api/models/sta/thing.py +48 -152
  19. hydroserverpy/api/models/sta/unit.py +16 -29
  20. hydroserverpy/api/services/__init__.py +1 -0
  21. hydroserverpy/api/services/base.py +92 -76
  22. hydroserverpy/api/services/etl/data_archive.py +42 -72
  23. hydroserverpy/api/services/etl/data_source.py +42 -72
  24. hydroserverpy/api/services/etl/orchestration_system.py +25 -33
  25. hydroserverpy/api/services/iam/role.py +38 -0
  26. hydroserverpy/api/services/iam/workspace.py +96 -99
  27. hydroserverpy/api/services/sta/datastream.py +151 -210
  28. hydroserverpy/api/services/sta/observed_property.py +31 -49
  29. hydroserverpy/api/services/sta/processing_level.py +30 -36
  30. hydroserverpy/api/services/sta/result_qualifier.py +24 -34
  31. hydroserverpy/api/services/sta/sensor.py +34 -48
  32. hydroserverpy/api/services/sta/thing.py +96 -89
  33. hydroserverpy/api/services/sta/unit.py +30 -34
  34. hydroserverpy/api/utils.py +22 -0
  35. hydroserverpy/etl/extractors/base.py +2 -4
  36. hydroserverpy/etl/loaders/hydroserver_loader.py +1 -0
  37. hydroserverpy/etl/timestamp_parser.py +82 -48
  38. hydroserverpy/etl/transformers/base.py +5 -9
  39. hydroserverpy/etl_csv/hydroserver_etl_csv.py +1 -1
  40. {hydroserverpy-1.2.1.dist-info → hydroserverpy-1.3.0b2.dist-info}/METADATA +1 -1
  41. hydroserverpy-1.3.0b2.dist-info/RECORD +70 -0
  42. hydroserverpy/api/http.py +0 -22
  43. hydroserverpy-1.2.1.dist-info/RECORD +0 -68
  44. {hydroserverpy-1.2.1.dist-info → hydroserverpy-1.3.0b2.dist-info}/WHEEL +0 -0
  45. {hydroserverpy-1.2.1.dist-info → hydroserverpy-1.3.0b2.dist-info}/licenses/LICENSE +0 -0
  46. {hydroserverpy-1.2.1.dist-info → hydroserverpy-1.3.0b2.dist-info}/top_level.txt +0 -0
  47. {hydroserverpy-1.2.1.dist-info → hydroserverpy-1.3.0b2.dist-info}/zip-safe +0 -0
@@ -1,102 +1,118 @@
1
- from typing import TYPE_CHECKING, Type, Union, Optional
1
+ import json
2
+ import uuid
3
+ from typing import TYPE_CHECKING, Type, List, Union
2
4
  from datetime import datetime
3
- from uuid import UUID
5
+ from hydroserverpy.api.models.base import HydroServerBaseModel, HydroServerCollection
6
+ from hydroserverpy.api.utils import order_by_to_camel
4
7
 
5
8
  if TYPE_CHECKING:
6
9
  from hydroserverpy import HydroServer
7
- from hydroserverpy.api.models.base import HydroServerModel
8
10
 
9
11
 
10
- class EndpointService:
11
- _model: Type["HydroServerModel"]
12
- _api_route: str
13
- _endpoint_route: str
12
+ class HydroServerBaseService:
13
+ model: Type[HydroServerBaseModel]
14
14
 
15
- def __init__(self, connection: "HydroServer") -> None:
16
- self._connection = connection
15
+ def __init__(self, client: "HydroServer") -> None:
16
+ self.client = client
17
17
 
18
- def _list(self, params: Optional[dict] = None):
19
- path = f"/{self._api_route}/{self._endpoint_route}"
20
-
21
- response = self._connection.request("get", path, params=params).json()
18
+ def list(
19
+ self,
20
+ page: int = ...,
21
+ page_size: int = ...,
22
+ order_by: List[str] = ...,
23
+ fetch_all: bool = False,
24
+ **kwargs
25
+ ):
26
+ kwargs = {
27
+ k: v for k, v in kwargs.items() if v is not ...
28
+ }
29
+ params = kwargs.copy()
30
+ params.update({
31
+ "page": page,
32
+ "page_size": page_size,
33
+ "order_by": [order_by_to_camel(order) for order in order_by] if order_by is not ... else order_by
34
+ })
35
+ params = {
36
+ k: ("null" if v is None else v)
37
+ for k, v in params.items()
38
+ if v is not ...
39
+ }
40
+
41
+ path = f"/{self.client.base_route}/{self.model.get_route()}"
42
+ response = self.client.request("get", path, params=params)
43
+ collection = HydroServerCollection(
44
+ model=self.model,
45
+ client=self.client,
46
+ service=self,
47
+ response=response,
48
+ order_by=params.get("order_by"),
49
+ filters={
50
+ (k[:-3] if k.endswith("_id") else k): v
51
+ for k, v in kwargs.items()
52
+ }
53
+ )
54
+ if fetch_all is True:
55
+ collection = collection.fetch_all()
22
56
 
23
- return [
24
- self._model(
25
- _connection=self._connection, _uid=UUID(str(obj.pop("id"))), **obj
26
- )
27
- for obj in response
28
- ]
57
+ return collection
29
58
 
30
- def _get(self, uid: Union[UUID, str]):
31
- path = f"/{self._api_route}/{self._endpoint_route}/{str(uid)}"
32
- response = self._connection.request("get", path).json()
59
+ def get(
60
+ self,
61
+ uid: Union[uuid.UUID, str]
62
+ ):
63
+ path = f"/{self.client.base_route}/{self.model.get_route()}/{str(uid)}"
64
+ response = self.client.request("get", path).json()
33
65
 
34
- return self._model(
35
- _connection=self._connection, _uid=UUID(str(response.pop("id"))), **response
66
+ return self.model(
67
+ client=self.client, uid=uuid.UUID(str(response.pop("id"))), **response
36
68
  )
37
69
 
38
- def _create(self, **kwargs):
39
- path = f"/{self._api_route}/{self._endpoint_route}"
70
+ def create(self, **kwargs):
71
+ path = f"/{self.client.base_route}/{self.model.get_route()}"
40
72
  headers = {"Content-type": "application/json"}
41
- response = self._connection.request(
42
- "post", path, headers=headers, json=self._to_iso_time(kwargs)
73
+ response = self.client.request(
74
+ "post", path, headers=headers, data=json.dumps(kwargs, default=self.default_serializer)
43
75
  ).json()
44
76
 
45
- return self._model(
46
- _connection=self._connection, _uid=UUID(str(response.pop("id"))), **response
77
+ return self.model(
78
+ client=self.client, uid=uuid.UUID(str(response.pop("id"))), **response
47
79
  )
48
80
 
49
- def _update(self, uid: Union[UUID, str], **kwargs):
50
- path = f"/{self._api_route}/{self._endpoint_route}/{str(uid)}"
81
+ def update(
82
+ self,
83
+ uid: Union[uuid.UUID, str],
84
+ **kwargs
85
+ ):
86
+ path = f"/{self.client.base_route}/{self.model.get_route()}/{str(uid)}"
51
87
  headers = {"Content-type": "application/json"}
52
- response = self._connection.request(
53
- "patch", path, headers=headers, json=self._to_iso_time(kwargs)
88
+ body = self.prune_unset(kwargs) or {}
89
+ response = self.client.request(
90
+ "patch", path, headers=headers, data=json.dumps(body, default=self.default_serializer)
54
91
  ).json()
55
92
 
56
- return self._model(
57
- _connection=self._connection, _uid=UUID(str(response.pop("id"))), **response
93
+ return self.model(
94
+ client=self.client, uid=uuid.UUID(str(response.pop("id"))), **response
58
95
  )
59
96
 
60
- def _delete(self, uid: Union[UUID, str]):
61
- path = f"/{self._api_route}/{self._endpoint_route}/{str(uid)}"
62
- response = self._connection.request("delete", path)
63
-
64
- return response
97
+ def delete(
98
+ self,
99
+ uid: Union[uuid.UUID, str]
100
+ ) -> None:
101
+ path = f"/{self.client.base_route}/{self.model.get_route()}/{str(uid)}"
102
+ self.client.request("delete", path)
103
+
104
+ @staticmethod
105
+ def default_serializer(obj):
106
+ if isinstance(obj, datetime):
107
+ return obj.isoformat()
108
+ raise TypeError(f"Type {type(obj)} not serializable")
65
109
 
66
- def _to_iso_time(self, obj):
110
+ def prune_unset(self, obj):
67
111
  if isinstance(obj, dict):
68
- return {k: self._to_iso_time(v) for k, v in obj.items()}
69
- elif isinstance(obj, list):
70
- return [self._to_iso_time(i) for i in obj]
71
- elif isinstance(obj, datetime):
72
- return obj.isoformat()
112
+ cleaned = {
113
+ k: self.prune_unset(v)
114
+ for k, v in obj.items()
115
+ if v is not ... and self.prune_unset(v) is not None
116
+ }
117
+ return cleaned if cleaned else None
73
118
  return obj
74
-
75
-
76
- class SensorThingsService(EndpointService):
77
- _sta_route: str
78
-
79
- def __init__(self, connection) -> None:
80
- super().__init__(connection)
81
-
82
- def _list(self, path: Optional[str] = None, params: Optional[dict] = None):
83
- path = path or f"/{self._sta_route}"
84
- response = self._connection.request("get", path, params=params)
85
-
86
- return [
87
- self._model(_connection=self._connection, _uid=obj.pop("@iot.id"), **obj)
88
- for obj in response.json()["value"]
89
- ]
90
-
91
- def _get(
92
- self,
93
- uid: Union[UUID, str],
94
- path: Optional[str] = None,
95
- params: Optional[dict] = None,
96
- ):
97
- path = path or f"/{self._sta_route}('{str(uid)}')"
98
- response = self._connection.request("get", path, params=params).json()
99
-
100
- return self._model(
101
- _connection=self._connection, _uid=response.pop("@iot.id"), **response
102
- )
@@ -1,57 +1,42 @@
1
- from datetime import datetime
2
- from typing import Optional, Literal, Union, List, TYPE_CHECKING
1
+ from typing import Optional, Union, List, Literal, TYPE_CHECKING
3
2
  from uuid import UUID
4
- from ..base import EndpointService
5
- from hydroserverpy.api.models import DataArchive, Datastream
6
-
3
+ from datetime import datetime
4
+ from hydroserverpy.api.models import DataArchive
5
+ from hydroserverpy.api.utils import normalize_uuid
6
+ from ..base import HydroServerBaseService
7
7
 
8
8
  if TYPE_CHECKING:
9
9
  from hydroserverpy import HydroServer
10
- from hydroserverpy.api.models import Workspace, OrchestrationSystem
10
+ from hydroserverpy.api.models import Workspace, OrchestrationSystem, Datastream
11
11
 
12
12
 
13
- class DataArchiveService(EndpointService):
14
- def __init__(self, connection: "HydroServer"):
15
- self._model = DataArchive
16
- self._api_route = "api/data"
17
- self._endpoint_route = "data-archives"
18
-
19
- super().__init__(connection)
13
+ class DataArchiveService(HydroServerBaseService):
14
+ def __init__(self, client: "HydroServer"):
15
+ self.model = DataArchive
16
+ super().__init__(client)
20
17
 
21
18
  def list(
22
19
  self,
23
- workspace: Optional[Union["Workspace", UUID, str]] = None,
24
- orchestration_system: Optional[Union["OrchestrationSystem", UUID, str]] = None,
20
+ page: int = ...,
21
+ page_size: int = ...,
22
+ order_by: List[str] = ...,
23
+ workspace: Optional[Union["Workspace", UUID, str]] = ...,
24
+ datastream: Optional[Union["Datastream", UUID, str]] = ...,
25
+ orchestration_system: Optional[Union["OrchestrationSystem", UUID, str]] = ...,
26
+ fetch_all: bool = False,
25
27
  ) -> List["DataArchive"]:
26
28
  """Fetch a collection of data archives."""
27
29
 
28
- params = {}
29
-
30
- workspace_id = getattr(workspace, "uid", workspace)
31
- workspace_id = str(workspace_id) if workspace_id else None
32
-
33
- orchestration_system_id = getattr(
34
- orchestration_system, "uid", orchestration_system
35
- )
36
- orchestration_system_id = (
37
- str(orchestration_system_id) if orchestration_system_id else None
38
- )
39
-
40
- if workspace_id:
41
- params["workspace_id"] = workspace_id
42
-
43
- if orchestration_system_id:
44
- params["orchestration_system_id"] = orchestration_system_id
45
-
46
- return super()._list(
47
- params=params,
30
+ return super().list(
31
+ page=page,
32
+ page_size=page_size,
33
+ order_by=order_by,
34
+ workspace_id=normalize_uuid(workspace),
35
+ datastream_id=normalize_uuid(datastream),
36
+ orchestration_system_id=normalize_uuid(orchestration_system),
37
+ fetch_all=fetch_all,
48
38
  )
49
39
 
50
- def get(self, uid: Union[UUID, str]) -> "DataArchive":
51
- """Get a data archive by ID."""
52
-
53
- return super()._get(uid=str(uid))
54
-
55
40
  def create(
56
41
  self,
57
42
  name: str,
@@ -72,12 +57,10 @@ class DataArchiveService(EndpointService):
72
57
  ) -> "DataArchive":
73
58
  """Create a new data archive."""
74
59
 
75
- kwargs = {
60
+ body = {
76
61
  "name": name,
77
- "workspaceId": str(getattr(workspace, "uid", workspace)),
78
- "orchestrationSystemId": getattr(
79
- orchestration_system, "uid", orchestration_system
80
- ),
62
+ "workspaceId": normalize_uuid(workspace),
63
+ "orchestrationSystemId": normalize_uuid(orchestration_system),
81
64
  "settings": settings,
82
65
  "schedule": {
83
66
  "interval": interval,
@@ -95,7 +78,7 @@ class DataArchiveService(EndpointService):
95
78
  },
96
79
  "datastreamIds": (
97
80
  [
98
- str(getattr(datastream, "uid", datastream))
81
+ normalize_uuid(datastream)
99
82
  for datastream in datastreams
100
83
  ]
101
84
  if datastreams
@@ -103,7 +86,7 @@ class DataArchiveService(EndpointService):
103
86
  ),
104
87
  }
105
88
 
106
- return super()._create(**kwargs)
89
+ return super().create(**body)
107
90
 
108
91
  def update(
109
92
  self,
@@ -124,7 +107,7 @@ class DataArchiveService(EndpointService):
124
107
  ) -> "DataArchive":
125
108
  """Update a data archive."""
126
109
 
127
- status_kwargs = {
110
+ status_body = {
128
111
  k: v
129
112
  for k, v in {
130
113
  "lastRunSuccessful": last_run_successful,
@@ -135,9 +118,9 @@ class DataArchiveService(EndpointService):
135
118
  }.items()
136
119
  if v is not ...
137
120
  }
138
- status_kwargs = status_kwargs if status_kwargs else ...
121
+ status_body = status_body if status_body else ...
139
122
 
140
- schedule_kwargs = {
123
+ schedule_body = {
141
124
  k: v
142
125
  for k, v in {
143
126
  "interval": interval,
@@ -148,9 +131,9 @@ class DataArchiveService(EndpointService):
148
131
  }.items()
149
132
  if v is not ...
150
133
  }
151
- schedule_kwargs = schedule_kwargs if schedule_kwargs else ...
134
+ schedule_body = schedule_body if schedule_body else ...
152
135
 
153
- kwargs = {
136
+ body = {
154
137
  k: v
155
138
  for k, v in {
156
139
  "name": name,
@@ -158,39 +141,26 @@ class DataArchiveService(EndpointService):
158
141
  orchestration_system, "uid", orchestration_system
159
142
  ),
160
143
  "settings": settings,
161
- "schedule": schedule_kwargs,
162
- "status": status_kwargs,
144
+ "schedule": schedule_body,
145
+ "status": status_body,
163
146
  }.items()
164
147
  if v is not ...
165
148
  }
166
149
 
167
- return super()._update(uid=str(uid), **kwargs)
168
-
169
- def delete(self, uid: Union[UUID, str]) -> None:
170
- """Delete a data archive."""
171
-
172
- super()._delete(uid=str(uid))
150
+ return super().update(uid=str(uid), **body)
173
151
 
174
152
  def add_datastream(
175
153
  self, uid: Union[UUID, str], datastream: Union["Datastream", UUID, str]
176
154
  ) -> None:
177
155
  """Add a datastream to this data archive."""
178
156
 
179
- datastream_id = str(getattr(datastream, "uid", datastream))
180
-
181
- self._connection.request(
182
- "post",
183
- f"{self._api_route}/{self._endpoint_route}/{str(uid)}/datastreams/{datastream_id}",
184
- )
157
+ path = f"/{self.client.base_route}/{self.model.get_route()}/{str(uid)}/datastreams/{normalize_uuid(datastream)}"
158
+ self.client.request("put", path)
185
159
 
186
160
  def remove_datastream(
187
161
  self, uid: Union[UUID, str], datastream: Union["Datastream", UUID, str]
188
162
  ) -> None:
189
163
  """Remove a datastream from this data archive."""
190
164
 
191
- datastream_id = str(getattr(datastream, "uid", datastream))
192
-
193
- self._connection.request(
194
- "delete",
195
- f"{self._api_route}/{self._endpoint_route}/{str(uid)}/datastreams/{datastream_id}",
196
- )
165
+ path = f"/{self.client.base_route}/{self.model.get_route()}/{str(uid)}/datastreams/{normalize_uuid(datastream)}"
166
+ self.client.request("delete", path)
@@ -1,57 +1,42 @@
1
- from datetime import datetime
2
- from typing import Optional, Literal, Union, List, TYPE_CHECKING
1
+ from typing import Optional, Union, List, Literal, TYPE_CHECKING
3
2
  from uuid import UUID
4
- from ..base import EndpointService
5
- from hydroserverpy.api.models import DataSource, Datastream
6
-
3
+ from datetime import datetime
4
+ from hydroserverpy.api.models import DataSource
5
+ from hydroserverpy.api.utils import normalize_uuid
6
+ from ..base import HydroServerBaseService
7
7
 
8
8
  if TYPE_CHECKING:
9
9
  from hydroserverpy import HydroServer
10
- from hydroserverpy.api.models import Workspace, OrchestrationSystem
10
+ from hydroserverpy.api.models import Workspace, OrchestrationSystem, Datastream
11
11
 
12
12
 
13
- class DataSourceService(EndpointService):
14
- def __init__(self, connection: "HydroServer"):
15
- self._model = DataSource
16
- self._api_route = "api/data"
17
- self._endpoint_route = "data-sources"
18
-
19
- super().__init__(connection)
13
+ class DataSourceService(HydroServerBaseService):
14
+ def __init__(self, client: "HydroServer"):
15
+ self.model = DataSource
16
+ super().__init__(client)
20
17
 
21
18
  def list(
22
19
  self,
23
- workspace: Optional[Union["Workspace", UUID, str]] = None,
24
- orchestration_system: Optional[Union["OrchestrationSystem", UUID, str]] = None,
20
+ page: int = ...,
21
+ page_size: int = ...,
22
+ order_by: List[str] = ...,
23
+ workspace: Optional[Union["Workspace", UUID, str]] = ...,
24
+ datastream: Optional[Union["Datastream", UUID, str]] = ...,
25
+ orchestration_system: Optional[Union["OrchestrationSystem", UUID, str]] = ...,
26
+ fetch_all: bool = False,
25
27
  ) -> List["DataSource"]:
26
28
  """Fetch a collection of data sources."""
27
29
 
28
- params = {}
29
-
30
- workspace_id = getattr(workspace, "uid", workspace)
31
- workspace_id = str(workspace_id) if workspace_id else None
32
-
33
- orchestration_system_id = getattr(
34
- orchestration_system, "uid", orchestration_system
35
- )
36
- orchestration_system_id = (
37
- str(orchestration_system_id) if orchestration_system_id else None
38
- )
39
-
40
- if workspace_id:
41
- params["workspace_id"] = workspace_id
42
-
43
- if orchestration_system_id:
44
- params["orchestration_system_id"] = orchestration_system_id
45
-
46
- return super()._list(
47
- params=params,
30
+ return super().list(
31
+ page=page,
32
+ page_size=page_size,
33
+ order_by=order_by,
34
+ workspace_id=normalize_uuid(workspace),
35
+ datastream_id=normalize_uuid(datastream),
36
+ orchestration_system_id=normalize_uuid(orchestration_system),
37
+ fetch_all=fetch_all,
48
38
  )
49
39
 
50
- def get(self, uid: Union[UUID, str]) -> "DataSource":
51
- """Get a data source by ID."""
52
-
53
- return super()._get(uid=str(uid))
54
-
55
40
  def create(
56
41
  self,
57
42
  name: str,
@@ -72,12 +57,10 @@ class DataSourceService(EndpointService):
72
57
  ) -> "DataSource":
73
58
  """Create a new data source."""
74
59
 
75
- kwargs = {
60
+ body = {
76
61
  "name": name,
77
- "workspaceId": str(getattr(workspace, "uid", workspace)),
78
- "orchestrationSystemId": getattr(
79
- orchestration_system, "uid", orchestration_system
80
- ),
62
+ "workspaceId": normalize_uuid(workspace),
63
+ "orchestrationSystemId": normalize_uuid(orchestration_system),
81
64
  "settings": settings,
82
65
  "schedule": {
83
66
  "interval": interval,
@@ -95,7 +78,7 @@ class DataSourceService(EndpointService):
95
78
  },
96
79
  "datastreamIds": (
97
80
  [
98
- str(getattr(datastream, "uid", datastream))
81
+ normalize_uuid(datastream)
99
82
  for datastream in datastreams
100
83
  ]
101
84
  if datastreams
@@ -103,7 +86,7 @@ class DataSourceService(EndpointService):
103
86
  ),
104
87
  }
105
88
 
106
- return super()._create(**kwargs)
89
+ return super().create(**body)
107
90
 
108
91
  def update(
109
92
  self,
@@ -124,7 +107,7 @@ class DataSourceService(EndpointService):
124
107
  ) -> "DataSource":
125
108
  """Update a data source."""
126
109
 
127
- status_kwargs = {
110
+ status_body = {
128
111
  k: v
129
112
  for k, v in {
130
113
  "lastRunSuccessful": last_run_successful,
@@ -135,9 +118,9 @@ class DataSourceService(EndpointService):
135
118
  }.items()
136
119
  if v is not ...
137
120
  }
138
- status_kwargs = status_kwargs if status_kwargs else ...
121
+ status_body = status_body if status_body else ...
139
122
 
140
- schedule_kwargs = {
123
+ schedule_body = {
141
124
  k: v
142
125
  for k, v in {
143
126
  "interval": interval,
@@ -148,9 +131,9 @@ class DataSourceService(EndpointService):
148
131
  }.items()
149
132
  if v is not ...
150
133
  }
151
- schedule_kwargs = schedule_kwargs if schedule_kwargs else ...
134
+ schedule_body = schedule_body if schedule_body else ...
152
135
 
153
- kwargs = {
136
+ body = {
154
137
  k: v
155
138
  for k, v in {
156
139
  "name": name,
@@ -158,39 +141,26 @@ class DataSourceService(EndpointService):
158
141
  orchestration_system, "uid", orchestration_system
159
142
  ),
160
143
  "settings": settings,
161
- "schedule": schedule_kwargs,
162
- "status": status_kwargs,
144
+ "schedule": schedule_body,
145
+ "status": status_body,
163
146
  }.items()
164
147
  if v is not ...
165
148
  }
166
149
 
167
- return super()._update(uid=str(uid), **kwargs)
168
-
169
- def delete(self, uid: Union[UUID, str]) -> None:
170
- """Delete a data source."""
171
-
172
- super()._delete(uid=str(uid))
150
+ return super().update(uid=str(uid), **body)
173
151
 
174
152
  def add_datastream(
175
153
  self, uid: Union[UUID, str], datastream: Union["Datastream", UUID, str]
176
154
  ) -> None:
177
155
  """Add a datastream to this data source."""
178
156
 
179
- datastream_id = str(getattr(datastream, "uid", datastream))
180
-
181
- self._connection.request(
182
- "post",
183
- f"{self._api_route}/{self._endpoint_route}/{str(uid)}/datastreams/{datastream_id}",
184
- )
157
+ path = f"/{self.client.base_route}/{self.model.get_route()}/{str(uid)}/datastreams/{normalize_uuid(datastream)}"
158
+ self.client.request("put", path)
185
159
 
186
160
  def remove_datastream(
187
161
  self, uid: Union[UUID, str], datastream: Union["Datastream", UUID, str]
188
162
  ) -> None:
189
163
  """Remove a datastream from this data source."""
190
164
 
191
- datastream_id = str(getattr(datastream, "uid", datastream))
192
-
193
- self._connection.request(
194
- "delete",
195
- f"{self._api_route}/{self._endpoint_route}/{str(uid)}/datastreams/{datastream_id}",
196
- )
165
+ path = f"/{self.client.base_route}/{self.model.get_route()}/{str(uid)}/datastreams/{normalize_uuid(datastream)}"
166
+ self.client.request("delete", path)