hydroserverpy 0.3.0__py3-none-any.whl → 0.4.0__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 (49) hide show
  1. hydroserverpy/__init__.py +1 -1
  2. hydroserverpy/core/endpoints/base.py +44 -31
  3. hydroserverpy/core/endpoints/data_loaders.py +6 -5
  4. hydroserverpy/core/endpoints/data_sources.py +6 -5
  5. hydroserverpy/core/endpoints/datastreams.py +89 -52
  6. hydroserverpy/core/endpoints/observed_properties.py +36 -18
  7. hydroserverpy/core/endpoints/processing_levels.py +36 -18
  8. hydroserverpy/core/endpoints/result_qualifiers.py +37 -19
  9. hydroserverpy/core/endpoints/sensors.py +37 -19
  10. hydroserverpy/core/endpoints/things.py +58 -37
  11. hydroserverpy/core/endpoints/units.py +37 -19
  12. hydroserverpy/core/schemas/base.py +13 -6
  13. hydroserverpy/core/schemas/data_loaders.py +6 -4
  14. hydroserverpy/core/schemas/data_sources.py +73 -56
  15. hydroserverpy/core/schemas/datastreams.py +101 -70
  16. hydroserverpy/core/schemas/observed_properties.py +18 -10
  17. hydroserverpy/core/schemas/processing_levels.py +10 -6
  18. hydroserverpy/core/schemas/result_qualifiers.py +7 -4
  19. hydroserverpy/core/schemas/sensors.py +33 -18
  20. hydroserverpy/core/schemas/things.py +97 -60
  21. hydroserverpy/core/schemas/units.py +7 -8
  22. hydroserverpy/core/service.py +31 -17
  23. hydroserverpy/etl/__init__.py +21 -0
  24. hydroserverpy/etl/extractors/__init__.py +0 -0
  25. hydroserverpy/etl/extractors/base.py +13 -0
  26. hydroserverpy/etl/extractors/ftp_extractor.py +50 -0
  27. hydroserverpy/etl/extractors/http_extractor.py +84 -0
  28. hydroserverpy/etl/extractors/local_file_extractor.py +25 -0
  29. hydroserverpy/etl/hydroserver_etl.py +40 -0
  30. hydroserverpy/etl/loaders/__init__.py +0 -0
  31. hydroserverpy/etl/loaders/base.py +13 -0
  32. hydroserverpy/etl/loaders/hydroserver_loader.py +68 -0
  33. hydroserverpy/etl/transformers/__init__.py +0 -0
  34. hydroserverpy/etl/transformers/base.py +52 -0
  35. hydroserverpy/etl/transformers/csv_transformer.py +88 -0
  36. hydroserverpy/etl/transformers/json_transformer.py +62 -0
  37. hydroserverpy/etl/types.py +7 -0
  38. hydroserverpy/etl_csv/__init__.py +0 -0
  39. hydroserverpy/{etl/service.py → etl_csv/hydroserver_etl_csv.py} +92 -54
  40. hydroserverpy/quality/service.py +84 -70
  41. hydroserverpy-0.4.0.dist-info/METADATA +18 -0
  42. hydroserverpy-0.4.0.dist-info/RECORD +51 -0
  43. {hydroserverpy-0.3.0.dist-info → hydroserverpy-0.4.0.dist-info}/WHEEL +1 -1
  44. hydroserverpy-0.3.0.dist-info/METADATA +0 -18
  45. hydroserverpy-0.3.0.dist-info/RECORD +0 -36
  46. /hydroserverpy/{etl → etl_csv}/exceptions.py +0 -0
  47. {hydroserverpy-0.3.0.dist-info → hydroserverpy-0.4.0.dist-info}/LICENSE +0 -0
  48. {hydroserverpy-0.3.0.dist-info → hydroserverpy-0.4.0.dist-info}/top_level.txt +0 -0
  49. {hydroserverpy-0.3.0.dist-info → hydroserverpy-0.4.0.dist-info}/zip-safe +0 -0
@@ -16,7 +16,7 @@ class SensorEndpoint(HydroServerEndpoint):
16
16
  :ivar _endpoint_route: The specific route of the endpoint, set to `'sensors'`.
17
17
  """
18
18
 
19
- def __init__(self, service: 'HydroServer'):
19
+ def __init__(self, service: "HydroServer"):
20
20
  """
