staplus-client 0.3.3__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.
Files changed (53) hide show
  1. staplus_client/__init__.py +47 -0
  2. staplus_client/__version__.py +8 -0
  3. staplus_client/dao/__init__.py +18 -0
  4. staplus_client/dao/actuator.py +30 -0
  5. staplus_client/dao/base.py +70 -0
  6. staplus_client/dao/campaign.py +25 -0
  7. staplus_client/dao/datastream.py +35 -0
  8. staplus_client/dao/features_of_interest.py +36 -0
  9. staplus_client/dao/historical_location.py +35 -0
  10. staplus_client/dao/license.py +25 -0
  11. staplus_client/dao/location.py +35 -0
  12. staplus_client/dao/multi_datastream.py +36 -0
  13. staplus_client/dao/observation.py +55 -0
  14. staplus_client/dao/observation_group.py +25 -0
  15. staplus_client/dao/observedproperty.py +35 -0
  16. staplus_client/dao/party.py +25 -0
  17. staplus_client/dao/relation.py +57 -0
  18. staplus_client/dao/sensor.py +35 -0
  19. staplus_client/dao/task.py +30 -0
  20. staplus_client/dao/tasking_capability.py +30 -0
  21. staplus_client/dao/thing.py +36 -0
  22. staplus_client/model/__init__.py +29 -0
  23. staplus_client/model/campaign.py +417 -0
  24. staplus_client/model/datastream.py +166 -0
  25. staplus_client/model/entity.py +29 -0
  26. staplus_client/model/ext/__init__.py +0 -0
  27. staplus_client/model/ext/entity_list.py +75 -0
  28. staplus_client/model/ext/entity_type.py +142 -0
  29. staplus_client/model/ext/unitofmeasurement.py +5 -0
  30. staplus_client/model/feature_of_interest.py +17 -0
  31. staplus_client/model/historical_location.py +21 -0
  32. staplus_client/model/license.py +301 -0
  33. staplus_client/model/location.py +22 -0
  34. staplus_client/model/multi_datastream.py +160 -0
  35. staplus_client/model/observation.py +218 -0
  36. staplus_client/model/observation_group.py +399 -0
  37. staplus_client/model/observedproperty.py +20 -0
  38. staplus_client/model/party.py +315 -0
  39. staplus_client/model/relation.py +246 -0
  40. staplus_client/model/sensor.py +16 -0
  41. staplus_client/model/thing.py +110 -0
  42. staplus_client/query/__init__.py +0 -0
  43. staplus_client/query/query.py +109 -0
  44. staplus_client/service/BearerAuth.py +23 -0
  45. staplus_client/service/__init__.py +17 -0
  46. staplus_client/service/auth_handler.py +23 -0
  47. staplus_client/service/staplusservice.py +162 -0
  48. staplus_client/utils.py +64 -0
  49. staplus_client-0.3.3.dist-info/LICENSE +165 -0
  50. staplus_client-0.3.3.dist-info/METADATA +470 -0
  51. staplus_client-0.3.3.dist-info/RECORD +53 -0
  52. staplus_client-0.3.3.dist-info/WHEEL +5 -0
  53. staplus_client-0.3.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,166 @@
