staplus-client


Namestaplus-client JSON
Version 0.3.3 PyPI version JSON
download
home_pagehttps://github.com/securedimensions/STAplus-Python-Client
SummaryA client library to facilitate interaction with a STAplus Server
upload_time2024-05-24 09:26:06
maintainerNone
docs_urlNone
authorAndreas Matheus
requires_pythonNone
licenseLGPL3
keywords ogc staplus sensorthingsapi iot
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # OGC STAplus (SensorThings) API Python Client

This STAplus Python Client implements the [STAplus](https://docs.ogc.org/is/22-022r1/22-022r1.html) API. The aim is to simplify development of STAplus and SensorThings enabled client applications.

**_NOTE:_** This implementation is an extension to the [FROST API Python Client](https://github.com/FraunhoferIOSB/FROST-Python-Client). To have better control over bug fixing and improvements, this implementation is actually based on a fork of the FROST API Python Client, hosted on a Secure Dimensions Github repository: [STA Python Client](https://github.com/securedimensions/STA-Python-Client).

## Python Version
This library requires Python 3.11 or better to support parsing ISO datetime values (`datetime.datetime.fromisoformat`). See [here](https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat) for more information.

## Features
* Support for all STAplus and SensorThings entity types
* CRUD operations
* Queries on entity lists
* Query on single entity
* MultiDatastreams
* Cloning Entities
* Fetching entities relative to an entity (using many-association)
* Fetching one single entity relative to an entity (using one-association)

## Installation via PyPi
Installation via pip: `pip install staplus-client`

## Limitations
This implementation has the following limitations for the Entity `Location` and `FeatureOfInterest`:

* `Location/location` must be a GeoJSON Geometry object (this is an Any in the SensorThings datamodel)
* `FeatureOfInterest/feature` must be a GeoJSON Object (this is an Any in the SensorThings datamodel)

For both entities, the `encodingType` attribute is not tested by the implementation. For interoperability with other applications, the value should be `application/geo+json`.

## API

The `STAplusService` class is central to the library. An instance of it represents a STAplus service and is identified by a URI.


### Creating Entities via the STAplus Client
The source code below demonstrates how to initialize the client for a STAplus endpoint on `url`. 

```python
import staplus_client as staplus

url = "<your domain>/staplus/v1.1"
service = staplus.STAplusService(url)
```

#### Configuring an Authentication Handler
When interacting with a STAplus service that has enabled authentication, the use of an `AuthHandler` is required.

```python
import staplus_client as staplus

url = "<your domain>/staplus/v1.1"
auth_handler.AuthHandler(...)
service = staPlus.STAplusService(url, auth_handler=auth)
```

#### Creating a Party Entity
The `Party` entity represents a user or an institution. When interacting with a STAplus service that has enabled authentication, the `Party` entity represents the acting user and access control controls Create, Update and Delete.
```python
import staplus_client as staplus

url = "<your domain>/staplus/v1.1"
auth_handler.AuthHandler(...)
service = staPlus.STAplusService(url, auth_handler=auth)
ljs = staPlus.Party(description='I am Long John Silver the opportunistic pirate created by Robert Louis Stevenson',
                    display_name='LJS',
                    role='individual')
service.create(ljs)
```

#### Creating a STAplus enriched Datastream
The STAplus `Datastream` is capable to have a `Party` and a `License` associated. Also, the `Thing` is associated to a `Party` entity.
```python
import staplus_client as staplus

url = "<your domain>/staplus/v1.1"
auth_handler.AuthHandler(...)
service = staplus.STAplusService(url, auth_handler=auth)
ljs = staplus.Party(description='I am Long John Silver the opportunistic pirate created by Robert Louis Stevenson',
                    display_name='LJS',
                    role='individual')
service.create(ljs)

# find the CC-BY license
cc_by = service.licenses().find('CC_BY')

# Create a thing associated to LJS
thing = staplus.Thing('Raspberry Pi', 'Raspberry Pi 4', )
thing.party = ljs

# Create a sensor
sensor = staplus.Sensor('air temperature sensor', 'SmartCitizen air temperature sensor', 'test/html', None,
                        'https://www.seeedstudio.com/Smart-Citizen-Starter-Kit-p-2865.html')

# Create a datastream associated to LJS with CC-BY license
datastream = staplus.Datastream('air temperature', 'air temperature measured with the SmartCitizen Kit',
                                'http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement', 
                                staplus.UnitOfMeasurement('Celsius', 'C', 'https://qudt.org/vocab/unit/DEG_C'))
datastream.observed_property = staplus.ObservedProperty('temperature', 'http://vocabs.lter-europe.net/EnvThes/22035',
                                            'air temperature')
datastream.party = ljs
datastream.thing = thing
datastream.sensor = sensor
datastream.license = cc_by

service.create(datastream)
```

#### Creating a few Observation entities
```python
import staplus_client as staplus

url = "<your domain>/staplus/v1.1"
auth_handler.AuthHandler(...)
service = staplus.STAplusService(url, auth_handler=auth)
ljs = staplus.Party(description='I am Long John Silver the opportunistic pirate created by Robert Louis Stevenson',
                    display_name='LJS',
                    role='individual')
service.create(ljs)

# The feature of interest
marienplatz = {
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [11.571831046,48.135666124]
    }
}
foi = staplus.FeatureOfInterest('Marienplatz', 'famous place in Munich', 'application/vnd.geo+json', marienplatz)

# The temperature
observation = staplus.Observation("2023-07-02T15:34:00Z", 20, "2023-07-02T15:34:00Z")
observation.feature_of_interest = foi
observation.datastream = service.datastreams().find(<the datastream id created previously>)

service.create(observation)

observation = staplus.Observation("2023-07-02T15:34:10Z", 21, "2023-07-02T15:34:10Z")
observation.feature_of_interest = foi
observation.datastream = service.datastreams().find(<the datastream id created previously>)

service.create(observation)
```

#### Creating an ObservationGroup Entity
A `ObservationGroup` entity can be used as a container of observations that belong together.

```python
import staplus_client as staplus

url = "<your domain>/staplus/v1.1"
service = staPlus.STAplusService(url, auth_handler=auth)
ljs = staPlus.Party(description='I am Long John Silver the opportunistic pirate created by Robert Louis Stevenson',
                    display_name='LJS',
                    role='individual')
service.create(ljs)
group = staPlus.ObservationGroup("Marienplatz", "observations on Marienplatz", "none", "")
group.creation_time = parse_datetime("2023-07-02T15:35:00Z")
# Add all the observations that are associated to the FoI named 'Marienplatz'
group.observations = service.observations().query().filter("FeatureOfInterest/name eq 'Marienplatz'").list()
group.license = service.licenses().find('CC_BY')
group.party = ljs

service.create(group)
```

#### Creating SensorThings Entities
How to use this implementation on SensorThings Entity Types, please see the [FROST-Python-Client](https://github.com/securedimensions/STAplus-Python-Client) documentation.

### Fetching Entities via the STAplus Client
This implementation supports the fetching of `EntityList` and `Entity`.

#### Fetching an EntityList
An `EntityList` is the result from fetching entities that have a multiplicity `0..*` or `1..*`. To fetch the list of entities, you need to use the `.list()` function. The following example fetches all datastreams:

```python
import staplus_client as staplus

url = "<your domain>/staplus/v1.1"
service = staplus.STAplusService(url)
datastreams = service.datastreams().query().list()
```

In order to get all entities of a given entity, you can use the function `get_<entity_plural>()`. For example, to fetch all datastreams of a given `Thing` please use the following code: 

```python
import staplus_client as staplus

url = "<your domain>/staplus/v1.1"
service = staplus.STAplusService(url)
thing = service.things().find(1)
thing_datastreams = thing.get_datastreams().query().list()
```

#### Fetching an Entity
An `Entity` is the result from fetching an entity that has multiplicity `0..1` or `1`. To fetch one single entity you need to use the `.item()` function. The following example fetches the thing associated to a datastream:

```python
import staplus_client as staplus

url = "<your domain>/staplus/v1.1"
service = staplus.STAplusService(url)
datastream = service.datastreams().find(1).item()
datastream_thing = datastream.get_thing().query().item()
```

### Cloning an Entity
When creating an Entity, mandatory entities can be provided either inline or by reference. To support the referencing of existing entities, the `clone()` function can be used. `clone()` returns a copy of the entity but only containing the `@iot.id`. This is important when preparing MQTT messages to publish observations.

#### Example ObservationGroup with inline entities
```JSON
{
  "Observations": [
    {
      "Datastream": {
        "@iot.id": 1,
        "description": "desc",
        "name": "new name",
        "observationType": "OM_Observation",
        "observedArea": {
          "coordinates": [11.509234, 48.110728],
          "type": "Point"
        },
        "phenomenonTime": "2023-07-24T06:30:18+00:00/2023-09-14T05:40:25.292000+00:00",
        "resultTime": "2023-07-24T06:30:18+00:00/2023-07-24T06:31:42+00:00",
        "unitOfMeasurement": { "definition": "...", "name": "n", "symbol": "n" }
      },
      "FeatureOfInterest": {
        "@iot.id": 77,
        "description": "A rainy place",
        "encodingType": "application/geo+json",
        "feature": { "coordinates": [-6.22299, 53.306816], "type": "Point" },
        "name": "Dublin",
        "properties": {
          "datastreams": [1, 2, 76, 2, 78, 77],
          "multi_datastreams": [11]
        }
      },
      "phenomenonTime": "2024-04-13T19:57:08+00:00",
      "result": 19.111,
      "resultTime": "2024-05-02T19:36:06+00:00"
    },
    {
      "Datastream": {
        "@iot.id": 2,
        "description": "air relative humidity measured with the SmartCitizen Kit",
        "name": "Relative Humidity",
        "observationType": "http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement",
        "observedArea": {
          "coordinates": [11.509234, 48.110728],
          "type": "Point"
        },
        "phenomenonTime": "2023-07-24T06:30:18+00:00/2023-07-24T06:31:42+00:00",
        "resultTime": "2023-07-24T06:30:18+00:00/2023-07-24T06:31:42+00:00",
        "unitOfMeasurement": {
          "definition": "https://qudt.org/vocab/unit/PERCENT",
          "name": "Percentage",
          "symbol": "%"
        }
      },
      "FeatureOfInterest": {
        "@iot.id": 77,
        "description": "A rainy place",
        "encodingType": "application/geo+json",
        "feature": { "coordinates": [-6.22299, 53.306816], "type": "Point" },
        "name": "Dublin",
        "properties": {
          "datastreams": [1, 2, 76, 2, 78, 77],
          "multi_datastreams": [11]
        }
      },
      "phenomenonTime": "2024-04-13T19:57:08+00:00",
      "result": 43.0,
      "resultTime": "2024-05-02T19:36:06+00:00"
    },
    {
      "Datastream": {
        "@iot.id": 76,
        "description": "Precipitation measured with the FT-0310 Weather Station",
        "name": "Rain",
        "observationType": "http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement",
        "unitOfMeasurement": {
          "definition": "https://qudt.org/vocab/unit/MilliM",
          "name": "millimiter",
          "symbol": "mm"
        }
      },
      "FeatureOfInterest": {
        "@iot.id": 77,
        "description": "A rainy place",
        "encodingType": "application/geo+json",
        "feature": { "coordinates": [-6.22299, 53.306816], "type": "Point" },
        "name": "Dublin",
        "properties": {
          "datastreams": [1, 2, 76, 2, 78, 77],
          "multi_datastreams": [11]
        }
      },
      "phenomenonTime": "2024-04-13T19:57:08+00:00",
      "result": 87.0,
      "resultTime": "2024-05-02T19:36:06+00:00"
    },
    {
      "Datastream": {
        "@iot.id": 77,
        "description": "Wind direction measured with the FT-0310 Weather Station",
        "name": "Wind direction",
        "observationType": "http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement",
        "unitOfMeasurement": {
          "definition": "https://qudt.org/vocab/unit/DEG",
          "name": "degree",
          "symbol": "deg"
        }
      },
      "FeatureOfInterest": {
        "@iot.id": 77,
        "description": "A rainy place",
        "encodingType": "application/geo+json",
        "feature": { "coordinates": [-6.22299, 53.306816], "type": "Point" },
        "name": "Dublin",
        "properties": {
          "datastreams": [1, 2, 76, 2, 78, 77],
          "multi_datastreams": [11]
        }
      },
      "phenomenonTime": "2024-04-13T19:57:08+00:00",
      "result": 241.0,
      "resultTime": "2024-05-02T19:36:06+00:00"
    },
    {
      "FeatureOfInterest": {
        "@iot.id": 77,
        "description": "A rainy place",
        "encodingType": "application/geo+json",
        "feature": { "coordinates": [-6.22299, 53.306816], "type": "Point" },
        "name": "Dublin",
        "properties": {
          "datastreams": [1, 2, 76, 2, 78, 77],
          "multi_datastreams": [11]
        }
      },
      "MultiDatastream": {
        "@iot.id": 11,
        "ObservedProperties": [
          {
            "@iot.id": 105,
            "definition": "http://vocab.nerc.ac.uk/standard_name/wind_speed/",
            "description": "Wind speed",
            "name": "wspeed"
          },
          {
            "@iot.id": 106,
            "definition": "http://vocab.nerc.ac.uk/standard_name/wind_gust_from_direction/",
            "description": "Wind gust",
            "name": "wgust"
          }
        ],
        "description": "Wind speed average and gust measured with the FT-0310 Weather Station",
        "multiObservationDataTypes": [
          "http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement",
          "http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement"
        ],
        "name": "Wind speed avg and gust",
        "observationType": "http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_ComplexObservation",
        "unitOfMeasurements": [
          {
            "definition": "https://qudt.org/vocab/unit/M-PER-SEC",
            "name": "Meters per second",
            "symbol": "m/s"
          },
          {
            "definition": "https://qudt.org/vocab/unit/M-PER-SEC",
            "name": "Meters per second",
            "symbol": "m/s"
          }
        ]
      },
      "phenomenonTime": "2024-04-13T19:57:08+00:00",
      "result": [0.0, 0.0],
      "resultTime": "2024-05-02T19:36:06+00:00"
    }
  ],
  "Party": {
    "@iot.id": "36fd7ca4-08bb-11ef-b156-a337e8ef4d15",
    "displayName": "LJS",
    "role": "individual"
  },
  "creationTime": "2024-05-02T19:36:06+00:00",
  "description": " ",
  "endTime": "2024-05-02T19:36:06+00:00",
  "name": "OG 2024-05-02T19:36:06+00:00"
}
```

This example with inline `Datastream` and `FeatureOfInterest` entities has the size of 6245 Bytes.

#### Example ObservationGroup with referencing entities
```JSON
{
  "Observations": [
    {
      "Datastream": { "@iot.id": 1 },
      "FeatureOfInterest": { "@iot.id": 77 },
      "phenomenonTime": "2024-04-13T19:57:08+00:00",
      "result": 19.111,
      "resultTime": "2024-05-03T09:48:33+00:00"
    },
    {
      "Datastream": { "@iot.id": 2 },
      "FeatureOfInterest": { "@iot.id": 77 },
      "phenomenonTime": "2024-04-13T19:57:08+00:00",
      "result": 43.0,
      "resultTime": "2024-05-03T09:48:33+00:00"
    },
    {
      "Datastream": { "@iot.id": 76 },
      "FeatureOfInterest": { "@iot.id": 77 },
      "phenomenonTime": "2024-04-13T19:57:08+00:00",
      "result": 87.0,
      "resultTime": "2024-05-03T09:48:33+00:00"
    },
    {
      "Datastream": { "@iot.id": 77 },
      "FeatureOfInterest": { "@iot.id": 77 },
      "phenomenonTime": "2024-04-13T19:57:08+00:00",
      "result": 241.0,
      "resultTime": "2024-05-03T09:48:33+00:00"
    },
    {
      "FeatureOfInterest": { "@iot.id": 77 },
      "MultiDatastream": { "@iot.id": 11 },
      "phenomenonTime": "2024-04-13T19:57:08+00:00",
      "result": [0.0, 0.0],
      "resultTime": "2024-05-03T09:48:33+00:00"
    }
  ],
  "Party": {
    "@iot.id": "4cd42a10-0932-11ef-919f-57f24e9b90e3",
    "displayName": "LJS",
    "role": "individual"
  },
  "creationTime": "2024-05-03T09:48:33+00:00",
  "description": " ",
  "endTime": "2024-05-03T09:48:33+00:00",
  "name": "OG 2024-05-03T09:48:33+00:00"
}
```

This example with referenced `Datastream` and `FeatureOfInterest` entities has the size of 1420 Bytes.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/securedimensions/STAplus-Python-Client",
    "name": "staplus-client",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "ogc, staplus, sensorthingsapi, IoT",
    "author": "Andreas Matheus",
    "author_email": "andreas.matheus@secure-dimensions.de",
    "download_url": "https://files.pythonhosted.org/packages/89/c1/dfd362fea4ad82106f830b4cd7d7d026a6045280e6c29f819af518c9a945/staplus_client-0.3.3.tar.gz",
    "platform": null,
    "description": "# OGC STAplus (SensorThings) API Python Client\n\nThis STAplus Python Client implements the [STAplus](https://docs.ogc.org/is/22-022r1/22-022r1.html) API. The aim is to simplify development of STAplus and SensorThings enabled client applications.\n\n**_NOTE:_** This implementation is an extension to the [FROST API Python Client](https://github.com/FraunhoferIOSB/FROST-Python-Client). To have better control over bug fixing and improvements, this implementation is actually based on a fork of the FROST API Python Client, hosted on a Secure Dimensions Github repository: [STA Python Client](https://github.com/securedimensions/STA-Python-Client).\n\n## Python Version\nThis library requires Python 3.11 or better to support parsing ISO datetime values (`datetime.datetime.fromisoformat`). See [here](https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat) for more information.\n\n## Features\n* Support for all STAplus and SensorThings entity types\n* CRUD operations\n* Queries on entity lists\n* Query on single entity\n* MultiDatastreams\n* Cloning Entities\n* Fetching entities relative to an entity (using many-association)\n* Fetching one single entity relative to an entity (using one-association)\n\n## Installation via PyPi\nInstallation via pip: `pip install staplus-client`\n\n## Limitations\nThis implementation has the following limitations for the Entity `Location` and `FeatureOfInterest`:\n\n* `Location/location` must be a GeoJSON Geometry object (this is an Any in the SensorThings datamodel)\n* `FeatureOfInterest/feature` must be a GeoJSON Object (this is an Any in the SensorThings datamodel)\n\nFor both entities, the `encodingType` attribute is not tested by the implementation. For interoperability with other applications, the value should be `application/geo+json`.\n\n## API\n\nThe `STAplusService` class is central to the library. An instance of it represents a STAplus service and is identified by a URI.\n\n\n### Creating Entities via the STAplus Client\nThe source code below demonstrates how to initialize the client for a STAplus endpoint on `url`. \n\n```python\nimport staplus_client as staplus\n\nurl = \"<your domain>/staplus/v1.1\"\nservice = staplus.STAplusService(url)\n```\n\n#### Configuring an Authentication Handler\nWhen interacting with a STAplus service that has enabled authentication, the use of an `AuthHandler` is required.\n\n```python\nimport staplus_client as staplus\n\nurl = \"<your domain>/staplus/v1.1\"\nauth_handler.AuthHandler(...)\nservice = staPlus.STAplusService(url, auth_handler=auth)\n```\n\n#### Creating a Party Entity\nThe `Party` entity represents a user or an institution. When interacting with a STAplus service that has enabled authentication, the `Party` entity represents the acting user and access control controls Create, Update and Delete.\n```python\nimport staplus_client as staplus\n\nurl = \"<your domain>/staplus/v1.1\"\nauth_handler.AuthHandler(...)\nservice = staPlus.STAplusService(url, auth_handler=auth)\nljs = staPlus.Party(description='I am Long John Silver the opportunistic pirate created by Robert Louis Stevenson',\n                    display_name='LJS',\n                    role='individual')\nservice.create(ljs)\n```\n\n#### Creating a STAplus enriched Datastream\nThe STAplus `Datastream` is capable to have a `Party` and a `License` associated. Also, the `Thing` is associated to a `Party` entity.\n```python\nimport staplus_client as staplus\n\nurl = \"<your domain>/staplus/v1.1\"\nauth_handler.AuthHandler(...)\nservice = staplus.STAplusService(url, auth_handler=auth)\nljs = staplus.Party(description='I am Long John Silver the opportunistic pirate created by Robert Louis Stevenson',\n                    display_name='LJS',\n                    role='individual')\nservice.create(ljs)\n\n# find the CC-BY license\ncc_by = service.licenses().find('CC_BY')\n\n# Create a thing associated to LJS\nthing = staplus.Thing('Raspberry Pi', 'Raspberry Pi 4', )\nthing.party = ljs\n\n# Create a sensor\nsensor = staplus.Sensor('air temperature sensor', 'SmartCitizen air temperature sensor', 'test/html', None,\n                        'https://www.seeedstudio.com/Smart-Citizen-Starter-Kit-p-2865.html')\n\n# Create a datastream associated to LJS with CC-BY license\ndatastream = staplus.Datastream('air temperature', 'air temperature measured with the SmartCitizen Kit',\n                                'http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement', \n                                staplus.UnitOfMeasurement('Celsius', 'C', 'https://qudt.org/vocab/unit/DEG_C'))\ndatastream.observed_property = staplus.ObservedProperty('temperature', 'http://vocabs.lter-europe.net/EnvThes/22035',\n                                            'air temperature')\ndatastream.party = ljs\ndatastream.thing = thing\ndatastream.sensor = sensor\ndatastream.license = cc_by\n\nservice.create(datastream)\n```\n\n#### Creating a few Observation entities\n```python\nimport staplus_client as staplus\n\nurl = \"<your domain>/staplus/v1.1\"\nauth_handler.AuthHandler(...)\nservice = staplus.STAplusService(url, auth_handler=auth)\nljs = staplus.Party(description='I am Long John Silver the opportunistic pirate created by Robert Louis Stevenson',\n                    display_name='LJS',\n                    role='individual')\nservice.create(ljs)\n\n# The feature of interest\nmarienplatz = {\n    \"type\": \"Feature\",\n    \"geometry\": {\n        \"type\": \"Point\",\n        \"coordinates\": [11.571831046,48.135666124]\n    }\n}\nfoi = staplus.FeatureOfInterest('Marienplatz', 'famous place in Munich', 'application/vnd.geo+json', marienplatz)\n\n# The temperature\nobservation = staplus.Observation(\"2023-07-02T15:34:00Z\", 20, \"2023-07-02T15:34:00Z\")\nobservation.feature_of_interest = foi\nobservation.datastream = service.datastreams().find(<the datastream id created previously>)\n\nservice.create(observation)\n\nobservation = staplus.Observation(\"2023-07-02T15:34:10Z\", 21, \"2023-07-02T15:34:10Z\")\nobservation.feature_of_interest = foi\nobservation.datastream = service.datastreams().find(<the datastream id created previously>)\n\nservice.create(observation)\n```\n\n#### Creating an ObservationGroup Entity\nA `ObservationGroup` entity can be used as a container of observations that belong together.\n\n```python\nimport staplus_client as staplus\n\nurl = \"<your domain>/staplus/v1.1\"\nservice = staPlus.STAplusService(url, auth_handler=auth)\nljs = staPlus.Party(description='I am Long John Silver the opportunistic pirate created by Robert Louis Stevenson',\n                    display_name='LJS',\n                    role='individual')\nservice.create(ljs)\ngroup = staPlus.ObservationGroup(\"Marienplatz\", \"observations on Marienplatz\", \"none\", \"\")\ngroup.creation_time = parse_datetime(\"2023-07-02T15:35:00Z\")\n# Add all the observations that are associated to the FoI named 'Marienplatz'\ngroup.observations = service.observations().query().filter(\"FeatureOfInterest/name eq 'Marienplatz'\").list()\ngroup.license = service.licenses().find('CC_BY')\ngroup.party = ljs\n\nservice.create(group)\n```\n\n#### Creating SensorThings Entities\nHow to use this implementation on SensorThings Entity Types, please see the [FROST-Python-Client](https://github.com/securedimensions/STAplus-Python-Client) documentation.\n\n### Fetching Entities via the STAplus Client\nThis implementation supports the fetching of `EntityList` and `Entity`.\n\n#### Fetching an EntityList\nAn `EntityList` is the result from fetching entities that have a multiplicity `0..*` or `1..*`. To fetch the list of entities, you need to use the `.list()` function. The following example fetches all datastreams:\n\n```python\nimport staplus_client as staplus\n\nurl = \"<your domain>/staplus/v1.1\"\nservice = staplus.STAplusService(url)\ndatastreams = service.datastreams().query().list()\n```\n\nIn order to get all entities of a given entity, you can use the function `get_<entity_plural>()`. For example, to fetch all datastreams of a given `Thing` please use the following code: \n\n```python\nimport staplus_client as staplus\n\nurl = \"<your domain>/staplus/v1.1\"\nservice = staplus.STAplusService(url)\nthing = service.things().find(1)\nthing_datastreams = thing.get_datastreams().query().list()\n```\n\n#### Fetching an Entity\nAn `Entity` is the result from fetching an entity that has multiplicity `0..1` or `1`. To fetch one single entity you need to use the `.item()` function. The following example fetches the thing associated to a datastream:\n\n```python\nimport staplus_client as staplus\n\nurl = \"<your domain>/staplus/v1.1\"\nservice = staplus.STAplusService(url)\ndatastream = service.datastreams().find(1).item()\ndatastream_thing = datastream.get_thing().query().item()\n```\n\n### Cloning an Entity\nWhen creating an Entity, mandatory entities can be provided either inline or by reference. To support the referencing of existing entities, the `clone()` function can be used. `clone()` returns a copy of the entity but only containing the `@iot.id`. This is important when preparing MQTT messages to publish observations.\n\n#### Example ObservationGroup with inline entities\n```JSON\n{\n  \"Observations\": [\n    {\n      \"Datastream\": {\n        \"@iot.id\": 1,\n        \"description\": \"desc\",\n        \"name\": \"new name\",\n        \"observationType\": \"OM_Observation\",\n        \"observedArea\": {\n          \"coordinates\": [11.509234, 48.110728],\n          \"type\": \"Point\"\n        },\n        \"phenomenonTime\": \"2023-07-24T06:30:18+00:00/2023-09-14T05:40:25.292000+00:00\",\n        \"resultTime\": \"2023-07-24T06:30:18+00:00/2023-07-24T06:31:42+00:00\",\n        \"unitOfMeasurement\": { \"definition\": \"...\", \"name\": \"n\", \"symbol\": \"n\" }\n      },\n      \"FeatureOfInterest\": {\n        \"@iot.id\": 77,\n        \"description\": \"A rainy place\",\n        \"encodingType\": \"application/geo+json\",\n        \"feature\": { \"coordinates\": [-6.22299, 53.306816], \"type\": \"Point\" },\n        \"name\": \"Dublin\",\n        \"properties\": {\n          \"datastreams\": [1, 2, 76, 2, 78, 77],\n          \"multi_datastreams\": [11]\n        }\n      },\n      \"phenomenonTime\": \"2024-04-13T19:57:08+00:00\",\n      \"result\": 19.111,\n      \"resultTime\": \"2024-05-02T19:36:06+00:00\"\n    },\n    {\n      \"Datastream\": {\n        \"@iot.id\": 2,\n        \"description\": \"air relative humidity measured with the SmartCitizen Kit\",\n        \"name\": \"Relative Humidity\",\n        \"observationType\": \"http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement\",\n        \"observedArea\": {\n          \"coordinates\": [11.509234, 48.110728],\n          \"type\": \"Point\"\n        },\n        \"phenomenonTime\": \"2023-07-24T06:30:18+00:00/2023-07-24T06:31:42+00:00\",\n        \"resultTime\": \"2023-07-24T06:30:18+00:00/2023-07-24T06:31:42+00:00\",\n        \"unitOfMeasurement\": {\n          \"definition\": \"https://qudt.org/vocab/unit/PERCENT\",\n          \"name\": \"Percentage\",\n          \"symbol\": \"%\"\n        }\n      },\n      \"FeatureOfInterest\": {\n        \"@iot.id\": 77,\n        \"description\": \"A rainy place\",\n        \"encodingType\": \"application/geo+json\",\n        \"feature\": { \"coordinates\": [-6.22299, 53.306816], \"type\": \"Point\" },\n        \"name\": \"Dublin\",\n        \"properties\": {\n          \"datastreams\": [1, 2, 76, 2, 78, 77],\n          \"multi_datastreams\": [11]\n        }\n      },\n      \"phenomenonTime\": \"2024-04-13T19:57:08+00:00\",\n      \"result\": 43.0,\n      \"resultTime\": \"2024-05-02T19:36:06+00:00\"\n    },\n    {\n      \"Datastream\": {\n        \"@iot.id\": 76,\n        \"description\": \"Precipitation measured with the FT-0310 Weather Station\",\n        \"name\": \"Rain\",\n        \"observationType\": \"http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement\",\n        \"unitOfMeasurement\": {\n          \"definition\": \"https://qudt.org/vocab/unit/MilliM\",\n          \"name\": \"millimiter\",\n          \"symbol\": \"mm\"\n        }\n      },\n      \"FeatureOfInterest\": {\n        \"@iot.id\": 77,\n        \"description\": \"A rainy place\",\n        \"encodingType\": \"application/geo+json\",\n        \"feature\": { \"coordinates\": [-6.22299, 53.306816], \"type\": \"Point\" },\n        \"name\": \"Dublin\",\n        \"properties\": {\n          \"datastreams\": [1, 2, 76, 2, 78, 77],\n          \"multi_datastreams\": [11]\n        }\n      },\n      \"phenomenonTime\": \"2024-04-13T19:57:08+00:00\",\n      \"result\": 87.0,\n      \"resultTime\": \"2024-05-02T19:36:06+00:00\"\n    },\n    {\n      \"Datastream\": {\n        \"@iot.id\": 77,\n        \"description\": \"Wind direction measured with the FT-0310 Weather Station\",\n        \"name\": \"Wind direction\",\n        \"observationType\": \"http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement\",\n        \"unitOfMeasurement\": {\n          \"definition\": \"https://qudt.org/vocab/unit/DEG\",\n          \"name\": \"degree\",\n          \"symbol\": \"deg\"\n        }\n      },\n      \"FeatureOfInterest\": {\n        \"@iot.id\": 77,\n        \"description\": \"A rainy place\",\n        \"encodingType\": \"application/geo+json\",\n        \"feature\": { \"coordinates\": [-6.22299, 53.306816], \"type\": \"Point\" },\n        \"name\": \"Dublin\",\n        \"properties\": {\n          \"datastreams\": [1, 2, 76, 2, 78, 77],\n          \"multi_datastreams\": [11]\n        }\n      },\n      \"phenomenonTime\": \"2024-04-13T19:57:08+00:00\",\n      \"result\": 241.0,\n      \"resultTime\": \"2024-05-02T19:36:06+00:00\"\n    },\n    {\n      \"FeatureOfInterest\": {\n        \"@iot.id\": 77,\n        \"description\": \"A rainy place\",\n        \"encodingType\": \"application/geo+json\",\n        \"feature\": { \"coordinates\": [-6.22299, 53.306816], \"type\": \"Point\" },\n        \"name\": \"Dublin\",\n        \"properties\": {\n          \"datastreams\": [1, 2, 76, 2, 78, 77],\n          \"multi_datastreams\": [11]\n        }\n      },\n      \"MultiDatastream\": {\n        \"@iot.id\": 11,\n        \"ObservedProperties\": [\n          {\n            \"@iot.id\": 105,\n            \"definition\": \"http://vocab.nerc.ac.uk/standard_name/wind_speed/\",\n            \"description\": \"Wind speed\",\n            \"name\": \"wspeed\"\n          },\n          {\n            \"@iot.id\": 106,\n            \"definition\": \"http://vocab.nerc.ac.uk/standard_name/wind_gust_from_direction/\",\n            \"description\": \"Wind gust\",\n            \"name\": \"wgust\"\n          }\n        ],\n        \"description\": \"Wind speed average and gust measured with the FT-0310 Weather Station\",\n        \"multiObservationDataTypes\": [\n          \"http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement\",\n          \"http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement\"\n        ],\n        \"name\": \"Wind speed avg and gust\",\n        \"observationType\": \"http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_ComplexObservation\",\n        \"unitOfMeasurements\": [\n          {\n            \"definition\": \"https://qudt.org/vocab/unit/M-PER-SEC\",\n            \"name\": \"Meters per second\",\n            \"symbol\": \"m/s\"\n          },\n          {\n            \"definition\": \"https://qudt.org/vocab/unit/M-PER-SEC\",\n            \"name\": \"Meters per second\",\n            \"symbol\": \"m/s\"\n          }\n        ]\n      },\n      \"phenomenonTime\": \"2024-04-13T19:57:08+00:00\",\n      \"result\": [0.0, 0.0],\n      \"resultTime\": \"2024-05-02T19:36:06+00:00\"\n    }\n  ],\n  \"Party\": {\n    \"@iot.id\": \"36fd7ca4-08bb-11ef-b156-a337e8ef4d15\",\n    \"displayName\": \"LJS\",\n    \"role\": \"individual\"\n  },\n  \"creationTime\": \"2024-05-02T19:36:06+00:00\",\n  \"description\": \" \",\n  \"endTime\": \"2024-05-02T19:36:06+00:00\",\n  \"name\": \"OG 2024-05-02T19:36:06+00:00\"\n}\n```\n\nThis example with inline `Datastream` and `FeatureOfInterest` entities has the size of 6245 Bytes.\n\n#### Example ObservationGroup with referencing entities\n```JSON\n{\n  \"Observations\": [\n    {\n      \"Datastream\": { \"@iot.id\": 1 },\n      \"FeatureOfInterest\": { \"@iot.id\": 77 },\n      \"phenomenonTime\": \"2024-04-13T19:57:08+00:00\",\n      \"result\": 19.111,\n      \"resultTime\": \"2024-05-03T09:48:33+00:00\"\n    },\n    {\n      \"Datastream\": { \"@iot.id\": 2 },\n      \"FeatureOfInterest\": { \"@iot.id\": 77 },\n      \"phenomenonTime\": \"2024-04-13T19:57:08+00:00\",\n      \"result\": 43.0,\n      \"resultTime\": \"2024-05-03T09:48:33+00:00\"\n    },\n    {\n      \"Datastream\": { \"@iot.id\": 76 },\n      \"FeatureOfInterest\": { \"@iot.id\": 77 },\n      \"phenomenonTime\": \"2024-04-13T19:57:08+00:00\",\n      \"result\": 87.0,\n      \"resultTime\": \"2024-05-03T09:48:33+00:00\"\n    },\n    {\n      \"Datastream\": { \"@iot.id\": 77 },\n      \"FeatureOfInterest\": { \"@iot.id\": 77 },\n      \"phenomenonTime\": \"2024-04-13T19:57:08+00:00\",\n      \"result\": 241.0,\n      \"resultTime\": \"2024-05-03T09:48:33+00:00\"\n    },\n    {\n      \"FeatureOfInterest\": { \"@iot.id\": 77 },\n      \"MultiDatastream\": { \"@iot.id\": 11 },\n      \"phenomenonTime\": \"2024-04-13T19:57:08+00:00\",\n      \"result\": [0.0, 0.0],\n      \"resultTime\": \"2024-05-03T09:48:33+00:00\"\n    }\n  ],\n  \"Party\": {\n    \"@iot.id\": \"4cd42a10-0932-11ef-919f-57f24e9b90e3\",\n    \"displayName\": \"LJS\",\n    \"role\": \"individual\"\n  },\n  \"creationTime\": \"2024-05-03T09:48:33+00:00\",\n  \"description\": \" \",\n  \"endTime\": \"2024-05-03T09:48:33+00:00\",\n  \"name\": \"OG 2024-05-03T09:48:33+00:00\"\n}\n```\n\nThis example with referenced `Datastream` and `FeatureOfInterest` entities has the size of 1420 Bytes.\n",
    "bugtrack_url": null,
    "license": "LGPL3",
    "summary": "A client library to facilitate interaction with a STAplus Server",
    "version": "0.3.3",
    "project_urls": {
        "Homepage": "https://github.com/securedimensions/STAplus-Python-Client"
    },
    "split_keywords": [
        "ogc",
        " staplus",
        " sensorthingsapi",
        " iot"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "eddcaa556107e63147914f8c95ed575501fdad24cd8b9eac7e946e5b55c5dc1d",
                "md5": "b59f8319f71c147f79753818d353f9dc",
                "sha256": "e8dbba738103f237a948cde564adcfaed74f1a03a93941b103d7f0782b67bb42"
            },
            "downloads": -1,
            "filename": "staplus_client-0.3.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b59f8319f71c147f79753818d353f9dc",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 59993,
            "upload_time": "2024-05-24T09:26:05",
            "upload_time_iso_8601": "2024-05-24T09:26:05.534920Z",
            "url": "https://files.pythonhosted.org/packages/ed/dc/aa556107e63147914f8c95ed575501fdad24cd8b9eac7e946e5b55c5dc1d/staplus_client-0.3.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "89c1dfd362fea4ad82106f830b4cd7d7d026a6045280e6c29f819af518c9a945",
                "md5": "b93ed837a242dc1af237a501748be72f",
                "sha256": "acc261751d6fff6fc0f7fac6ea083ffd89a36e147c23a9929f3bd1b3fb245d84"
            },
            "downloads": -1,
            "filename": "staplus_client-0.3.3.tar.gz",
            "has_sig": false,
            "md5_digest": "b93ed837a242dc1af237a501748be72f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 32096,
            "upload_time": "2024-05-24T09:26:06",
            "upload_time_iso_8601": "2024-05-24T09:26:06.619085Z",
            "url": "https://files.pythonhosted.org/packages/89/c1/dfd362fea4ad82106f830b4cd7d7d026a6045280e6c29f819af518c9a945/staplus_client-0.3.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-24 09:26:06",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "securedimensions",
    "github_project": "STAplus-Python-Client",
    "github_not_found": true,
    "lcname": "staplus-client"
}
        
Elapsed time: 0.24103s