Skip to main content

Python SDK

import pyclarify

Using our Python SDK is one of the easiest ways to get started with the Clarify API. You can use it for writing and reading data, modifying metadata and insert data to signals, as well as publishing signals.

Prerequisites

In order to start using the Python SDK, you need

  • To know a bit of Python. For a refresher, see the Official Python tutorial.
  • Python3 (>= 3.7) and pip.
  • Credentials file from a Clarify integration.
  • Make sure you have enabled the Namespaces of the methods you want to have access to.

Installation

To use PyClarify, first install it using pip:

Install with pip
 $ pip install pyclarify

Interact with Clarify

PyClarify provides a fast and easy way to interact with Clarify using the Client() class. This class takes as an argument the path of your credentials in string format, which should always be the first step when starting to interact with PyClarify.

Connect to Clarify

from pyclarify import Client

client = Client("./clarify-credentials.json")

Create a new Signal

Using the Signal model you can add metadata to a signal and insert one or multiple signals with the save_signals() method. The signals are uniquely identified by its <INPUT_ID>.

from pyclarify import Signal

signal = Signal(
name = "Home temperature",
description = "Temperature in the bedroom",
labels = {
"data-source": ["Raspberry Pi"],
"location": ["Home"]
}
)

input_dict = {
"<INPUT_ID>" : signal
}

response = client.save_signals(
signals_by_input=input_dict
)

Alternatively you can also use arrays to save signals.

from pyclarify import Signal

signal = Signal(
name = "Home temperature",
description = "Temperature in the bedroom",
labels = {
"data-source": ["Raspberry Pi"],
"location": ["Home"]
}
)
response = client.save_signals(
input_ids=['<INPUT_ID>'],
signals=[signal]
)

Insert data into a signal

Using the DataFrame model you can insert data to one or multiple signals with the insert() method.

from pyclarify import DataFrame

timestamps = ["2021-11-01T21:50:06Z", "2021-11-02T21:50:06Z"]

data = DataFrame(
series={"<INPUT_ID_1>": [1, None], "<INPUT_ID_2>": [None, 5]},
times=timestamps,
)

response = client.insert(data)

Query your stored signals

When you have signals in your organization you can select them with the select_signals() method. This will only return the meta data of the signals.

response = client.select_signals(
skip=10,
limit=50,
sort=["-id"]
)

Publish the signals as Items

Use the Item model to publish your signals as items. The items can have different meta data than their signal counterpart. They can also be set to be visible programmatically for the entire organization. Each signal is uniquely identified by its input ID in combination with the integration ID.

from pyclarify import Item

item = Item(
name = "Home temperature",
description = "Temperature in the bedroom",
labels = {
"data-source": ["Raspberry Pi"],
"location": ["Home"]
},
visible=True
)

items_dict = {
"<SIGNAL_ID>": item
}

response = client.publish_signals(
items_by_signal=item_dict
)

Alternatively you can also use arrays to publish signals.

from pyclarify import Item

item = Item(
name = "Home temperature",
description = "Temperature in the bedroom",
labels = {
"data-source": ["Raspberry Pi"],
"location": ["Home"]
},
visible=True
)
response = client.publish_signals(
signal_ids=['<SIGNAL_ID>'],
items=[item],
create_only=False
)

Use filters to get a specific selection

Filters can be combined to form logical AND and OR operations. This is translated to python using the & and | symbols.

from pyclarify.query import Filter, Regex

only_raspberries = Filter(
fields={
"labels.data-source": Regex(value="Raspberry")
}
)

response = client.select_items(
filter=only_raspberries
)

The implemented operators are:

  • Equal
  • NotEqual
  • Regex
  • In
  • NotIn
  • Less
  • LessOrEqual
  • Greater
  • GreaterOrEqual

The usage is described in the API reference.

Get the data and include relationships

Use the data_frame method to get the time series of your items. You can also include relationships to get the corresponding meta data for the values.

response = client.data_frame(
filter=only_raspberries,
include=["item"]
)

Use help to get more insight

All our user facing methods and models have docstrings attached! Use it to unlock the full potential of the SDK.

$ help(client.data_frame)
data_frame(
filter: Optional[pyclarify.query.filter.Filter] = None,
sort: List[str] = [],
limit: int = 20,
skip: int = 0,
total: bool = False,
gte: Union[datetime.datetime, str] = None,
lt: Union[datetime.datetime, str] = None,
last: int = -1,
rollup: Union[str, datetime.timedelta] = None,
include: List[str] = []
) -> pyclarify.views.generics.Response method of pyclarify.client.Client instance

Return dataframe for items.

Time selection:
- Maximum window size is 40 days (40 * 24 hours) when rollup is null or less than PT1M (1 minute).
- Maximum window size is 400 days (400 * 24 hours) when rollup is greater than or equal to PT1M (1 minute).
- No maximum window size if rollup is window.

Parameters
----------
filter: Filter, optional
A Filter Model that describes a mongodb filter to be applied.

sort: list of strings
List of strings describing the order in which to sort the items in the response.

limit: int, default 20
The maximum number of resources to select. Negative numbers means no limit, which may or may not be allowed.

skip: int default: 0
Skip the first N matches. A negative skip is treated as 0.

total: bool default: False
When true, force the inclusion of a total count in the response. A total count is the total number of resources that matches filter.

gte: string(RFC 3339 timestamp) or python datetime, optional, default <now - 7 days>
An RFC3339 time describing the inclusive start of the window.

lt: string(RFC 3339 timestamp) or python datetime, optional, default <now + 7 days>
An RFC3339 time describing the exclusive end of the window.

last: int, default -1
If above 0, select last N timestamps per series. The selection happens after the rollup aggregation.

rollup: timedelta or string(RFC 3339 duration) or "window", default None
If RFC 3339 duration is specified, roll-up the values into either the full time window
(`gte` -> `lt`) or evenly sized buckets.

include: List of strings, optional
A list of strings specifying which relationships to be included in the response.

Example
-------

>>> client.data_frame(
>>> filter = query.Filter(fields={"name": query.NotEqual(value="Air Temperature")}),
>>> sort = ["-id"],
>>> limit = 5,
>>> skip = 3,
>>> total = False,
>>> gte="2022-01-01T01:01:01Z",
>>> lt="2022-01-09T01:01:01Z",
>>> rollup="PT24H",

Returns
-------
Response
In case of a valid return value, returns a pydantic model with the following format:

>>> jsonrpc = '2.0'
>>> id = '1'
>>> result = SelectDataFrameResponse(
>>> meta={
>>> 'total': -1,
>>> 'groupIncludedByType': True
>>> },
>>> data=DataFrame(
>>> times=[datetime.datetime(2022, 7, 12, 12, 0, tzinfo=datetime.timezone.utc),..],
>>> series={
>>> 'c5ep6ojsbu8cohpih9bg': [0.18616, 0.18574000000000002, ...,],
>>> ...
>>> }
>>> )
>>> included=None
>>> ),
>>> error = None

In case of the error the method return a pydantic model with the following format:

>>> jsonrpc = '2.0'
>>> id = '1'
>>> result = None
>>> error = Error(
>>> code = '-32602',
>>> message = 'Invalid params',
>>> data = ErrorData(trace = <trace_id>, params = {})
>>> )

Learn more

For more information about PyClarify check out the SDK, the reference or try out some interactive tutorials.

If you found any errors, ambiguities or have any suggestions on how to make this guide better, please contact us via chat or send an email to hello@clarify.io 🙌

Disclaimer By using our guides you agree to the following disclaimer.