Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
85ab5c7
added a retry object to requests
geomar-madolf Aug 21, 2023
4cd2a0f
Merge branch 'geomar-fix-compare-local-and-server-objects' into geoma…
geomar-madolf Aug 21, 2023
dbb1799
added gitlab ci
geomar-madolf Aug 21, 2023
31d9ead
Update sensorthingsservice.py
geomar-madolf Oct 5, 2023
7fd738f
Merge branch 'marc-adolf-geomar-clone-main-patch-08153' into 'geomar-…
geomar-madolf Nov 16, 2023
8a39005
merged
geomar-madolf Nov 28, 2023
5390f8e
Merge branch 'merge-fh-gm' into 'geomar-clone-main'
geomar-madolf Nov 28, 2023
331b808
added config for basic auth variables in the requests
geomar-madolf Feb 15, 2024
8bd524a
added retry parameters as config
geomar-madolf Feb 15, 2024
b981a6d
Merge branch 'merge-fh-gm' into 'geomar-clone-main'
geomar-madolf Mar 20, 2024
1a8a80c
exemp the fields properties in things from comparison
geomar-madolf Jan 24, 2025
02f21cb
Merge branch 'geomar-clone-main' of git.geomar.de:dm/services/frost-s…
geomar-madolf Jan 24, 2025
05e132c
Merge branch 'merge-fh-gm' into 'geomar-clone-main'
geomar-madolf Jan 24, 2025
cfad982
Merge branch 'geomar-clone-main' of git.geomar.de:dm/services/frost-s…
geomar-madolf Jan 24, 2025
7108e93
take new version from github
geomar-madolf Oct 9, 2025
7786dac
https://git.geomar.de/dm/services/frost-sta/frost-python-client-geoma…
geomar-madolf Oct 10, 2025
cf1b25e
added dist as release target
geomar-madolf Oct 10, 2025
93e286a
Merge branch 'marc-fix-pipeline' into marc-merge
geomar-madolf Oct 10, 2025
9d03faa
adapted tests for our changes
geomar-madolf Oct 10, 2025
113ed0d
now use pytest
geomar-madolf Oct 10, 2025
9cd1361
version ++
geomar-madolf Oct 10, 2025
53850d6
Marc fix pipeline
geomar-madolf Oct 10, 2025
527c01b
Merge branch 'marc-fix-pipeline' into 'geomar-clone-main'
geomar-madolf Oct 10, 2025
55a2566
resolved conflicts
geomar-madolf Oct 10, 2025
baf9a37
add python to pytest call
geomar-madolf Oct 13, 2025
9bebc41
added session handler and tests
geomar-madolf Oct 15, 2025
5f2c1dd
add session_handler file
geomar-madolf Oct 15, 2025
d56d938
changed gitlab ci images
geomar-madolf Oct 15, 2025
719788c
Update python-publish.yml
geomar-madolf Oct 15, 2025
1a13c85
Merge branch 'marc-merge' into 'geomar-clone-main'
geomar-madolf Oct 15, 2025
e077904
removed unnessecary lines
geomar-madolf Oct 15, 2025
0f0b230
removed unnessecary lines
geomar-madolf Oct 15, 2025
5bb6bbc
Update python-publish.yml
geomar-madolf Oct 15, 2025
b8ddfd0
Merge branch 'marc-merge' into 'geomar-clone-main'
geomar-madolf Oct 15, 2025
696d723
just tags should trigger a new package push
geomar-madolf Oct 15, 2025
75e4a20
updated readme with session
geomar-madolf Oct 15, 2025
e9fc9f1
Merge branch 'geomar-clone-main' into 'marc-merge'
geomar-madolf Oct 15, 2025
499e3e7
wrongfully readded main branch at release job
geomar-madolf Oct 15, 2025
03b0965
Update python-publish.yml
geomar-madolf Oct 15, 2025
7d494c5
Merge branch 'marc-merge' into 'geomar-clone-main'
geomar-madolf Oct 15, 2025
d9f5a9a
Merge branch 'geomar-clone-main' of git.geomar.de:dm/services/frost-s…
geomar-madolf Oct 15, 2025
1ae6442
Merge branch 'geomar-clone-main' into marc-merge
geomar-madolf Oct 15, 2025
9d51570
Merge branch 'marc-merge' into 'geomar-clone-main'
geomar-madolf Oct 15, 2025
5766c0f
removed gitlab ci and set version to match github
geomar-madolf Oct 15, 2025
ae13924
Merge pull request #1 from geomar-madolf/geomar-to-github
geomar-madolf Oct 15, 2025
0d9148a
removed config object
geomar-madolf Oct 15, 2025
a1775d7
Merge branch 'marc-merge' into geomar-to-github
geomar-madolf Oct 15, 2025
6fc0142
Merge pull request #2 from geomar-madolf/geomar-to-github
geomar-madolf Oct 15, 2025
a1e0cc6
removed changed to thing
geomar-madolf Oct 15, 2025
7807fb8
Merge pull request #3 from geomar-madolf/geomar-to-github
geomar-madolf Oct 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import frost_sta_client as fsc

