# Sensorthings API Python Client
The **FR**aunhofer **O**pensource **S**ensor**T**hings API Python Client is a python package for the [SensorThingsAPI](https://github.com/opengeospatial/sensorthings) and aims to simplify development of SensorThings enabled client applications
## Features
* CRUD operations
* Queries on entity lists
* MultiDatastreams
## API
The `SensorThingsService` class is central to the library. An instance of it represents a SensorThings service and is
identified by a URI.
### CRUD operations
The source code below demonstrates the CRUD operations for Thing objects. Operations for other entities work similarly.
```python
import frost_sta_client as fsc
url = "exampleserver.com/FROST-Server/v1.1"
service = fsc.SensorThingsService(url)
```
#### Creating Entities
```python
from geojson import Point
point = Point((-115.81, 37.24))
location = fsc.Location(name="here", description="and there", location=point, encoding_type='application/geo+json')
thing = fsc.Thing(name='new thing',
description='I am a thing with a location',
properties={'withLocation': True, 'owner': 'IOSB'})
thing.locations = [location]
service.create(thing)
```
#### Querying Entities
Queries to the FROST Server can be modified to include filters, selections or expansions. The return value is always
an EntityList object, containing the parsed json response of the server.
```python
things_list = service.things().query().filter('id eq 1').list()
for thing in things_list:
print("my name is: {}".format(thing.name))
```
### EntityLists
When querying a list of entities that is particularly long, the FROST server divides the list into smaller chunks,
replaying to the request with the first chunk accompanied by the link to the next one.
The class `EntityList` implements the function `__iter__` and `__next__` which makes it capable of iterating
through the entire list of entities, including the calls to all chunks.
```python
things_list = service.things().query().list()
for thing in things_list:
print("my name is: {}".format(thing.name))
```
In a case where only the current chunk is supposed to be iterated, the `entities` list can be used.
```python
things_list = service.things().query().top(20).list()
for thing in things_list.entities:
print("my name is: {}".format(thing.name))
```
### Queries to related entity lists
For example the Observations of a given Datastream can be queried via
```python
datastream = service.datastreams().find(1)
observations_list = datastream.get_observations().query().filter("result gt 10").list()
```
### Callback function in `EntityList`
The progress of the loading process can be tracked by supplying a callback function along with a step size. The callback
function and the step size must both be provided to the `list` function (see example below).
If a callback function and a step size are used, the callback function is called every time the step size is
reached during the iteration within the for-loop. (Note that the callback function so far only works in
combination with a for-loop).
The callback function is called with one argument, which is the current index of the iteration.
```python
def callback_func(loaded_entities):
print("loaded {} entities!".format(loaded_entities))
service = fsc.SensorThingsService('example_url')
things = service.things().query().list(callback=callback_func, step_size=5)
for thing in things:
print(thing.name)
```
### DataArrays
DataArrays can be used to make the creation of Observations easier, because with an DataArray only one HTTP Request
has to be created.
An example usage looks as follows:
```python
import frost_sta_client as fsc
service = fsc.SensorThingsService("exampleserver.com/FROST-Server/v1.1")
dav = fsc.model.ext.data_array_value.DataArrayValue()
datastream = service.datastreams().find(1)
foi = service.features_of_interest().find(1)
components = {dav.Property.PHENOMENON_TIME, dav.Property.RESULT, dav.Property.FEATURE_OF_INTEREST}
dav.components = components
dav.datastream = datastream
obs1 = fsc.Observation(result=3,
phenomenon_time='2022-12-19T10:00:00Z',
datastream=datastream,
feature_of_interest=foi)
obs2 = fsc.Observation(result=5,
phenomenon_time='2022-12-19T10:00:00Z/2022-12-19T11:00:00Z',
datastream=datastream,
feature_of_interest=foi)
dav.add_observation(obs1)
dav.add_observation(obs2)
dad = fsc.model.ext.data_array_document.DataArrayDocument()
dad.add_data_array_value(dav)
result_list = service.observations().create(dad)
```
### Json (De)Serialization
Since not all possible backends that are configurable in jsonpickle handle long floats equally, the backend json
module is set to demjson3 per default. The backend can be modified by calling
`jsonpickle.set_preferred_backend('name_of_preferred_backend')` anywhere in the code that uses the client.
Raw data
{
"_id": null,
"home_page": "https://github.com/FraunhoferIOSB/FROST-Python-Client",
"name": "frost-sta-client",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "sta,ogc,frost,sensorthingsapi,IoT",
"author": "Jonathan Vogl",
"author_email": "jonathan.vogl@iosb.fraunhofer.de",
"download_url": "https://files.pythonhosted.org/packages/2d/4e/85467c0198837d2fa76b5d477e4c874f9d5bad6a7e5120499b853df46a90/frost_sta_client-1.1.45.tar.gz",
"platform": null,
"description": "# Sensorthings API Python Client\n\nThe **FR**aunhofer **O**pensource **S**ensor**T**hings API Python Client is a python package for the [SensorThingsAPI](https://github.com/opengeospatial/sensorthings) and aims to simplify development of SensorThings enabled client applications\n\n## Features\n* CRUD operations\n* Queries on entity lists\n* MultiDatastreams\n\n## API\n\nThe `SensorThingsService` class is central to the library. An instance of it represents a SensorThings service and is \nidentified by a URI.\n\n\n### CRUD operations\nThe source code below demonstrates the CRUD operations for Thing objects. Operations for other entities work similarly.\n```python\nimport frost_sta_client as fsc\n\nurl = \"exampleserver.com/FROST-Server/v1.1\"\nservice = fsc.SensorThingsService(url)\n```\n#### Creating Entities\n```python\nfrom geojson import Point\n\npoint = Point((-115.81, 37.24))\nlocation = fsc.Location(name=\"here\", description=\"and there\", location=point, encoding_type='application/geo+json')\n \nthing = fsc.Thing(name='new thing',\n description='I am a thing with a location',\n properties={'withLocation': True, 'owner': 'IOSB'})\nthing.locations = [location]\nservice.create(thing)\n```\n#### Querying Entities\nQueries to the FROST Server can be modified to include filters, selections or expansions. The return value is always\nan EntityList object, containing the parsed json response of the server.\n```python\nthings_list = service.things().query().filter('id eq 1').list()\n\nfor thing in things_list:\n print(\"my name is: {}\".format(thing.name))\n```\n### EntityLists\n\nWhen querying a list of entities that is particularly long, the FROST server divides the list into smaller chunks,\nreplaying to the request with the first chunk accompanied by the link to the next one.\n\nThe class `EntityList` implements the function `__iter__` and `__next__` which makes it capable of iterating \nthrough the entire list of entities, including the calls to all chunks.\n```python\nthings_list = service.things().query().list()\n\nfor thing in things_list:\n print(\"my name is: {}\".format(thing.name))\n```\n\nIn a case where only the current chunk is supposed to be iterated, the `entities` list can be used.\n\n```python\nthings_list = service.things().query().top(20).list()\n\nfor thing in things_list.entities:\n print(\"my name is: {}\".format(thing.name))\n```\n\n### Queries to related entity lists\n\nFor example the Observations of a given Datastream can be queried via\n```python\ndatastream = service.datastreams().find(1)\nobservations_list = datastream.get_observations().query().filter(\"result gt 10\").list()\n```\n\n### Callback function in `EntityList`\nThe progress of the loading process can be tracked by supplying a callback function along with a step size. The callback\nfunction and the step size must both be provided to the `list` function (see example below).\n\nIf a callback function and a step size are used, the callback function is called every time the step size is\nreached during the iteration within the for-loop. (Note that the callback function so far only works in\ncombination with a for-loop).\n\nThe callback function is called with one argument, which is the current index of the iteration.\n\n```python\ndef callback_func(loaded_entities):\n print(\"loaded {} entities!\".format(loaded_entities))\n\nservice = fsc.SensorThingsService('example_url')\n\nthings = service.things().query().list(callback=callback_func, step_size=5)\nfor thing in things:\n print(thing.name)\n```\n\n### DataArrays\nDataArrays can be used to make the creation of Observations easier, because with an DataArray only one HTTP Request\nhas to be created.\n\nAn example usage looks as follows:\n```python\n import frost_sta_client as fsc\n \n service = fsc.SensorThingsService(\"exampleserver.com/FROST-Server/v1.1\")\n dav = fsc.model.ext.data_array_value.DataArrayValue()\n datastream = service.datastreams().find(1)\n foi = service.features_of_interest().find(1)\n components = {dav.Property.PHENOMENON_TIME, dav.Property.RESULT, dav.Property.FEATURE_OF_INTEREST}\n dav.components = components\n dav.datastream = datastream\n obs1 = fsc.Observation(result=3,\n phenomenon_time='2022-12-19T10:00:00Z',\n datastream=datastream,\n feature_of_interest=foi)\n obs2 = fsc.Observation(result=5,\n phenomenon_time='2022-12-19T10:00:00Z/2022-12-19T11:00:00Z',\n datastream=datastream,\n feature_of_interest=foi)\n dav.add_observation(obs1)\n dav.add_observation(obs2)\n dad = fsc.model.ext.data_array_document.DataArrayDocument()\n dad.add_data_array_value(dav)\n result_list = service.observations().create(dad)\n```\n\n### Json (De)Serialization\nSince not all possible backends that are configurable in jsonpickle handle long floats equally, the backend json\nmodule is set to demjson3 per default. The backend can be modified by calling\n`jsonpickle.set_preferred_backend('name_of_preferred_backend')` anywhere in the code that uses the client.\n",
"bugtrack_url": null,
"license": "LGPL3",
"summary": "a client library to facilitate interaction with a FROST SensorThingsAPI Server",
"version": "1.1.45",
"project_urls": {
"Homepage": "https://github.com/FraunhoferIOSB/FROST-Python-Client"
},
"split_keywords": [
"sta",
"ogc",
"frost",
"sensorthingsapi",
"iot"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "a5d98cd48ebbf6d82fa8d7fb2c5c920be5deef82f6f163330518047c56e48a36",
"md5": "e49e01f15bc7370285e9343c622b0702",
"sha256": "5b201f6ea13e7a6007fbbfdee71980bc26968f2a9ed854e315b9e16ee3648a29"
},
"downloads": -1,
"filename": "frost_sta_client-1.1.45-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "e49e01f15bc7370285e9343c622b0702",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 61619,
"upload_time": "2023-11-08T14:25:01",
"upload_time_iso_8601": "2023-11-08T14:25:01.842175Z",
"url": "https://files.pythonhosted.org/packages/a5/d9/8cd48ebbf6d82fa8d7fb2c5c920be5deef82f6f163330518047c56e48a36/frost_sta_client-1.1.45-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2d4e85467c0198837d2fa76b5d477e4c874f9d5bad6a7e5120499b853df46a90",
"md5": "abe4c1b7e26fe6fe1470451d511c80ce",
"sha256": "a085ee3d3201b9302861c4280d6844413cb33568cd34d6f6ae21c5498a09aea4"
},
"downloads": -1,
"filename": "frost_sta_client-1.1.45.tar.gz",
"has_sig": false,
"md5_digest": "abe4c1b7e26fe6fe1470451d511c80ce",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 32891,
"upload_time": "2023-11-08T14:25:04",
"upload_time_iso_8601": "2023-11-08T14:25:04.016762Z",
"url": "https://files.pythonhosted.org/packages/2d/4e/85467c0198837d2fa76b5d477e4c874f9d5bad6a7e5120499b853df46a90/frost_sta_client-1.1.45.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-08 14:25:04",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "FraunhoferIOSB",
"github_project": "FROST-Python-Client",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "jsonpickle",
"specs": [
[
"<=",
"2.2.0"
]
]
},
{
"name": "demjson3",
"specs": []
},
{
"name": "requests",
"specs": []
},
{
"name": "furl",
"specs": []
},
{
"name": "geojson",
"specs": []
},
{
"name": "jsonpatch",
"specs": []
},
{
"name": "python-dateutil",
"specs": []
}
],
"lcname": "frost-sta-client"
}