21
21
  Initialize the SensorEndpoint.
22
22
 
@@ -27,13 +27,13 @@ class SensorEndpoint(HydroServerEndpoint):
27
27
  super().__init__(service)
28
28
  self._model = Sensor
29
29
  self._api_route = self._service.api_route
30
- self._endpoint_route = 'sensors'
30
+ self._endpoint_route = "sensors"
31
31
 
32
32
  def list(
33
- self,
34
- include_owned: bool = True,
35
- include_unowned: bool = True,
36
- include_templates: bool = True
33
+ self,
34
+ include_owned: bool = True,
35
+ include_unowned: bool = True,
36
+ include_templates: bool = True,
37
37
  ) -> List[Sensor]:
38
38
  """
39
39
  Retrieve a collection of sensors.
@@ -43,22 +43,40 @@ class SensorEndpoint(HydroServerEndpoint):
43
43
  :param include_templates: Whether to include template observed properties.
44
44
  """
45
45
 
46
- if include_owned is True and include_unowned is True and include_templates is True:
47
- owner = 'anyUserOrNoUser'
48
- elif include_owned is True and include_unowned is True and include_templates is False:
49
- owner = 'anyUser'
50
- elif include_owned is True and include_unowned is False and include_templates is True:
51
- owner = 'currentUserOrNoUser'
52
- elif include_owned is True and include_unowned is False and include_templates is False:
53
- owner = 'currentUser'
54
- elif include_owned is False and include_unowned is False and include_templates is True:
55
- owner = 'noUser'
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"
56
76
  else:
57
77
  return []
58
78
 
59
- return super()._get(params={
60
- 'owner': owner
61
- })
79
+ return super()._get(params={"owner": owner})
62
80
 
63
81
  @expand_docstring(include_uid=True)
64
82
  def get(self, uid: Union[UUID, str]) -> Sensor:
@@ -18,7 +18,7 @@ class ThingEndpoint(HydroServerEndpoint):
18
18
  :ivar _endpoint_route: The specific route of the endpoint, set to `'things'`.
19
19
  """
20
20
 
21
- def __init__(self, service: 'HydroServer'):
21
+ def __init__(self, service: "HydroServer"):
22
22
  """
23
23
  Initialize the ThingEndpoint.
24
24
 
@@ -29,9 +29,11 @@ class ThingEndpoint(HydroServerEndpoint):
29
29
  super().__init__(service)
30
30
  self._model = Thing
31
31
  self._api_route = self._service.api_route
32
- self._endpoint_route = 'things'
32
+ self._endpoint_route = "things"
33
33
 
34
- def list(self, owned_only: bool = False, primary_owned_only: bool = False) -> List[Thing]:
34
+ def list(
35
+ self, owned_only: bool = False, primary_owned_only: bool = False
36
+ ) -> List[Thing]:
35
37
  """
36
38
  Retrieve a collection of things owned by the logged-in user.
37
39
 
@@ -39,10 +41,12 @@ class ThingEndpoint(HydroServerEndpoint):
39
41
  :param primary_owned_only: Only list things primary owned by the logged-in user.
40
42
  """
41
43
 
42
- return super()._get(params={
43
- 'owned_only': owned_only,
44
- 'primary_owned_only': primary_owned_only,
45
- })
44
+ return super()._get(
45
+ params={
46
+ "owned_only": owned_only,
47
+ "primary_owned_only": primary_owned_only,
48
+ }
49
+ )
46
50
 
47
51
  @expand_docstring(include_uid=True)
48
52
  def get(self, uid: Union[UUID, str]) -> Thing:
@@ -86,14 +90,15 @@ class ThingEndpoint(HydroServerEndpoint):
86
90
  :rtype: List[Datastream]
87
91
  """
88
92
 
89
- response = getattr(self._service, '_request')(
90
- 'get', f'{self._api_route}/data/{self._endpoint_route}/{str(uid)}/datastreams'
93
+ response = getattr(self._service, "_request")(
94
+ "get",
95
+ f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}/datastreams",
91
96
  )
92
97
 
93
98
  endpoint = DatastreamEndpoint(self._service)
94
99
 
95
100
  return [
96
- Datastream(_endpoint=endpoint, _uid=UUID(str(entity.pop('id'))), **entity)
101
+ Datastream(_endpoint=endpoint, _uid=UUID(str(entity.pop("id"))), **entity)
97
102
  for entity in json.loads(response.content)
98
103
  ]
99
104
 
@@ -107,11 +112,14 @@ class ThingEndpoint(HydroServerEndpoint):
107
112
  :rtype: List[Tag]
108
113
  """