url = "exampleserver.com/FROST-Server/v1.1"
auth_handler = fsc.AuthHandler(username="admin", password="admin") # if server is configured for basic auth, else None
service = fsc.SensorThingsService(url, auth_handler=auth_handler)
session_handler = fsc.SessionHandler() #if continuous requests from requests.Sessions should be used
service = fsc.SensorThingsService(url, auth_handler=auth_handler, session_handler=session_handler)
```
#### Creating Entities
```python
Expand Down
1 change: 1 addition & 0 deletions frost_sta_client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from frost_sta_client.model.ext.unitofmeasurement import UnitOfMeasurement
from frost_sta_client.service.sensorthingsservice import SensorThingsService
from frost_sta_client.service.auth_handler import AuthHandler
from frost_sta_client.service.session_handler import SessionHandler
from frost_sta_client.model.ext.entity_type import EntityTypes
from frost_sta_client.model.ext.entity_list import EntityList
from frost_sta_client.model.ext.data_array_value import DataArrayValue
Expand Down
1 change: 1 addition & 0 deletions frost_sta_client/service/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from frost_sta_client.service import sensorthingsservice
from frost_sta_client.service import auth_handler
from frost_sta_client.service import session_handler
328 changes: 181 additions & 147 deletions frost_sta_client/service/sensorthingsservice.py
Original file line number Diff line number Diff line change
@@ -1,147 +1,181 @@
# Copyright (C) 2021 Fraunhofer Institut IOSB, Fraunhoferstr. 1, D 76131
# Karlsruhe, Germany.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import requests
from furl import furl
import logging

from frost_sta_client.dao import *
from frost_sta_client.service import auth_handler
from frost_sta_client.model.ext import entity_type


class SensorThingsService:

def __init__(self, url, auth_handler=None, proxies=None):
self.url = url
self.auth_handler = auth_handler
self.proxies = proxies

@property
def url(self):
return self._url

@url.setter
def url(self, value):
if value is None:
self._url = value
return
try:
self._url = furl(value)
except ValueError as e:
logging.error("received invalid url")
raise e


@property
def auth_handler(self):
return self._auth_handler

@auth_handler.setter
def auth_handler(self, value):
if value is None:
self._auth_handler = None
return
if not isinstance(value, auth_handler.AuthHandler):
raise ValueError('auth should be of type AuthHandler!')
self._auth_handler = value


@property
def proxies(self):
return self._proxies

@proxies.setter
def proxies(self, value):
if value is None:
self._proxies = None
return
elif not isinstance(value, dict):
raise ValueError('Proxies must be a Dictionary!')
self._proxies = value


def execute(self, method, url, **kwargs):
if self.auth_handler is not None:
response = requests.request(method, url, proxies=self.proxies, auth=self.auth_handler.add_auth_header(), **kwargs)
else:
response = requests.request(method, url, proxies=self.proxies, **kwargs)
try:
response.raise_for_status()
except requests.exceptions.HTTPError as e:
raise e

return response

def get_path(self, parent, relation):
if parent is None:
return relation
this_entity_type = entity_type.get_list_for_class(type(parent))
_id = f"'{parent.id}'" if isinstance(parent.id, str) else parent.id
return "{entity_type}({id})/{relation}".format(entity_type=this_entity_type, id=_id, relation=relation)

def get_full_path(self, parent, relation):
slash = "" if self.url.pathstr[-1] == '/' else "/"
url = self.url.url + slash + self.get_path(parent, relation)
return furl(url)

def create(self, entity):
entity.get_dao(self).create(entity)

def update(self, entity):
entity.get_dao(self).update(entity)

def patch(self, entity, patches):
entity.get_dao(self).patch(entity, patches)

def delete(self, entity):
entity.get_dao(self).delete(entity)

def actuators(self):
return actuator.ActuatorDao(self)

def datastreams(self):
return datastream.DatastreamDao(self)

def features_of_interest(self):
return features_of_interest.FeaturesOfInterestDao(self)