1
+ # Copyright (C) 2023-2024 Secure Dimensions GmbH, Munich, Germany.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ from frost_sta_client.model import datastream
17
+ from staplus_client import utils
18
+ from staplus_client.model.ext import entity_list, entity_type
19
+ from staplus_client.dao.datastream import DatastreamDao
20
+ from staplus_client.model import license, party, campaign
21
+
22
+
23
+ class Datastream(datastream.Datastream):
24
+
25
+ def __init__(self,
26
+ name='',
27
+ description='',
28
+ observation_type='',
29
+ unit_of_measurement=None,
30
+ observed_area=None,
31
+ properties=None,
32
+ phenomenon_time=None,
33
+ result_time=None,
34
+ thing=None,
35
+ sensor=None,
36
+ observed_property=None,
37
+ observations=None,
38
+ campaigns=None,
39
+ party=None,
40
+ license=None,
41
+ **kwargs):
42
+ super().__init__(name, description, observation_type, unit_of_measurement,
43
+ observed_area, properties, phenomenon_time, result_time, thing,
44
+ sensor, observations, observed_property, **kwargs)
45
+ self.campaigns = campaigns
46
+ self.party = party
47
+ self.license = license
48
+
49
+ def __new__(cls, *args, **kwargs):
50
+ new_datastream = super().__new__(cls, args, kwargs)
51
+ attributes = dict(_campaigns=None, _party=None, _license=None, _self_link='', _service=None)
52
+ for key, value in attributes.items():
53
+ new_datastream.__dict__[key] = value
54
+ return new_datastream
55
+
56
+ @property
57
+ def party(self):
58
+ return self._party
59
+
60
+ @party.setter
61
+ def party(self, value):
62
+ if value is None or isinstance(value, party.Party):
63
+ self._party = value
64
+ return
65
+ raise ValueError('party should be of type Party!')
66
+
67
+ def get_party(self):
68
+ result = self.service.party()
69
+ result.parent = self
70
+ return result
71
+
72
+ @property
73
+ def license(self):
74
+ return self._license
75
+
76
+ @license.setter
77
+ def license(self, value):
78
+ if value is None or isinstance(value, license.License):
79
+ self._license = value
80
+ return
81
+ raise ValueError('license should be of type License!')
82
+
83
+ def get_license(self):
84
+ result = self.service.license()
85
+ result.parent = self
86
+ return result
87
+
88
+ def get_thing(self):
89
+ result = self.service.thing()
90
+ result.parent = self
91
+ return result
92
+
93
+ def get_sensor(self):
94
+ result = self.service.sensor()
95
+ result.parent = self
96
+ return result
97
+
98
+ def get_observed_property(self):
99
+ result = self.service.observed_property()
100
+ result.parent = self
101
+ return result
102
+
103
+ @property
104
+ def campaigns(self):
105
+ return self._campaigns
106
+
107
+ @campaigns.setter
108
+ def campaigns(self, values):
109
+ if values is None:
110
+ self._campaigns = None
111
+ return
112
+ if isinstance(values, list) and all(isinstance(ps, campaign.Campaign) for ps in values):
113
+ entity_class = entity_type.EntityTypes['Campaign']['class']
114
+ self._campaigns = entity_list.EntityList(entity_class=entity_class, entities=values)
115
+ return
116
+ if not isinstance(values, entity_list.EntityList) or \
117
+ any((not isinstance(ps, campaign.Campaign)) for ps in values.entities):
118
+ raise ValueError('campaigns should be a list of Campaign')
119
+ self._campaigns = values
120
+
121
+ def get_campaigns(self):
122
+ result = self.service.campaigns()
123
+ result.parent = self
124
+ return result
125
+
126
+ def ensure_service_on_children(self, service):
127
+ super().ensure_service_on_children(service)
128
+ if self.party is not None:
129
+ self.party.set_service(service)
130
+ if self.license is not None:
131
+ self.license.set_service(service)
132
+ if self.campaigns is not None:
133
+ self.campaigns.set_service(service)
134
+
135
+ def __getstate__(self):
136
+ data = super().__getstate__()
137
+ if self.party is not None:
138
+ data['Party'] = self.party
139
+ if self.license is not None:
140
+ data['License'] = self.license
141
+ if self._campaigns is not None and len(self.campaigns.entities) > 0:
142
+ data['Campaigns'] = self.campaigns.__getstate__()
143
+
144
+ return data
145
+
146
+ def __setstate__(self, state):
147
+ super().__setstate__(state)
148
+ if state.get("Party", None) is not None:
149
+ self.party = party.Party()
150
+ self.party.__setstate__(state["Party"])
151
+ if state.get("License", None) is not None:
152
+ self.license = license.License()
153
+ self.license.__setstate__(state["License"])
154
+ if state.get("Campaigns", None) is not None and isinstance(state["Campaigns"], list):
155
+ entity_class = entity_type.EntityTypes['Campaign']['class']
156
+ self.campaigns = utils.transform_json_to_entity_list(state['Campaigns'], entity_class)
157
+ self.campaigns.next_link = state.get("Campaigns@iot.nextLink", None)
158
+ self.campaigns.count = state.get("Campaigns@iot.count", None)
159
+
160
+ def get_dao(self, service):
161
+ return DatastreamDao(service)
162
+
163
+ def clone(self):
164
+ entity = self.__class__()
165
+ entity.id = self.id
166
+ return entity
@@ -0,0 +1,29 @@
1
+ # Copyright (C) 2023-2024 Secure Dimensions GmbH, Munich, Germany.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ from frost_sta_client.model import entity
17
+ from staplus_client.service.staplusservice import STAplusService
18
+
19
+ class Entity(entity.Entity):
20
+ def service(self, value):
21
+ if value is None or isinstance(value, STAplusService):
22
+ self._service = value
23
+ return
24
+ raise ValueError('service should be of type STAplusService')
25
+
26
+ def set_service(self, service):
27
+ if self.service != service:
28
+ self.service = service
29
+ self.ensure_service_on_children(service)
File without changes
@@ -0,0 +1,75 @@
1
+ # Copyright (C) 2023-2024 Secure Dimensions GmbH, Munich, Germany.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ import logging
17
+ import requests
18
+
19
+ from staplus_client.service.staplusservice import STAplusService
20
+ from staplus_client.model.entity import Entity
21
+ from frost_sta_client.model.ext import entity_list
22
+
23
+ class EntityList(entity_list.EntityList):
24
+ def __init__(self, entity_class, entities=None):
25
+ super().__init__(entity_class, entities)
26
+
27
+ def __next__(self):
28
+ idx, next_entity = next(self.iterable_entities, (len(self.entities), None))
29
+ if self.step_size is not None and idx is not None and idx % self.step_size == 0:
30
+ self.callback(idx)
31
+ if next_entity is not None:
32
+ return next_entity
33
+ if self.next_link is not None:
34
+ try:
35
+ response = self.service.execute('get', self.next_link)
36
+ except requests.exceptions.HTTPError as e:
37
+ error_json = e.response.json()
38
+ error_message = error_json['message']
39
+ logging.error("Query failed with status-code {}, {}".format(e.response.status_code, error_message))
40
+ raise e
41
+ logging.debug('Received response: {} from {}'.format(response.status_code, self.next_link))
42
+ try:
43
+ json_response = response.json()
44
+ except ValueError:
45
+ raise ValueError('Cannot find json in http response')
46
+
47
+ result_list = staplus_client.utils.transform_json_to_entity_list(json_response, self.entity_class)
48
+ self.entities += result_list.entities
49
+ self.set_service(self.service)
50
+ self.next_link = json_response.get("@iot.nextLink", None)
51
+ self.iterable_entities = iter(enumerate(self.entities[-len(result_list.entities):], start=idx))
52
+ return next(self.iterable_entities)[1]
53
+ raise StopIteration
54
+
55
+ @property
56
+ def service(self):
57
+ return self._service
58
+
59
+ @service.setter
60
+ def service(self, value):
61
+ if value is None or isinstance(value, STAplusService):
62
+ self._service = value
63
+ return
64
+ raise ValueError('service should be of type STAplusService')
65
+
66
+ def set_service(self, service):
67
+ self.service = service
68
+ for entity in self.entities:
69
+ entity.set_service(service)
70
+
71
+ def entities(self, values):
72
+ if isinstance(values, list) and all(isinstance(v, Entity) for v in values):
73
+ self._entities = values
74
+ return
75
+ raise ValueError('entities should be a list of STAplus entities')
@@ -0,0 +1,142 @@
1
+ # Copyright (C) 2023-2024 Secure Dimensions GmbH, Munich, Germany.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ EntityTypes = {
17
+ 'Datastream': {
18
+ 'singular': 'Datastream',
19
+ 'plural': 'Datastreams',
20
+ 'class': 'staplus_client.model.datastream.Datastream',
21
+ 'relations_list': ['Sensor', 'Thing', 'ObservedProperty', 'Observations', 'Party', 'License', 'Campaign']
22
+ },
23
+ 'MultiDatastream': {
24
+ 'singular': 'MultiDatastream',
25
+ 'plural': 'MultiDatastreams',
26
+ 'class': 'staplus_client.model.multi_datastream.MultiDatastream',
27
+ 'relations_list': ['Sensor', 'Thing', 'ObservedProperties', 'Observations', 'Party', 'License', 'Campaign']
28
+ },
29
+ 'FeatureOfInterest': {
30
+ 'singular': 'FeatureOfInterest',
31
+ 'plural': 'FeaturesOfInterest',
32
+ 'class': 'staplus_client.model.feature_of_interest.FeatureOfInterest',
33
+ 'relations_list': ['Observations']
34
+ },
35
+ 'HistoricalLocation': {
36
+ 'singular': 'HistoricalLocation',
37
+ 'plural': 'HistoricalLocations',
38
+ 'class': 'staplus_client.model.historical_location.HistoricalLocation',
39
+ 'relations_list': ['Thing', 'Locations']
40
+ },
41
+ 'Actuator': {
42
+ 'singular': 'Actuator',
43
+ 'plural': 'Actuators',
44
+ 'class': 'frost_sta_client.model.actuator.Actuator',
45
+ 'relations_list': ['TaskingCapabilities']
46
+ },
47
+ 'Location': {
48
+ 'singular': 'Location',
49
+ 'plural': 'Locations',
50
+ 'class': 'staplus_client.model.location.Location',
51
+ 'relations_list': ['Things', 'HistoricalLocations']
52
+ },
53
+ 'Observation': {
54
+ 'singular': 'Observation',
55
+ 'plural': 'Observations',
56
+ 'class': 'staplus_client.model.observation.Observation',
57
+ 'relations_list': ['FeatureOfInterest', 'Datastream', 'MultiDatastream', 'Subjects', 'Objects']
58
+ },
59
+ 'Thing': {
60
+ 'singular': 'Thing',
61
+ 'plural': 'Things',
62
+ 'class': 'staplus_client.model.thing.Thing',
63
+ 'relations_list': ['Datastreams', 'MultiDatastreams', 'Locations', 'HistoricalLocations', 'TaskingCapabilities',
64
+ 'Party']
65
+ },
66
+ 'ObservedProperty': {
67
+ 'singular': 'ObservedProperty',
68
+ 'plural': 'ObservedProperties',
69
+ 'class': 'staplus_client.model.observedproperty.ObservedProperty',
70
+ 'relations_list': ['Datastreams', 'MultiDatastreams']
71
+ },
72
+ 'Sensor': {
73
+ 'singular': 'Sensor',
74
+ 'plural': 'Sensors',
75
+ 'class': 'staplus_client.model.sensor.Sensor',
76
+ 'relations_list': ['Datastreams', 'MultiDatastreams']
77
+ },
78
+ 'Task': {
79
+ 'singular': 'Task',
80
+ 'plural': 'Tasks',
81
+ 'class': 'frost_sta_client.model.task.Task',
82
+ 'relations_list': ['TaskingCapability']
83
+ },
84
+ 'TaskingCapability': {
85
+ 'singular': 'TaskingCapability',
86
+ 'plural': 'TaskingCapabilities',
87
+ 'class': 'frost_sta_client.model.tasking_capability.TaskingCapability',
88
+ 'relations_list': ['Tasks', 'Actuator', 'Thing']
89
+ },
90
+ 'UnitOfMeasurement': {
91
+ 'singular': 'UnitOfMeasurement',
92
+ 'plural': 'UnitOfMeasurements',
93
+ 'class': 'frost_sta_client.model.ext.unitofmeasurement.UnitOfMeasurement'
94
+ },
95
+ 'EntityList': {
96
+ 'singular': 'EntityList',
97
+ 'plural': 'EntityLists',
98
+ 'class': 'staplus_client.model.ext.entity_list.EntityList'
99
+ },
100
+ #
101
+ # STAplus
102
+ #
103
+ 'Party': {
104
+ 'singular': 'Party',
105
+ 'plural': 'Parties',
106
+ 'class': 'staplus_client.model.party.Party',
107
+ 'relations_list': ['Datastreams', 'MultiDatastreams', 'Things', 'Campaigns', 'ObservationGroups']
108
+ },
109
+ 'License': {
110
+ 'singular': 'License',
111
+ 'plural': 'Licenses',
112
+ 'class': 'staplus_client.model.license.License',
113
+ 'relations_list': ['Datastreams', 'MultiDatastreams', 'ObservationGroups', 'Campaigns']
114
+ },
115
+ 'Campaign': {
116
+ 'singular': 'Campaign',
117
+ 'plural': 'Campaigns',
118
+ 'class': 'staplus_client.model.campaign.Campaign',
119
+ 'relations_list': ['Party', 'License', 'Datastreams', 'MultiDatastreams', 'ObservationGroups']
120
+ },
121
+ 'ObservationGroup': {
122
+ 'singular': 'ObservationGroup',
123
+ 'plural': 'ObservationGroups',
124
+ 'class': 'staplus_client.model.observation_group.ObservationGroup',
125
+ 'relations_list': ['Party', 'License', 'Observations', 'Relations', 'Campaigns']
126
+ },
127
+ 'Relation': {
128
+ 'singular': 'Relation',
129
+ 'plural': 'Relations',
130
+ 'class': 'staplus_client.model.relation.Relation',
131
+ 'relations_list': ['Subject', 'Object', 'ObservationGroups']
132
+ }
133
+ }
134
+
135
+ list_for_class = {}
136
+ for key, entity_type in EntityTypes.items():
137
+ list_for_class[entity_type["class"]] = entity_type["plural"]
138
+
139
+
140
+ def get_list_for_class(clazz):
141
+ clazz_name = clazz.__module__ + "." + clazz.__name__
142
+ return list_for_class[clazz_name]
@@ -0,0 +1,5 @@
1
+ from frost_sta_client.model.ext import unitofmeasurement
2
+
3
+ class UnitOfMeasurement(unitofmeasurement.UnitOfMeasurement):
4
+ def __init__(self, name="", symbol="", definition=""):
5
+ super().__init__(name, symbol, definition)
@@ -0,0 +1,17 @@
1
+ from frost_sta_client.model import feature_of_interest
2
+ from staplus_client.dao.features_of_interest import FeaturesOfInterestDao
3
+
4
+ class FeatureOfInterest(feature_of_interest.FeatureOfInterest):
5
+
6
+ def clone(self):
7
+ entity = self.__class__()
8
+ entity.id = self.id
9
+ return entity
10
+
11
+ def get_observations(self):
12
+ result = self.service.observations()
13
+ result.parent = self
14
+ return result
15
+
16
+ def get_dao(self, service):
17
+ return FeaturesOfInterestDao(service)
@@ -0,0 +1,21 @@
1
+ from frost_sta_client.model import historical_location
2
+ from staplus_client.dao.historical_location import HistoricalLocationDao
3
+
4
+ class HistoricalLocation(historical_location.HistoricalLocation):
5
+ def clone(self):
6
+ entity = self.__class__()
7
+ entity.id = self.id
8
+ return entity
9
+
10
+ def get_thing(self):
11
+ result = self.service.thing()
12
+ result.parent = self
13
+ return result
14
+
15
+ def get_locations(self):
16
+ result = self.service.locations()
17
+ result.parent = self
18
+ return result
19
+
20
+ def get_dao(self, service):
21
+ return HistoricalLocationDao(service)