Skip to main content

A Python library that helps building NGSI-LD entities and interacting with a NGSI-LD Context Broker

Project description

The ngsildclient library

PyPI License

Overview

ngsildclient is a Python library that helps building NGSI-LD entities and interacting with a NGSI-LD Context Broker.

While the library primary purpose is to ease and speed up the development of a NGSI Agent, it's also valuable for Data Modeling in the design stage especially in interactive mode with the help of autocompletion - such as in Python console or in Jupyter notebook.

Key Features

Build NGSI-LD entities

The task of building a large NGSI-LD compliant entity is tedious, error-prone and results in a significant amount of code.

ngsildclient provides primitives to build and manipulate NGSI-LD compliant entities without effort, in respect with the ETSI specifications.

Development goals are :

  • Support metadata, nested properties, adding/updating/removing properties
  • Provide helpers to build commonly used structures from schema.org, i.e. PostalAdress, OpeningHoursSpecification
  • Remain pragmatic : aim at building entities compliant with concrete NGSI-LD Datamodels while keeping up with evolving ETSI specifications

Implement the NGSI-LD API

ngsildclient provides a NGSI-LD API Client implementation.

Acting as a Context Producer/Consumer ngsildclient is able to send/receive NGSI-LD entities to/from the Context Broker for creation and other operations.

As of v.0.1.3 it covers a subset of the API that allows following operations :

  • single-entity operations : retrieve(), exists(), create(), update(), upsert(), delete()
  • array-of-entities (aka batch) operations : create(), upsert(), update(), delete()
  • query-based operations : query(), count(), delete_where()
  • type operations : available(), drop()
  • gobal operations : purge()

Smart Building Demo

How to build the NGSI-LD SmartBuilding example from the Smart Data Models Initiative and ask the Context Broker to create it.

demo

Where to get it

The source code is currently hosted on GitHub at : https://github.com/Orange-OpenSource/python-orion-client

Binary installer for the latest released version is available at the Python package index.

pip install ngsildclient

Installation

ngsildclient requires Python 3.9+.

One should use a virtual environment. For example with pyenv.

mkdir myfiwareproject && cd myfiwareproject
pyenv virtualenv 3.10.2 myfiwareproject
pyenv local
pip install ngsildclient

Getting started

Build your first NGSI-LD entity

from datetime import datetime
from ngsildclient import Entity

# No context provided => defaults to NGSI-LD Core Context
entity = Entity("AirQualityObserved", "RZ:Obsv4567")

# Once we've created our entity by calling the Entity() constructor 
# We can add properties thanks to primitives

# tprop() sets a TemporalProperty
entity.tprop("dateObserved", datetime(2018, 8, 7, 12))

# gprop() sets a GeoProperty : Point, Polygon, ...
entity.gprop("location", (44, -8))

# prop() is used for other properties
entity.prop("PM10", 8).prop("NO2", 22, unitcode="GP", userdata={"reliability": 0.95})

# rel() sets a Relationship Property
entity.rel("refPointOfInterest", "PointOfInterest:RZ:MainSquare")

entity.pprint()

The resulting JSON looks like this :

{
  "@context": [
    "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context.jsonld"
  ],
  "id": "urn:ngsi-ld:AirQualityObserved:RZ:Obsv4567",
  "type": "AirQualityObserved",
  "dateObserved": {
    "type": "Property",
    "value": {
      "@type": "DateTime",
      "@value": "2018-08-07T12:00:00Z"
    }
  },
  "PM10": {
    "type": "Property",
    "value": 8
  },
  "NO2": {
    "type": "Property",
    "value": 22,
    "unitCode": "GP",
    "reliability": 0.95
  },
  "location": {
    "type": "GeoProperty",
    "value": {
      "type": "Point",
      "coordinates": [
        -8,
        44
      ]
    }
  },
  "refPointOfInterest": {
    "type": "Relationship",
    "object": "urn:ngsi-ld:PointOfInterest:RZ:MainSquare"
  }
}

Once you're satisfied with it, you can save it to a file to share it, for example with the Smart Data Models Initiative.

entity.save("air_quality_sample.json")

Or you can send it to the NGSI-LD Context Broker for creation.

Send an entity to the broker then retrieve it

from ngsildclient import Entity, SmartDataModels, Client

# This time we don't create our own entity but download a sample from the Smart Data Models Initiative
farm = Entity.load(SmartDataModels.SmartAgri.Agrifood.AgriFarm)

# We can visualize it : here we would like the simplified representation (aka KeyValues)
farm.pprint(kv=True)

# We could add/update properties using the prop primitives as we did previously
# For the sake of example we'll just update the phone number, using the dot notation facility
farm["contactPoint.value.telephone"] = "00349674538"

# Send it to the Context Broker for creation
# Here you need a Context Broker up and running
# You can find some ready-to-use docker-compose files in the brokers/ folder
# Without any arguments the client targets localhost and the default port
with Client() as client:
    client.create(farm)

# Later you'll be able to retrieve the entity from the broker and resend it for update
with Client() as client:
    # retrieve the entity by its id
    farm = client.retrieve("urn:ngsi-ld:AgriFarm:72d9fb43-53f8-4ec8-a33c-fa931360259a")
    # It would also work by passing the entity - in case it's still in memory
    # farm = client.retrieve(farm)
    farm["contactPoint.value.telephone"] = "00349674539"
    client.update(farm)

Send, query then delete a batch of entities

# Let's generate a batch of farms
# A poor mocking strategy just for the sake of example !
farms: list[Entity] = []
for hexdigit in "bcdef":
  newfarm = farm.copy()
  newfarm.id = newfarm.id[:-1] + hexdigit
  farms.append(newfarm)

with Client() as client:
    client.upsert(farms) # 5 new farms created ! (with a single API call)

# Later you'll be able to retrieve entities
with Client() as client:
    # Count our farm entities
    # Replace count by query to retrieve the entities
    client.count(type="AgriFarm", query='contactPoint[email]=="wheatfarm@email.com"') # 6 = the original farm + 5 copies
    
# Eventually we'd like to do some cleanup
# We could use client.purge() for an agressive cleanup
with Client() as client:
    client.drop("AgriFarm") # delete all entities with type Agrifarm

License

Apache 2.0

Known limitations

As of v0.1.3 does not support pagination.

Documentation

Docstrings are widely used in the code.

For example.

from ngsildclient import Entity

help(Entity)

For examples (from basic to more complex and realistic) you can have a look at the tests folder.

Especially the tests/test_entity.py file that builds basic entities.

And inside the tests/smartdatamodels folder that builds some sample entities from the Smart Data Models Initiative.

Roadmap

  • Add authentication
  • Extend API coverage : add support for subscriptions
  • Add documentation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ngsildclient-0.1.3.tar.gz (35.8 kB view hashes)

Uploaded Source

Built Distribution

ngsildclient-0.1.3-py3-none-any.whl (44.5 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page