Publish signals
With the signals created, there is one final step to complete before we can view our data in Clarify and that is publishing our signals. This step exists to allow for a final quality control of the signal metadata, and to ensure that manual edits that we do to metadata is not overwritten by the integration code. The publish step creates items that can be visualized in Timelines, tagged in comments, and discussed with our colleagues.
Using the UI
Programmatically (experimental)
In version 1.1beta1 of the API the support for publishing signals has been added. This makes it easier to publish large numbers of signals. To learn more about this, check out the reference guide.
- cURL
- Python
- Go
The curl example uses Basic Auth for simplicity.
# BASIC_AUTH_USERNAME=<Username from Basic Auth credentials>
# BASIC_AUTH_PASSWORD=<Password from Basic Auth credentials>
# INTEGRATION_ID=${BASIC_AUTH_USERNAME}
curl -u ${BASIC_AUTH_USERNAME}:${BASIC_AUTH_PASSWORD} \
--request POST \
--url 'https://api.clarify.io/v1/rpc' \
--header 'content-type: application/json' \
--header 'X-API-Version: 1.1' \
--data \
'
{
"jsonrpc": "2.0",
"method": "admin.selectSignal",
"id": 10,
"params": {
"integration": "'${INTEGRATION_ID}'",
"query": {
"filter": {
"annotations.docs-clarify-io/example/name": "select_signals"
},
"limit": 10
},
"include": ["item"]
}
}
'
from pyclarify import Client, query
client = Client("./clarify-credentials.json")
filter = query.Filter(fields={
"annotations."annotations.docs-clarify-io/example/name": query.Equal(value="save_signals")
})
response = client.select_signals(filter=filter, limit=10, include=["item"])
data = response.result.data
package main
import (
"context"
"encoding/json"
"os"
clarify "github.com/clarify/clarify-go"
"github.com/clarify/clarify-go/query"
)
func main() {
// To select or publish signals, you must grant the integration access to
// the "admin" namespace in the Clarify admin panel.
creds, err := clarify.CredentialsFromFile("clarify-credentials.json")
if err != nil {
panic(err)
}
ctx := context.Background()
client := creds.Client(ctx)
// For this example, the signals we want to select are created by the same
// integration that we are using to select them. Note that this isn't a
// requirement; for production cases, you may want this integration ID to be
// configured to be something else.
integrationID := creds.Integration
query := fields.Query().
Where(fields.Comparisons{"annotations.docs-clarify-io/example/name": fields.Equal("publish_signals")}).
Limit(10)
result, err := client.Clarify().SelectItems(query).Do(ctx)
if err != nil {
panic(err)
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
enc.Encode(result)
}
- cURL
- Python
- Go
The curl example uses Basic Auth for simplicity.
# BASIC_AUTH_USERNAME=<Username from Basic Auth credentials>
# BASIC_AUTH_PASSWORD=<Password from Basic Auth credentials>
# INTEGRATION_ID=${BASIC_AUTH_USERNAME}
# SIGNAL_ID=<id from admin.selectSignals result>
# SIGNAL_HASH=<meta.attributesHash from admin.selectSignals result>
curl -u ${BASIC_AUTH_USERNAME}:${BASIC_AUTH_PASSWORD} \
--request POST \
--url 'https://api.clarify.io/v1/rpc' \
--header 'content-type: application/json' \
--header 'X-API-Version: 1.1' \
--data '
{
"jsonrpc": "2.0",
"method": "admin.publishSignals",
"id": "1",
"params": {
"integration": "'${INTEGRATION_ID}'",
"itemsBySignal": {
"'${SIGNAL_ID}'" : {
"annotations": {
"docs-clarify-io/example/source-signal/attributes-hash": "'${SIGNAL_HASH}'",
"docs-clarify-io/example/source-signal/id": "'${SIGNAL_ID}'"
},
"name": "Building status",
"description": "Overall building status, aggregated from environmental sensors."
"labels": {
"data-source": ["Manual"],
"location": ["Banana stand", "Pier"]
},
"sourceType": "aggregation"
"valueType": "enum".
"enumValues": {
"0": "✅",
"1": "🔥"
},
"sampleInterval": "PT15M",
"gapDetection": "PT2H"
}
},
"createOnly": false
}
}'
from pyclarify import Client, Item
client = Client("./clarify-credentials.json")
item = Item(
annotations={
"annotations.docs-clarify-io/example/name: "save_signals",
"annotations.docs-clarify-io/example/publish": "true",
},
name="Building status",
description="Overall building status, aggregated from environmental sensors.",
labels={
"data-source": ["Environmental Sensors"],
"location": ["Banana Stand", "Pier"]
},
sourceType="aggregation",
valueType="enum",
enumValues={
0: "✅",
1: "🔥",
},
sampleInterval="PT15M",
gapDetection="PT2H"
)
items_dict = {
"SIGNAL_ID": item
}
response = client.publish_signals(items_by_signal=item_dict)
This example is for reference only. For a full example of how to select multiple signals and publish using transforms see examples/publish_signals in the clarify-go repo.
package main
import (
"context"
"encoding/json"
"os"
"time"
clarify "github.com/clarify/clarify-go"
"github.com/clarify/clarify-go/query"
"github.com/clarify/clarify-go/views"
)
func main() {
// To select or publish signals, you must grant the integration access to
// the "admin" namespace in the Clarify admin panel.
creds, err := clarify.CredentialsFromFile("clarify-credentials.json")
if err != nil {
panic(err)
}
ctx := context.Background()
client := creds.Client(ctx)
// For this example, the signals we want to publish are created by the same
// integration that we are using to select them. Note that this isn't a
// requirement; for production cases, you may want this integration ID to be
// configured to be something else.
integrationID := creds.Integration
// This example assume SIGNAL_ID is set in the environment; normally you would
// do a client.SelectSignals call instead.
signalID := os.Getenv("SIGNAL_ID")
result, err := client.Admin().PublishSignals(integrationID, map[string]views.ItemSave{
signalID: views.ItemSave{
MetaSave: views.MetaSave{
Annotations: fields.Annotations{
// Annotation keys should be prefixed to avoid collision.
"annotations.docs-clarify-io/example/name": "save_signals",
"annotations.docs-clarify-io/example/publish": "true",
},
},
ItemSaveAttributes: views.ItemSaveAttributes{
Name: "Building status",
Description: "Overall building status, aggregated from environmental sensors.",
Labels: fields.Labels{
// Label keys generally does not need to be prefixed.
"data-source": {"Environmental Sensors"},
"location": {"Banana Stand", "Pier"},
},
SourceType: views.Aggregation,
ValueType: views.Enum,
EnumValues: fields.EnumValues{
0: "✅",
1: "🔥",
},
SampleInterval: fields.AsFixedDuration(15 * time.Minute),
GapDetection: fields.AsFixedDuration(2 * time.Hour),
},
},
}).Do(ctx)
if err != nil {
panic(err)
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
enc.Encode(result)
}
What's next?
Now that you have created your first signal and published it, you should be ready to start integrating some actual data sources. Check out the integration guides to learn how to connect specific data sources, or head on over to the user guides to learn more about interacting with Clarify.