hydroserverpy 0.2.5__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.
- hydroserverpy/__init__.py +6 -15
- hydroserverpy/core/endpoints/__init__.py +9 -0
- hydroserverpy/core/endpoints/base.py +146 -0
- hydroserverpy/core/endpoints/data_loaders.py +93 -0
- hydroserverpy/core/endpoints/data_sources.py +93 -0
- hydroserverpy/core/endpoints/datastreams.py +225 -0
- hydroserverpy/core/endpoints/observed_properties.py +111 -0
- hydroserverpy/core/endpoints/processing_levels.py +111 -0
- hydroserverpy/core/endpoints/result_qualifiers.py +111 -0
- hydroserverpy/core/endpoints/sensors.py +111 -0
- hydroserverpy/core/endpoints/things.py +261 -0
- hydroserverpy/core/endpoints/units.py +111 -0
- hydroserverpy/{components → core/schemas}/__init__.py +1 -2
- hydroserverpy/core/schemas/base.py +124 -0
- hydroserverpy/core/schemas/data_loaders.py +73 -0
- hydroserverpy/core/schemas/data_sources.py +223 -0
- hydroserverpy/core/schemas/datastreams.py +330 -0
- hydroserverpy/core/schemas/observed_properties.py +43 -0
- hydroserverpy/core/schemas/processing_levels.py +31 -0
- hydroserverpy/core/schemas/result_qualifiers.py +26 -0
- hydroserverpy/core/schemas/sensors.py +68 -0
- hydroserverpy/core/schemas/things.py +346 -0
- hydroserverpy/core/schemas/units.py +29 -0
- hydroserverpy/core/service.py +200 -0
- hydroserverpy/etl/__init__.py +21 -0
- hydroserverpy/etl/extractors/__init__.py +0 -0
- hydroserverpy/etl/extractors/base.py +13 -0
- hydroserverpy/etl/extractors/ftp_extractor.py +50 -0
- hydroserverpy/etl/extractors/http_extractor.py +84 -0
- hydroserverpy/etl/extractors/local_file_extractor.py +25 -0
- hydroserverpy/etl/hydroserver_etl.py +40 -0
- hydroserverpy/etl/loaders/__init__.py +0 -0
- hydroserverpy/etl/loaders/base.py +13 -0
- hydroserverpy/etl/loaders/hydroserver_loader.py +68 -0
- hydroserverpy/etl/transformers/__init__.py +0 -0
- hydroserverpy/etl/transformers/base.py +52 -0
- hydroserverpy/etl/transformers/csv_transformer.py +88 -0
- hydroserverpy/etl/transformers/json_transformer.py +62 -0
- hydroserverpy/etl/types.py +7 -0
- hydroserverpy/etl_csv/__init__.py +0 -0
- hydroserverpy/{etl.py → etl_csv/hydroserver_etl_csv.py} +118 -95
- hydroserverpy/quality/__init__.py +1 -0
- hydroserverpy/quality/service.py +405 -0
- hydroserverpy-0.4.0.dist-info/METADATA +18 -0
- hydroserverpy-0.4.0.dist-info/RECORD +51 -0
- {hydroserverpy-0.2.5.dist-info → hydroserverpy-0.4.0.dist-info}/WHEEL +1 -1
- hydroserverpy/components/data_loaders.py +0 -67
- hydroserverpy/components/data_sources.py +0 -98
- hydroserverpy/components/datastreams.py +0 -47
- hydroserverpy/components/observed_properties.py +0 -48
- hydroserverpy/components/processing_levels.py +0 -48
- hydroserverpy/components/result_qualifiers.py +0 -48
- hydroserverpy/components/sensors.py +0 -48
- hydroserverpy/components/things.py +0 -48
- hydroserverpy/components/units.py +0 -48
- hydroserverpy/components/users.py +0 -28
- hydroserverpy/main.py +0 -62
- hydroserverpy/models.py +0 -218
- hydroserverpy/schemas/data_loaders.py +0 -27
- hydroserverpy/schemas/data_sources.py +0 -58
- hydroserverpy/schemas/datastreams.py +0 -56
- hydroserverpy/schemas/observed_properties.py +0 -33
- hydroserverpy/schemas/processing_levels.py +0 -33
- hydroserverpy/schemas/result_qualifiers.py +0 -32
- hydroserverpy/schemas/sensors.py +0 -39
- hydroserverpy/schemas/things.py +0 -107
- hydroserverpy/schemas/units.py +0 -32
- hydroserverpy/schemas/users.py +0 -28
- hydroserverpy/service.py +0 -170
- hydroserverpy/utils.py +0 -37
- hydroserverpy-0.2.5.dist-info/METADATA +0 -15
- hydroserverpy-0.2.5.dist-info/RECORD +0 -35
- /hydroserverpy/{schemas → core}/__init__.py +0 -0
- /hydroserverpy/{exceptions.py → etl_csv/exceptions.py} +0 -0
- {hydroserverpy-0.2.5.dist-info → hydroserverpy-0.4.0.dist-info}/LICENSE +0 -0
- {hydroserverpy-0.2.5.dist-info → hydroserverpy-0.4.0.dist-info}/top_level.txt +0 -0
- {hydroserverpy-0.2.5.dist-info → hydroserverpy-0.4.0.dist-info}/zip-safe +0 -0
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
from uuid import UUID
|
|
2
|
-
from typing import List
|
|
3
|
-
from hydroserverpy.schemas.datastreams import DatastreamGetResponse, DatastreamPostBody, DatastreamPatchBody
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class Datastream:
|
|
7
|
-
|
|
8
|
-
def __init__(self, service):
|
|
9
|
-
self._service = service
|
|
10
|
-
|
|
11
|
-
def list(self):
|
|
12
|
-
|
|
13
|
-
return self._service.get(
|
|
14
|
-
'datastreams',
|
|
15
|
-
response_schema=List[DatastreamGetResponse]
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
def get(self, datastream_id: str):
|
|
19
|
-
|
|
20
|
-
return self._service.get(
|
|
21
|
-
f'datastreams/{datastream_id}',
|
|
22
|
-
response_schema=DatastreamGetResponse
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
def create(self, datastream_body: DatastreamPostBody):
|
|
26
|
-
|
|
27
|
-
return self._service.post(
|
|
28
|
-
f'datastreams',
|
|
29
|
-
headers={'Content-type': 'application/json'},
|
|
30
|
-
data=datastream_body.json(by_alias=True),
|
|
31
|
-
response_schema=DatastreamGetResponse
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
def update(self, datastream_id: UUID, datastream_body: DatastreamPatchBody):
|
|
35
|
-
|
|
36
|
-
return self._service.patch(
|
|
37
|
-
f'datastreams/{str(datastream_id)}',
|
|
38
|
-
headers={'Content-type': 'application/json'},
|
|
39
|
-
data=datastream_body.json(exclude_unset=True, by_alias=True),
|
|
40
|
-
response_schema=DatastreamGetResponse
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
def delete(self, datastream_id: UUID):
|
|
44
|
-
|
|
45
|
-
return self._service.delete(
|
|
46
|
-
f'datastreams/{str(datastream_id)}'
|
|
47
|
-
)
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
from uuid import UUID
|
|
3
|
-
from hydroserverpy.schemas.observed_properties import ObservedPropertyGetResponse, ObservedPropertyPostBody, \
|
|
4
|
-
ObservedPropertyPatchBody
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class ObservedProperty:
|
|
8
|
-
|
|
9
|
-
def __init__(self, service):
|
|
10
|
-
self._service = service
|
|
11
|
-
|
|
12
|
-
def list(self):
|
|
13
|
-
|
|
14
|
-
return self._service.get(
|
|
15
|
-
'observed-properties',
|
|
16
|
-
response_schema=List[ObservedPropertyGetResponse]
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
def get(self, observed_property_id: UUID):
|
|
20
|
-
|
|
21
|
-
return self._service.get(
|
|
22
|
-
f'observed-properties/{observed_property_id}',
|
|
23
|
-
response_schema=ObservedPropertyGetResponse
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
def create(self, observed_property_body: ObservedPropertyPostBody):
|
|
27
|
-
|
|
28
|
-
return self._service.post(
|
|
29
|
-
f'observed-properties',
|
|
30
|
-
headers={'Content-type': 'application/json'},
|
|
31
|
-
data=observed_property_body.json(by_alias=True),
|
|
32
|
-
response_schema=ObservedPropertyGetResponse
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
def update(self, observed_property_id: UUID, observed_property_body: ObservedPropertyPatchBody):
|
|
36
|
-
|
|
37
|
-
return self._service.patch(
|
|
38
|
-
f'observed-properties/{str(observed_property_id)}',
|
|
39
|
-
headers={'Content-type': 'application/json'},
|
|
40
|
-
data=observed_property_body.json(exclude_unset=True, by_alias=True),
|
|
41
|
-
response_schema=ObservedPropertyGetResponse
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
def delete(self, observed_property_id: UUID):
|
|
45
|
-
|
|
46
|
-
return self._service.delete(
|
|
47
|
-
f'observed-properties/{str(observed_property_id)}'
|
|
48
|
-
)
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
from uuid import UUID
|
|
3
|
-
from hydroserverpy.schemas.processing_levels import ProcessingLevelGetResponse, ProcessingLevelPostBody, \
|
|
4
|
-
ProcessingLevelPatchBody
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class ProcessingLevel:
|
|
8
|
-
|
|
9
|
-
def __init__(self, service):
|
|
10
|
-
self._service = service
|
|
11
|
-
|
|
12
|
-
def list(self):
|
|
13
|
-
|
|
14
|
-
return self._service.get(
|
|
15
|
-
'processing-levels',
|
|
16
|
-
response_schema=List[ProcessingLevelGetResponse]
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
def get(self, processing_level_id: str):
|
|
20
|
-
|
|
21
|
-
return self._service.get(
|
|
22
|
-
f'processing-levels/{processing_level_id}',
|
|
23
|
-
response_schema=ProcessingLevelGetResponse
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
def create(self, processing_level_body: ProcessingLevelPostBody):
|
|
27
|
-
|
|
28
|
-
return self._service.post(
|
|
29
|
-
f'processing-levels',
|
|
30
|
-
headers={'Content-type': 'application/json'},
|
|
31
|
-
data=processing_level_body.json(by_alias=True),
|
|
32
|
-
response_schema=ProcessingLevelGetResponse
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
def update(self, processing_level_id: UUID, processing_level_body: ProcessingLevelPatchBody):
|
|
36
|
-
|
|
37
|
-
return self._service.patch(
|
|
38
|
-
f'processing-levels/{str(processing_level_id)}',
|
|
39
|
-
headers={'Content-type': 'application/json'},
|
|
40
|
-
data=processing_level_body.json(exclude_unset=True, by_alias=True),
|
|
41
|
-
response_schema=ProcessingLevelGetResponse
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
def delete(self, processing_level_id: UUID):
|
|
45
|
-
|
|
46
|
-
return self._service.delete(
|
|
47
|
-
f'processing-levels/{str(processing_level_id)}'
|
|
48
|
-
)
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
from uuid import UUID
|
|
3
|
-
from hydroserverpy.schemas.result_qualifiers import ResultQualifierGetResponse, ResultQualifierPostBody, \
|
|
4
|
-
ResultQualifierPatchBody
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class ResultQualifier:
|
|
8
|
-
|
|
9
|
-
def __init__(self, service):
|
|
10
|
-
self._service = service
|
|
11
|
-
|
|
12
|
-
def list(self):
|
|
13
|
-
|
|
14
|
-
return self._service.get(
|
|
15
|
-
'result-qualifiers',
|
|
16
|
-
response_schema=List[ResultQualifierGetResponse]
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
def get(self, result_qualifier_id: str):
|
|
20
|
-
|
|
21
|
-
return self._service.get(
|
|
22
|
-
f'result-qualifiers/{result_qualifier_id}',
|
|
23
|
-
response_schema=ResultQualifierGetResponse
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
def create(self, result_qualifier_body: ResultQualifierPostBody):
|
|
27
|
-
|
|
28
|
-
return self._service.post(
|
|
29
|
-
f'result-qualifiers',
|
|
30
|
-
headers={'Content-type': 'application/json'},
|
|
31
|
-
data=result_qualifier_body.json(by_alias=True),
|
|
32
|
-
response_schema=ResultQualifierGetResponse
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
def update(self, result_qualifier_id: UUID, result_qualifier_body: ResultQualifierPatchBody):
|
|
36
|
-
|
|
37
|
-
return self._service.patch(
|
|
38
|
-
f'result-qualifiers/{str(result_qualifier_id)}',
|
|
39
|
-
headers={'Content-type': 'application/json'},
|
|
40
|
-
data=result_qualifier_body.json(exclude_unset=True, by_alias=True),
|
|
41
|
-
response_schema=ResultQualifierGetResponse
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
def delete(self, result_qualifier_id: UUID):
|
|
45
|
-
|
|
46
|
-
return self._service.delete(
|
|
47
|
-
f'result-qualifiers/{str(result_qualifier_id)}'
|
|
48
|
-
)
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
from uuid import UUID
|
|
3
|
-
from hydroserverpy.schemas.sensors import SensorGetResponse, SensorPostBody, \
|
|
4
|
-
SensorPatchBody
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class Sensor:
|
|
8
|
-
|
|
9
|
-
def __init__(self, service):
|
|
10
|
-
self._service = service
|
|
11
|
-
|
|
12
|
-
def list(self):
|
|
13
|
-
|
|
14
|
-
return self._service.get(
|
|
15
|
-
'sensors',
|
|
16
|
-
response_schema=List[SensorGetResponse]
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
def get(self, sensor_id: str):
|
|
20
|
-
|
|
21
|
-
return self._service.get(
|
|
22
|
-
f'sensors/{sensor_id}',
|
|
23
|
-
response_schema=SensorGetResponse
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
def create(self, sensor_body: SensorPostBody):
|
|
27
|
-
|
|
28
|
-
return self._service.post(
|
|
29
|
-
f'sensors',
|
|
30
|
-
headers={'Content-type': 'application/json'},
|
|
31
|
-
data=sensor_body.json(by_alias=True),
|
|
32
|
-
response_schema=SensorGetResponse
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
def update(self, sensor_id: UUID, sensor_body: SensorPatchBody):
|
|
36
|
-
|
|
37
|
-
return self._service.patch(
|
|
38
|
-
f'sensors/{str(sensor_id)}',
|
|
39
|
-
headers={'Content-type': 'application/json'},
|
|
40
|
-
data=sensor_body.json(exclude_unset=True, by_alias=True),
|
|
41
|
-
response_schema=SensorGetResponse
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
def delete(self, sensor_id: UUID):
|
|
45
|
-
|
|
46
|
-
return self._service.delete(
|
|
47
|
-
f'sensors/{str(sensor_id)}'
|
|
48
|
-
)
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
from uuid import UUID
|
|
3
|
-
from hydroserverpy.schemas.things import ThingGetResponse, ThingPostBody, \
|
|
4
|
-
ThingPatchBody
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class Thing:
|
|
8
|
-
|
|
9
|
-
def __init__(self, service):
|
|
10
|
-
self._service = service
|
|
11
|
-
|
|
12
|
-
def list(self):
|
|
13
|
-
|
|
14
|
-
return self._service.get(
|
|
15
|
-
'things',
|
|
16
|
-
response_schema=List[ThingGetResponse]
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
def get(self, thing_id: str):
|
|
20
|
-
|
|
21
|
-
return self._service.get(
|
|
22
|
-
f'things/{thing_id}',
|
|
23
|
-
response_schema=ThingGetResponse
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
def create(self, thing_body: ThingPostBody):
|
|
27
|
-
|
|
28
|
-
return self._service.post(
|
|
29
|
-
f'things',
|
|
30
|
-
headers={'Content-type': 'application/json'},
|
|
31
|
-
data=thing_body.json(by_alias=True),
|
|
32
|
-
response_schema=ThingGetResponse
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
def update(self, thing_id: UUID, thing_body: ThingPatchBody):
|
|
36
|
-
|
|
37
|
-
return self._service.patch(
|
|
38
|
-
f'things/{str(thing_id)}',
|
|
39
|
-
headers={'Content-type': 'application/json'},
|
|
40
|
-
data=thing_body.json(exclude_unset=True, by_alias=True),
|
|
41
|
-
response_schema=ThingGetResponse
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
def delete(self, thing_id: UUID):
|
|
45
|
-
|
|
46
|
-
return self._service.delete(
|
|
47
|
-
f'things/{str(thing_id)}'
|
|
48
|
-
)
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
from uuid import UUID
|
|
3
|
-
from hydroserverpy.schemas.units import UnitGetResponse, UnitPostBody, \
|
|
4
|
-
UnitPatchBody
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class Unit:
|
|
8
|
-
|
|
9
|
-
def __init__(self, service):
|
|
10
|
-
self._service = service
|
|
11
|
-
|
|
12
|
-
def list(self):
|
|
13
|
-
|
|
14
|
-
return self._service.get(
|
|
15
|
-
'units',
|
|
16
|
-
response_schema=List[UnitGetResponse]
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
def get(self, unit_id: str):
|
|
20
|
-
|
|
21
|
-
return self._service.get(
|
|
22
|
-
f'units/{unit_id}',
|
|
23
|
-
response_schema=UnitGetResponse
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
def create(self, unit_body: UnitPostBody):
|
|
27
|
-
|
|
28
|
-
return self._service.post(
|
|
29
|
-
f'units',
|
|
30
|
-
headers={'Content-type': 'application/json'},
|
|
31
|
-
data=unit_body.json(by_alias=True),
|
|
32
|
-
response_schema=UnitGetResponse
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
def update(self, unit_id: UUID, unit_body: UnitPatchBody):
|
|
36
|
-
|
|
37
|
-
return self._service.patch(
|
|
38
|
-
f'units/{str(unit_id)}',
|
|
39
|
-
headers={'Content-type': 'application/json'},
|
|
40
|
-
data=unit_body.json(exclude_unset=True, by_alias=True),
|
|
41
|
-
response_schema=UnitGetResponse
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
def delete(self, unit_id: UUID):
|
|
45
|
-
|
|
46
|
-
return self._service.delete(
|
|
47
|
-
f'units/{str(unit_id)}'
|
|
48
|
-
)
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
from pydantic import BaseModel, Field
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class Organization(BaseModel):
|
|
6
|
-
code: str
|
|
7
|
-
name: str
|
|
8
|
-
description: Optional[str]
|
|
9
|
-
type: str
|
|
10
|
-
link: Optional[str]
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class UserResponse(BaseModel):
|
|
14
|
-
email: str
|
|
15
|
-
first_name: str = Field(..., alias='firstName')
|
|
16
|
-
last_name: str = Field(..., alias='lastName')
|
|
17
|
-
middle_name: Optional[str] = Field(None, alias='middleName')
|
|
18
|
-
phone: Optional[str]
|
|
19
|
-
address: Optional[str]
|
|
20
|
-
type: str
|
|
21
|
-
link: Optional[str]
|
|
22
|
-
organization: Optional[Organization]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class User:
|
|
26
|
-
|
|
27
|
-
def __init__(self, service):
|
|
28
|
-
self._service = service
|
hydroserverpy/main.py
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
from typing import Optional, Union, Tuple
|
|
2
|
-
from pydantic import AnyHttpUrl
|
|
3
|
-
from hydroserverpy.service import BaseService
|
|
4
|
-
from hydroserverpy.components import DataLoader, DataSource, Datastream, ObservedProperty, ProcessingLevel, \
|
|
5
|
-
ResultQualifier, Sensor, Thing, Unit, User
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class HydroServer(BaseService):
|
|
9
|
-
|
|
10
|
-
def __init__(
|
|
11
|
-
self,
|
|
12
|
-
host: Union[AnyHttpUrl, str],
|
|
13
|
-
auth: Optional[Tuple[str, str]] = None,
|
|
14
|
-
sta_path: str = 'api/sensorthings/v1.1',
|
|
15
|
-
api_path: str = 'api/data'
|
|
16
|
-
):
|
|
17
|
-
super().__init__(
|
|
18
|
-
host=host,
|
|
19
|
-
auth=auth,
|
|
20
|
-
sta_path=sta_path,
|
|
21
|
-
api_path=api_path
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
@property
|
|
25
|
-
def data_loaders(self):
|
|
26
|
-
return DataLoader(self)
|
|
27
|
-
|
|
28
|
-
@property
|
|
29
|
-
def data_sources(self):
|
|
30
|
-
return DataSource(self)
|
|
31
|
-
|
|
32
|
-
@property
|
|
33
|
-
def datastreams(self):
|
|
34
|
-
return Datastream(self)
|
|
35
|
-
|
|
36
|
-
@property
|
|
37
|
-
def observed_properties(self):
|
|
38
|
-
return ObservedProperty(self)
|
|
39
|
-
|
|
40
|
-
@property
|
|
41
|
-
def processing_levels(self):
|
|
42
|
-
return ProcessingLevel(self)
|
|
43
|
-
|
|
44
|
-
@property
|
|
45
|
-
def result_qualifiers(self):
|
|
46
|
-
return ResultQualifier(self)
|
|
47
|
-
|
|
48
|
-
@property
|
|
49
|
-
def sensors(self):
|
|
50
|
-
return Sensor(self)
|
|
51
|
-
|
|
52
|
-
@property
|
|
53
|
-
def things(self):
|
|
54
|
-
return Thing(self)
|
|
55
|
-
|
|
56
|
-
@property
|
|
57
|
-
def units(self):
|
|
58
|
-
return Unit(self)
|
|
59
|
-
|
|
60
|
-
@property
|
|
61
|
-
def users(self):
|
|
62
|
-
return User(self)
|
hydroserverpy/models.py
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import yaml
|
|
2
|
-
import re
|
|
3
|
-
import simplejson as json
|
|
4
|
-
from uuid import UUID
|
|
5
|
-
from datetime import datetime
|
|
6
|
-
from crontab import CronTab
|
|
7
|
-
from pydantic import BaseModel, validator, root_validator, conint, AnyHttpUrl, Field
|
|
8
|
-
from typing import List, Optional, Literal, Union
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class HydroLoaderDatastream(BaseModel):
|
|
12
|
-
id: UUID
|
|
13
|
-
value_count: Optional[int] = Field(None, alias='valueCount')
|
|
14
|
-
result_time: Optional[datetime] = Field(None, alias='resultTime')
|
|
15
|
-
phenomenon_time: Optional[datetime] = Field(None, alias='phenomenonTime')
|
|
16
|
-
file_row_start_index: Optional[int]
|
|
17
|
-
file_result_end_time: Optional[datetime]
|
|
18
|
-
chunk_result_start_time: Optional[datetime]
|
|
19
|
-
chunk_result_end_time: Optional[datetime]
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class HydroLoaderObservationsResponse(BaseModel):
|
|
23
|
-
datastream_id: str
|
|
24
|
-
request_url: str
|
|
25
|
-
status_code: int
|
|
26
|
-
reason: str
|
|
27
|
-
chunk_start_time: str
|
|
28
|
-
chunk_end_time: str
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class HydroLoaderConfSchedule(BaseModel):
|
|
32
|
-
crontab: Optional[str]
|
|
33
|
-
interval_units: Optional[Literal['minutes', 'hours', 'days', 'weeks', 'months']]
|
|
34
|
-
interval: Optional[conint(gt=0)]
|
|
35
|
-
start_time: Optional[datetime]
|
|
36
|
-
end_time: Optional[datetime]
|
|
37
|
-
paused: Optional[bool]
|
|
38
|
-
|
|
39
|
-
@root_validator(pre=True)
|
|
40
|
-
def check_crontab_or_interval(cls, values):
|
|
41
|
-
"""
|
|
42
|
-
The check_crontab_or_interval function is a validator that ensures that the HydroLoaderConfSchedule model
|
|
43
|
-
does not include both a crontab and an interval. It also ensures that if an interval is
|
|
44
|
-
included, it includes both an interval and its units.
|
|
45
|
-
|
|
46
|
-
:param cls: Pass the class of the model to be created
|
|
47
|
-
:param values: Pass the values of the fields in a form to
|
|
48
|
-
:return: The values dictionary
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
if values.get('crontab') and (values.get('interval_units') or values.get('interval')):
|
|
52
|
-
raise ValueError('Schedule can include either a crontab or an interval, not both.')
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
values.get('interval_units') and not values.get('interval')
|
|
56
|
-
) or (
|
|
57
|
-
not values.get('interval_units') and values.get('interval')
|
|
58
|
-
):
|
|
59
|
-
raise ValueError('Interval must include both an interval and interval_units.')
|
|
60
|
-
|
|
61
|
-
return values
|
|
62
|
-
|
|
63
|
-
@validator('crontab')
|
|
64
|
-
def check_valid_crontab(cls, v):
|
|
65
|
-
"""
|
|
66
|
-
The check_valid_crontab function is a validator that uses the CronTab library to check if the inputted
|
|
67
|
-
crontab string is valid. If it's not, an exception will be raised.
|
|
68
|
-
|
|
69
|
-
:param cls: Pass the class to the function
|
|
70
|
-
:param v: Pass the value of the field to be validated
|
|
71
|
-
:return: The crontab string
|
|
72
|
-
"""
|
|
73
|
-
|
|
74
|
-
if v is not None:
|
|
75
|
-
CronTab(v)
|
|
76
|
-
|
|
77
|
-
return v
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
class HydroLoaderConfFileAccess(BaseModel):
|
|
81
|
-
path: Optional[str]
|
|
82
|
-
url: Optional[AnyHttpUrl]
|
|
83
|
-
header_row: Optional[conint(gt=0)] = None
|
|
84
|
-
data_start_row: Optional[conint(gt=0)] = 1
|
|
85
|
-
delimiter: Optional[str] = ','
|
|
86
|
-
quote_char: Optional[str] = '"'
|
|
87
|
-
|
|
88
|
-
@root_validator(pre=True)
|
|
89
|
-
def check_path_or_url(cls, values):
|
|
90
|
-
"""
|
|
91
|
-
The check_path_or_url function is a validator that takes in the values of the HydroLoaderConfFileAccess model
|
|
92
|
-
and checks to see if there is either a path or url. If there isn't, it raises an error.
|
|
93
|
-
|
|
94
|
-
:param cls: Pass the class of the object being created
|
|
95
|
-
:param values: Pass in the values of the path and url parameters
|
|
96
|
-
:return: The values dictionary
|
|
97
|
-
"""
|
|
98
|
-
|
|
99
|
-
if bool(values.get('path')) == bool(values.get('url')):
|
|
100
|
-
raise ValueError('File access must include either a path or a URL.')
|
|
101
|
-
|
|
102
|
-
return values
|
|
103
|
-
|
|
104
|
-
@root_validator(pre=True)
|
|
105
|
-
def check_header_and_data_rows(cls, values):
|
|
106
|
-
"""
|
|
107
|
-
The check_header_and_data_rows function is a class method that takes in the values of the header_row and
|
|
108
|
-
data_start_row and ensures the header row is not greater than the data start row. If it is, it raises an error.
|
|
109
|
-
|
|
110
|
-
:param cls: Refer to the class that is being created
|
|
111
|
-
:param values: Get the values of the header_row and data_start_row
|
|
112
|
-
:return: The values dictionary
|
|
113
|
-
"""
|
|
114
|
-
|
|
115
|
-
if values.get('header_row') is not None and values.get('header_row') >= values.get('data_start_row'):
|
|
116
|
-
raise ValueError('Header row cannot occur after data start row.')
|
|
117
|
-
|
|
118
|
-
return values
|
|
119
|
-
|
|
120
|
-
@validator('delimiter')
|
|
121
|
-
def convert_delimiters(cls, v):
|
|
122
|
-
"""
|
|
123
|
-
The convert_delimiters function is a validator that takes in a string and replaces all instances of '\\t' with
|
|
124
|
-
'\t'. This function is used to convert the delimiters from the input file into tab-delimited format.
|
|
125
|
-
|
|
126
|
-
:param cls: Pass the class object to the function
|
|
127
|
-
:param v: Pass the value of the escaped delimiter into the function
|
|
128
|
-
:return: An unescaped delimiter string
|
|
129
|
-
"""
|
|
130
|
-
|
|
131
|
-
return v.replace('\\t', '\t')
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
class HydroLoaderConfFileTimestamp(BaseModel):
|
|
135
|
-
column: Union[conint(gt=0), str]
|
|
136
|
-
format: Optional[str] = '%Y-%m-%dT%H:%M:%S%Z'
|
|
137
|
-
offset: Optional[str] = '+0000'
|
|
138
|
-
|
|
139
|
-
@validator('format')
|
|
140
|
-
def check_valid_strftime(cls, v):
|
|
141
|
-
"""
|
|
142
|
-
The check_valid_strftime function is a validator that takes in a datetime strf string and checks to see if it
|
|
143
|
-
is valid. It uses the strftime function from the datetime module, which returns an error if the string passed
|
|
144
|
-
to it is not valid.
|
|
145
|
-
|
|
146
|
-
:param cls: Pass the class to which the validator is attached
|
|
147
|
-
:param v: Pass the value of the argument to be checked
|
|
148
|
-
:return: The value of the string
|
|
149
|
-
"""
|
|
150
|
-
|
|
151
|
-
datetime.now().strftime(v)
|
|
152
|
-
|
|
153
|
-
return v
|
|
154
|
-
|
|
155
|
-
@validator('offset', always=True)
|
|
156
|
-
def parse_tzinfo(cls, v):
|
|
157
|
-
"""
|
|
158
|
-
The parse_tzinfo function is a validator for the offset field. It takes in a string and returns an instance
|
|
159
|
-
of datetime.tzinfo, which is used by Python's datetime module to represent timezone information. The function
|
|
160
|
-
first checks that the input string is a valid UTC offset formatted like "+0000". If it is not valid, then it
|
|
161
|
-
raises an exception.
|
|
162
|
-
|
|
163
|
-
:param cls: Pass in the class of the object being created
|
|
164
|
-
:param v: Pass the timezone offset
|
|
165
|
-
:return: A tzinfo object
|
|
166
|
-
"""
|
|
167
|
-
|
|
168
|
-
tzinfo_pattern = r'^[+-](0[0-9]|1[0-4])[0-5][0-9]$'
|
|
169
|
-
if v is not None and re.match(tzinfo_pattern, v) is None:
|
|
170
|
-
raise ValueError('The offset must be a valid UTC timezone offset formatted such as "+0000".')
|
|
171
|
-
|
|
172
|
-
return v # datetime.strptime(v, '%z').tzinfo if v is not None else None
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
class HydroLoaderConfFileDatastream(BaseModel):
|
|
176
|
-
column: Union[conint(gt=0), str]
|
|
177
|
-
id: UUID
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
class HydroLoaderConf(BaseModel):
|
|
181
|
-
schedule: Optional[HydroLoaderConfSchedule]
|
|
182
|
-
file_access: HydroLoaderConfFileAccess
|
|
183
|
-
file_timestamp: HydroLoaderConfFileTimestamp
|
|
184
|
-
datastreams: List[HydroLoaderConfFileDatastream]
|
|
185
|
-
|
|
186
|
-
@root_validator()
|
|
187
|
-
def check_header_and_fields(cls, values):
|
|
188
|
-
""""""
|
|
189
|
-
|
|
190
|
-
if not values.get('file_access') or not values['file_access'].header_row:
|
|
191
|
-
if values.get('file_timestamp') and not isinstance(values['file_timestamp'].column, int):
|
|
192
|
-
raise ValueError('If no header row is defined, all column identifiers must be integers.')
|
|
193
|
-
if values.get('datastreams'):
|
|
194
|
-
for datastream in values['datastreams']:
|
|
195
|
-
if not isinstance(datastream.column, int):
|
|
196
|
-
raise ValueError('If no header row is defined, all column identifiers must be integers.')
|
|
197
|
-
|
|
198
|
-
return values
|
|
199
|
-
|
|
200
|
-
def to_yaml(
|
|
201
|
-
self,
|
|
202
|
-
file_path: str
|
|
203
|
-
):
|
|
204
|
-
"""
|
|
205
|
-
The to_yaml function takes a file path and writes the configuration to that file in YAML format.
|
|
206
|
-
|
|
207
|
-
:param self: Refer to the current instance of the class
|
|
208
|
-
:param file_path: str: Specify the file path to save the configuration
|
|
209
|
-
:return: A yaml file
|
|
210
|
-
"""
|
|
211
|
-
|
|
212
|
-
with open(file_path, 'w') as conf_file:
|
|
213
|
-
yaml.dump(
|
|
214
|
-
json.loads(self.json()),
|
|
215
|
-
conf_file,
|
|
216
|
-
sort_keys=False,
|
|
217
|
-
default_flow_style=False
|
|
218
|
-
)
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
from pydantic import BaseModel
|
|
2
|
-
from uuid import UUID
|
|
3
|
-
from hydroserverpy.utils import allow_partial
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class DataLoaderID(BaseModel):
|
|
7
|
-
id: UUID
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class DataLoaderFields(BaseModel):
|
|
11
|
-
name: str
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class DataLoaderGetResponse(DataLoaderFields, DataLoaderID):
|
|
15
|
-
pass
|
|
16
|
-
|
|
17
|
-
class Config:
|
|
18
|
-
allow_population_by_field_name = True
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class DataLoaderPostBody(DataLoaderFields):
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@allow_partial
|
|
26
|
-
class DataLoaderPatchBody(DataLoaderFields):
|
|
27
|
-
pass
|