109
114
 
110
- response = getattr(self._service, '_request')(
111
- 'get', f'{self._api_route}/data/{self._endpoint_route}/{str(uid)}/tags'
115
+ response = getattr(self._service, "_request")(
116
+ "get", f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}/tags"
112
117
  )
113
118
 
114
- return [Tag(_uid=UUID(str(entity.pop('id'))), **entity) for entity in json.loads(response.content)]
119
+ return [
120
+ Tag(_uid=UUID(str(entity.pop("id"))), **entity)
121
+ for entity in json.loads(response.content)
122
+ ]
115
123
 
116
124
  def create_tag(self, uid: Union[UUID, str], key: str, value: str) -> Tag:
117
125
  """
@@ -127,16 +135,19 @@ class ThingEndpoint(HydroServerEndpoint):
127
135
  :rtype: Tag
128
136
  """
129
137
 
130
- response = getattr(self._service, '_request')(
131
- 'post', f'{self._api_route}/data/{self._endpoint_route}/{str(uid)}/tags',
132
- headers={'Content-type': 'application/json'},
138
+ response = getattr(self._service, "_request")(
139
+ "post",
140
+ f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}/tags",
141
+ headers={"Content-type": "application/json"},
133
142
  data=Tag(key=key, value=value).json(exclude_unset=True, by_alias=True),
134
143
  )
135
144
  entity = json.loads(response.content)
136
145
 
137
- return Tag(_uid=UUID(str(entity.pop('id'))), **entity)
146
+ return Tag(_uid=UUID(str(entity.pop("id"))), **entity)
138
147
 
139
- def update_tag(self, uid: Union[UUID, str], tag_uid: Union[UUID, str], value: str) -> Tag:
148
+ def update_tag(
149
+ self, uid: Union[UUID, str], tag_uid: Union[UUID, str], value: str
150
+ ) -> Tag:
140
151
  """
141
152
  Update an existing tag for a specific thing.
142
153
 
@@ -150,14 +161,15 @@ class ThingEndpoint(HydroServerEndpoint):
150
161
  :rtype: Tag
151
162
  """
152
163
 
153
- response = getattr(self._service, '_request')(
154
- 'patch', f'{self._api_route}/data/{self._endpoint_route}/{str(uid)}/tags/{str(tag_uid)}',
155
- headers={'Content-type': 'application/json'},
156
- data=json.dumps({'value': str(value)}),
164
+ response = getattr(self._service, "_request")(
165
+ "patch",
166
+ f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}/tags/{str(tag_uid)}",
167
+ headers={"Content-type": "application/json"},
168
+ data=json.dumps({"value": str(value)}),
157
169
  )
158
170
  entity = json.loads(response.content)
159
171
 
160
- return Tag(_uid=UUID(str(entity.pop('id'))), **entity)
172
+ return Tag(_uid=UUID(str(entity.pop("id"))), **entity)
161
173
 
162
174
  def delete_tag(self, uid: Union[UUID, str], tag_uid: Union[UUID, str]) -> None:
163
175
  """
@@ -169,8 +181,9 @@ class ThingEndpoint(HydroServerEndpoint):
169
181
  :type tag_uid: UUID or str
170
182
  """
171
183
 
172
- getattr(self._service, '_request')(
173
- 'delete', f'{self._api_route}/data/{self._endpoint_route}/{str(uid)}/tags/{str(tag_uid)}'
184
+ getattr(self._service, "_request")(
185
+ "delete",
186
+ f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}/tags/{str(tag_uid)}",
174
187
  )
175
188
 
176
189
  def list_photos(self, uid: Union[UUID, str]) -> List[Photo]:
@@ -183,11 +196,14 @@ class ThingEndpoint(HydroServerEndpoint):
183
196
  :rtype: List[Photo]
