Continuum Canvas Widget Processors
Overview
Assumptions
The reader should have a working knowledge of the Python programming language.
Hello World
Let's start by building a very simple 'hello world' processor Widget.
In the Canvas Editor, click the New Item button. In the dialog, enter tutorials
as the Project, processor
as the Component, and proc.widget
as the Name. Click Save.
Paste the following code into the editor and click Save:
{ "type": "processor", "options": { "processor": { "project": "tutorial", "component": "processor", "name": "proc.py" } } }
This Widget definition simply points to a processor resource. Let's create that resource.
In the resource browser, click the + beside the component we created called processor. A prompt will appear - enter proc.pyinto
the Name and click Save.
Paste the following in to the editor and click Save:
def main(**kwargs): return "hello world"
In the resource browser, select 'proc.widget' and click the Test button.
You cannot Test a processor resource - always change back to the parent Widget to click the Test button.
The test window should appear and say 'hello world'. Congratulations, you just made a Processor Widget!
Rules
A Processor has a few simple rules that must be followed, or errors will occur.
-
The main function definition must be
def main(**kwargs):
-
Whatever processing happens, the processor must return a string - no other return types are permitted.
-
Of course, Python indenting rules must be followed.
Features
Canvas is part of the Continuum platform, and a few helper functions are available.
Writing Log Output
The Canvas logger can be accessed within a processor. It's a standard Python logger, supporting .debug
, .info
, .warning
, .error
, and .critical
.
To write into the log file:
canvas.logger.critical("this is a log entry")
Looking into the Session
While you can access the Session directly, a helper method exists as well. To pull a value out of the Session:
x = canvas.lookup_var("foo", kwargs["session"]) return x
The canvas.lookup_var
function is helpful, because Session can contain very complex structures. lookup_var
utilizes Python eval
rules for evaluating the expression against the Session. Use of the Widget feature to set results into the Session will almost always result in a complex Session.
For example:
x = canvas.lookup_var('my_array[3]["item"].get("name")', kwargs["session"]) return x
would look into the Session for the 4th item in 'my_array', find the 'item' property on that object and get the 'name'.
Standard Arguments
The 'main' function definition accepts an arguments dictionary - **kwargs.
Individual arguments can be accessed as follows for example to set d
to the Widget data:
d = kwargs["data"]
kwargs
contains the following properties:
-
data - If the Widget had a Datasource definition and a Code option, results are available.
-
session
- The complete Session for this Widget. -
args - Any additional arguments provided as 'args' in the 'processor' option of the widget.
-
options - The Widget Options
-
datasource - The Widget Datasource
Advanced Example
Here is an example of a Processor that generates JSON data about host uptime, suitable for a Flot chart.
This example assumes a running Deployment in Deploy, with associated Hosts.
In the Canvas Editor, click the New Item
button. In the dialog, enter tutorials
as the Project, processor
as the Component, and advanced.widget
as the Name. Click Save.
Paste the following code into the editor and click Save:
{
"type": "processor",
"options": {
"processor": {
"project": "tutorial",
"component": "processor",
"name": "advanced.py"
}
},
"datasource": {
"name": "_CATO"
},
"code" : [
"select cast(dh.host_name as char(12)) as host_name,",
" ifnull((unix_timestamp(now()) - unix_timestamp(dh.up_dt)) / 3600, 0) as uptime",
" from deployment_host dh",
" join deployment_service_inst dsi on dh.host_id = dsi.host_id",
" limit 1"]
}
Obviously this Widget could be enhanced to pick a specific Instance, instead of just a random one.
In the resource browser, click the +
beside the component we created called processor
. A prompt will appear - enter advanced.py
into the Name and click Save
.
Paste the following in to the editor and click Save
:
import json
def main(**kwargs):
"""
Returns Flot friendly data json representing host uptime.
"""
session = kwargs["session"]
rows = kwargs["data"]
data = []
ticks = []
# work the rows
if rows:
i = 0
for row in rows:
data.append({"data": [[i, row["uptime"]]]})
ticks.append([i, row["host_name"]])
i += 1
# for this bar chart we're returning flot options as well
out = {}
out["ticks"] = ticks
out["data"] = data
return json.dumps(out, sort_keys=True, indent=4, default=canvas.jsonSerializeHandler)
else:
canvas.logger.warning("Provided data is empty.")
return "[]"
Select the 'advanced.widget' in the resource browser and click Test. Congratulations, you've built an advanced Processor Widget!
The data returned by this widget Would be requested by a Layout that includes the necessary javascript to push this data into a client side charting tool such as Flot.