def historical_locations(self):
return historical_location.HistoricalLocationDao(self)

def locations(self):
return location.LocationDao(self)

def multi_datastreams(self):
return multi_datastream.MultiDatastreamDao(self)

def observations(self):
return observation.ObservationDao(self)

def observed_properties(self):
return observedproperty.ObservedPropertyDao(self)

def sensors(self):
return sensor.SensorDao(self)

def tasks(self):
return task.TaskDao(self)

def tasking_capabilities(self):
return tasking_capability.TaskingCapabilityDao(self)

def things(self):
return thing.ThingDao(self)
# Copyright (C) 2021 Fraunhofer Institut IOSB, Fraunhoferstr. 1, D 76131
# Karlsruhe, Germany.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import requests

from furl import furl
import logging

from frost_sta_client.dao import *
from frost_sta_client.service import auth_handler
from frost_sta_client.service import session_handler
from frost_sta_client.model.ext import entity_type


class SensorThingsService:
def __init__(self, url, auth_handler=None, session_handler=None, proxies=None):
self.url = url
self.session_handler = session_handler
self.auth_handler = auth_handler
self.proxies = proxies

@property
def url(self):
return self._url

@url.setter
def url(self, value):
if value is None:
self._url = value
return
try:
self._url = furl(value)
except ValueError as e:
logging.error("received invalid url")
raise e

@property
def auth_handler(self):
return self._auth_handler

@auth_handler.setter
def auth_handler(self, value):
if value is None:
self._auth_handler = None
return
if not isinstance(value, auth_handler.AuthHandler):
raise ValueError("auth should be of type AuthHandler!")

self._auth_handler = value
if self.session_handler is not None:
self.session_handler.set_auth(value.add_auth_header())

@property
def session_handler(self):
return self._session_handler

@session_handler.setter
def session_handler(self, value):
if value is None:
self._session_handler = None
return
if not isinstance(value, session_handler.SessionHandler):
raise ValueError("session should be of type SessionHandler!")
self._session_handler = value

if self.auth_handler is not None:
self.session_handler.set_auth(self.auth_handler.add_auth_header())

@property
def proxies(self):
return self._proxies

@proxies.setter
def proxies(self, value):
if value is None:
self._proxies = None
return
elif not isinstance(value, dict):
raise ValueError("Proxies must be a Dictionary!")
self._proxies = value

def execute(self, method, url, **kwargs):

if self.session_handler is not None:
request_session = self.session_handler.get_session()
response = request_session.request(
method=method, url=url, proxies=self.proxies, **kwargs
)
elif self.auth_handler is not None:
response = requests.request(
method=method,
url=url,
proxies=self.proxies,
auth=self.auth_handler.add_auth_header(),
**kwargs,
)
else:
response = requests.request(
method=method, url=url, proxies=self.proxies, **kwargs
)
try:
response.raise_for_status()
except requests.exceptions.HTTPError as e:
raise e

return response

def get_path(self, parent, relation):
if parent is None:
return relation
this_entity_type = entity_type.get_list_for_class(type(parent))
_id = f"'{parent.id}'" if isinstance(parent.id, str) else parent.id
return "{entity_type}({id})/{relation}".format(
entity_type=this_entity_type, id=_id, relation=relation
)

def get_full_path(self, parent, relation):
slash = "" if self.url.pathstr[-1] == "/" else "/"
url = self.url.url + slash + self.get_path(parent, relation)
return furl(url)

def create(self, entity):
entity.get_dao(self).create(entity)

def update(self, entity):
entity.get_dao(self).update(entity)

def patch(self, entity, patches):
entity.get_dao(self).patch(entity, patches)

def delete(self, entity):
entity.get_dao(self).delete(entity)

def actuators(self):
return actuator.ActuatorDao(self)

def datastreams(self):
return datastream.DatastreamDao(self)

def features_of_interest(self):
return features_of_interest.FeaturesOfInterestDao(self)

def historical_locations(self):
return historical_location.HistoricalLocationDao(self)

def locations(self):
return location.LocationDao(self)

def multi_datastreams(self):
return multi_datastream.MultiDatastreamDao(self)

def observations(self):
return observation.ObservationDao(self)

def observed_properties(self):
return observedproperty.ObservedPropertyDao(self)

def sensors(self):
return sensor.SensorDao(self)

def tasks(self):
return task.TaskDao(self)

def tasking_capabilities(self):
return tasking_capability.TaskingCapabilityDao(self)

def things(self):
return thing.ThingDao(self)
Loading