184
197
  """
185
198
 
186
- response = getattr(self._service, '_request')(
187
- 'get', f'{self._api_route}/data/{self._endpoint_route}/{str(uid)}/photos'
199
+ response = getattr(self._service, "_request")(
200
+ "get", f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}/photos"
188
201
  )
189
202
 
190
- return [Photo(_uid=UUID(str(entity.pop('id'))), **entity) for entity in json.loads(response.content)]
203
+ return [
204
+ Photo(_uid=UUID(str(entity.pop("id"))), **entity)
205
+ for entity in json.loads(response.content)
206
+ ]
191
207
 
192
208
  def upload_photo(self, uid: Union[UUID, str], file: IO) -> List[Photo]:
193
209
  """
@@ -201,12 +217,16 @@ class ThingEndpoint(HydroServerEndpoint):
201
217
  :rtype: List[Photo]
202
218
  """
203
219
 
204
- response = getattr(self._service, '_request')(
205
- 'post', f'{self._api_route}/data/{self._endpoint_route}/{str(uid)}/photos',
206
- files={'files': file}
220
+ response = getattr(self._service, "_request")(
221
+ "post",
222
+ f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}/photos",
223
+ files={"files": file},
207
224
  )
208
225
 
209
- return [Photo(_uid=UUID(str(entity.pop('id'))), **entity) for entity in json.loads(response.content)]
226
+ return [
227
+ Photo(_uid=UUID(str(entity.pop("id"))), **entity)
228
+ for entity in json.loads(response.content)
229
+ ]
210
230
 
211
231
  def delete_photo(self, uid: Union[UUID, str], photo_uid: Union[UUID, str]) -> None:
212
232
  """
@@ -218,8 +238,9 @@ class ThingEndpoint(HydroServerEndpoint):
218
238
  :type photo_uid: UUID or str
219
239
  """
220
240
 
221
- getattr(self._service, '_request')(
222
- 'delete', f'{self._api_route}/data/{self._endpoint_route}/{str(uid)}/photos/{str(photo_uid)}'
241
+ getattr(self._service, "_request")(
242
+ "delete",
243
+ f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}/photos/{str(photo_uid)}",
223
244
  )
224
245
 
225
246
  def get_archive(self, uid: Union[UUID, str]) -> Archive:
@@ -232,9 +253,9 @@ class ThingEndpoint(HydroServerEndpoint):
232
253
  :rtype: Archive
233
254
  """
234
255
 
235
- response = getattr(self._service, '_request')(
236
- 'get', f'{self._api_route}/data/{self._endpoint_route}/{str(uid)}/archive'
256
+ response = getattr(self._service, "_request")(
257
+ "get", f"{self._api_route}/data/{self._endpoint_route}/{str(uid)}/archive"
237
258
  )
238
259
  entity = json.loads(response.content)
239
260
 
240
- return Archive(_uid=UUID(str(entity.pop('id'))), **entity)
261
+ return Archive(_uid=UUID(str(entity.pop("id"))), **entity)
@@ -16,7 +16,7 @@ class UnitEndpoint(HydroServerEndpoint):
16
16
  :ivar _endpoint_route: The specific route of the endpoint, set to `'units'`.
17
17
  """
18
18
 
19
- def __init__(self, service: 'HydroServer'):
19
+ def __init__(self, service: "HydroServer"):
20
20
  """
21
21
  Initialize the UnitEndpoint.
22
22
 
@@ -27,13 +27,13 @@ class UnitEndpoint(HydroServerEndpoint):
27
27
  super().__init__(service)
28
28
  self._model = Unit
29
29
  self._api_route = self._service.api_route
30
- self._endpoint_route = 'units'
30
+ self._endpoint_route = "units"
31
31
 
32
32
  def list(
33
- self,
34
- include_owned: bool = True,
35
- include_unowned: bool = True,
36
- include_templates: bool = True
33
+ self,
34
+ include_owned: bool = True,
35
+ include_unowned: bool = True,
36
+ include_templates: bool = True,
37
37
  ) -> List[Unit]:
38
38
  """
39
39
  Retrieve a collection of units.
@@ -43,22 +43,40 @@ class UnitEndpoint(HydroServerEndpoint):
43
43
  :param include_templates: Whether to include template observed properties.
44
44
  """
45
45
 
46
- if include_owned is True and include_unowned is True and include_templates is True:
47
- owner = 'anyUserOrNoUser'
48
- elif include_owned is True and include_unowned is True and include_templates is False:
49
- owner = 'anyUser'
50
- elif include_owned is True and include_unowned is False and include_templates is True:
51
- owner = 'currentUserOrNoUser'
52
- elif include_owned is True and include_unowned is False and include_templates is False:
53
- owner = 'currentUser'
54
- elif include_owned is False and include_unowned is False and include_templates is True:
55
- owner = 'noUser'
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"
56
76
  else:
57
77
  return []
58
78
 
59
- return super()._get(params={
60
- 'owner': owner
61
- })
79
+ return super()._get(params={"owner": owner})
62
80
 
63
81
  @expand_docstring(include_uid=True)
64
82
  def get(self, uid: Union[UUID, str]) -> Unit:
@@ -1,4 +1,10 @@
1
- from pydantic import BaseModel, PrivateAttr, AliasGenerator, AliasChoices, computed_field
1
+ from pydantic import (
2
+ BaseModel,
3
+ PrivateAttr,
4
+ AliasGenerator,
5
+ AliasChoices,
6
+ computed_field,
7
+ )
2
8
  from pydantic.alias_generators import to_camel
3
9
  from uuid import UUID
4
10
  from typing import Optional
@@ -81,7 +87,8 @@ class HydroServerCoreModel(HydroServerBaseModel):
81
87
  """
82
88
 
83
89
  return {
84
- key: getattr(self, key) for key, value in self._original_data.items()
90
+ key: getattr(self, key)
91
+ for key, value in self._original_data.items()
85
92
  if hasattr(self, key) and getattr(self, key) != value
86
93
  }
87
94
 
@@ -90,8 +97,8 @@ class HydroServerCoreModel(HydroServerBaseModel):
90
97
  Refresh the model with the latest data from the server.
91
98
  """
92
99
 
93
- entity = self._endpoint.get(uid=self.uid).model_dump(exclude=['uid'])
94
- self._original_data = entity.dict(by_alias=False, exclude=['uid'])
100
+ entity = self._endpoint.get(uid=self.uid).model_dump(exclude=["uid"])
101
+ self._original_data = entity.dict(by_alias=False, exclude=["uid"])
95
102
  self.__dict__.update(self._original_data)
96
103
 
97
104
  def save(self) -> None:
@@ -101,7 +108,7 @@ class HydroServerCoreModel(HydroServerBaseModel):
101
108
 
102
109
  if self._patch_data:
103
110
  entity = self._endpoint.update(uid=self.uid, **self._patch_data)
104
- self._original_data = entity.dict(by_alias=False, exclude=['uid'])
111
+ self._original_data = entity.dict(by_alias=False, exclude=["uid"])
105
112
  self.__dict__.update(self._original_data)
106
113
 
107
114
  def delete(self) -> None:
@@ -112,6 +119,6 @@ class HydroServerCoreModel(HydroServerBaseModel):
112
119
  """
113
120
 
114
121
  if not self._uid:
115
- raise AttributeError('This resource cannot be deleted: UID is not set.')
122
+ raise AttributeError("This resource cannot be deleted: UID is not set.")
116
123
  self._endpoint.delete(uid=self._uid)
117
124
  self._uid = None
@@ -9,8 +9,10 @@ if TYPE_CHECKING:
9
9
 
10
10
  class DataLoaderFields(BaseModel):
11
11
  name: str = Field(
12
- ..., strip_whitespace=True, max_length=255,
13
- description='The name of the data loader.'
12
+ ...,
13
+ strip_whitespace=True,
14
+ max_length=255,
15
+ description="The name of the data loader.",
14
16
  )
15
17
 
16
18
 
@@ -37,7 +39,7 @@ class DataLoader(HydroServerCoreModel, DataLoaderFields):
37
39
  self._data_sources = None
38
40
 
39
41
  @property
40
- def data_sources(self) -> List['DataSource']:
42
+ def data_sources(self) -> List["DataSource"]:
41
43
  """
42
44
  The data sources associated with the data loader. If not already cached, fetch the data sources from the server.
43
45
 
@@ -55,7 +57,7 @@ class DataLoader(HydroServerCoreModel, DataLoaderFields):
55
57
  Refresh the data loader with the latest data from the server and update cached data sources.
56
58
  """
57
59
 
58
- entity = self._endpoint.get(uid=self.uid).model_dump(exclude=['uid'])
60
+ entity = self._endpoint.get(uid=self.uid).model_dump(exclude=["uid"])
59
61
  self._original_data = entity
60
62
  self.__dict__.update(entity)
61
63
  if self._data_sources is not None: